Как получить всех пользователей из AD LDAP в Laravel без проблем с тайм-аутом или памятью?Php

Кемеровские программисты php общаются здесь
Ответить
Anonymous
 Как получить всех пользователей из AD LDAP в Laravel без проблем с тайм-аутом или памятью?

Сообщение Anonymous »

В настоящее время я работаю над приложением Laravel 10, которое интегрируется с Active Directory (AD) с помощью пакета AdLdap2 и функций PHP LDAP (PHP 8). Однако я сталкиваюсь с проблемами при попытке получить всех пользователей (более 20 000) с сервера LDAP.
Вот два метода, которые я пробовал:
Способ 1. Использование пакета AdLdap2

Код: Выделить всё

private function handleAdLdapUsersEx($provider): void
{
try {
$pageSize = 200;

if ($this->searchBase->filter) {
$provider->where($this->searchBase->filter);
}

$pagedUsers = $provider->select('distinguishedname', 'givenname', 'name', 'objectguid', 'samaccountname', 'userprincipalname', 'mail')
->whereEnabled()
->limit($pageSize)
->paginate($pageSize, $this->currentPage);

dump($pagedUsers->count());

if ($pagedUsers->count() > 0) {
collect($pagedUsers->getResults())->chunk(100)->each(function ($chunkedUsers) {
$this->handleBulk($chunkedUsers);
unset($chunkedUsers);
gc_collect_cycles();
});

if ($pagedUsers->count() === $pageSize) {
ImportUsersJob::dispatch($this->searchBase, $this->ldapConnector, $this->ldapConfig, $this->currentPage + 1);
}
}
} catch (\Exception $e) {
dd($e->getMessage());
}
}

В этом методе я устанавливаю ограничение на разбиение на страницы, даже с ограничением и разбиением на страницы я получаю все записи на одной странице, но у меня все еще возникают тайм-ауты. Установка общедоступного $timeout = 600; работает, но я бы хотел избежать жесткого кодирования тайм-аута.
Метод 2: использование функций PHP LDAP

Код: Выделить всё

private function handleAdLdapUsers($provider, $ldapConnector): void
{
try {
$usersFetched = 0;
$lastUserEntry = null;

$ldapConnection = ldap_connect($provider->getConnection()->getHost());
ldap_set_option($ldapConnection, LDAP_OPT_PROTOCOL_VERSION, 3);
ldap_bind($ldapConnection, $ldapConnector->getUsernames(), $ldapConnector->getPassword());

$filter = !empty($this->searchBase->filter) ? $this->searchBase->filter : "(objectClass=*)";

$result = @ldap_search($ldapConnection, $provider->getDn(), $filter, [], 0, 1);
$firstEntry = ldap_first_entry($ldapConnection, $result);

while ($firstEntry) {
$attributes = ldap_get_attributes($ldapConnection, $firstEntry);

$users = $provider->select('distinguishedname', 'givenname', 'name', 'objectguid', 'samaccountname', 'userprincipalname', 'mail', 'usncreated')
->whereEnabled()
->get($attributes);

if ($users->count() > 0) {
$this->handleBulk($users);
$usersFetched = $users->count();
} else {
break;
}

$lastUserEntry = ldap_next_entry($ldapConnection, $firstEntry);
$firstEntry = $lastUserEntry;
}

ldap_unbind($ldapConnection);
} catch (\Exception $e) {
dd($e->getMessage());
}
}

Этот метод возвращает предупреждение «Предел размера превышен» и извлекает только 1000 записей. Я подавил предупреждение с помощью @ldap_search, но мне все еще нужен способ получить всех пользователей (потенциально более 50 000), не нарушая ограничения по размеру и не сталкиваясь с проблемами памяти.
  • Как я могу изменить свои запросы или разбиение на страницы, чтобы эффективно обрабатывать выборку всех пользователей?
  • Существуют ли передовые методы работы с большими наборами данных в Laravel при запросах LDAP?
  • Есть ли способ настроить сервер LDAP так, чтобы он позволял получать данные, превышающие предельный размер по умолчанию?
Будем очень признательны за любую помощь или рекомендации!

Подробнее здесь: https://stackoverflow.com/questions/791 ... ory-issues
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «Php»