Signatur
Beschreibung
ldap_search durchsucht den LDAP-Verzeichnisbaum ab dem angegebenen Basis-DN (base) rekursiv nach Einträgen, die dem übergebenen Filter entsprechen. Der Suchbereich umfasst den Basisknoten selbst sowie alle seine Unterknoten (Scope subtree). Die Funktion ist das Arbeitspferd für typische Verzeichnisabfragen, etwa um Benutzer oder Gruppen in einem Active Directory oder OpenLDAP zu finden.
Das zurückgegebene LDAP\Result-Objekt (bzw. vor PHP 8.1 eine Ressource) kann anschließend mit ldap_get_entries, ldap_first_entry oder ähnlichen Funktionen ausgelesen werden. Über den Parameter $attributes lässt sich die Rückgabe auf bestimmte Attribute beschränken, was die übertragene Datenmenge erheblich reduziert.
Mit dem optionalen Parameter $sizelimit kann die maximale Anzahl zurückgegebener Einträge begrenzt werden. Zu beachten ist, dass der LDAP-Server selbst ebenfalls ein serverseitiges Limit setzen kann, das nicht überschritten werden kann. $timelimit schränkt die maximale Suchdauer in Sekunden ein. Der Parameter $deref steuert, wie LDAP-Aliase aufgelöst werden.
Sollen mehrere Verbindungen gleichzeitig durchsucht werden, kann als erster Parameter ein Array von LDAP\Connection-Objekten übergeben werden, wobei $base und $filter ebenfalls als Arrays übergeben werden müssen. In diesem Fall liefert die Funktion ein Array von LDAP\Result-Objekten zurück.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $ldap Pflicht | LDAP\Connection|array | Eine gültige LDAP\Connection-Instanz (erzeugt von ldap_connect) oder ein Array solcher Instanzen für parallele Mehrfachsuchen. |
|
| $base Pflicht | array|string | Der Basis-DN (Distinguished Name), ab dem die Suche beginnt, z. B. "dc=example,dc=com". Bei Mehrfachsuchen ein Array von Basis-DNs. |
|
| $filter Pflicht | array|string | Der LDAP-Suchfilter gemäß RFC 4515, z. B. "(uid=jdoe)" oder "(&(objectClass=user)(sAMAccountName=admin))". Bei Mehrfachsuchen ein Array von Filtern. |
|
| $attributes | array | [] | Array mit den Namen der zurückzugebenden Attribute, z. B. ["cn", "mail", "uid"]. Ein leeres Array (Standard) liefert alle Attribute des Eintrags. |
| $attributes_only | int | 0 | Wenn auf 1 gesetzt, werden nur die Attributnamen ohne deren Werte zurückgegeben. Standard ist 0 (Attributnamen und -werte). |
| $sizelimit | int | -1 | Maximale Anzahl zurückzugebender Einträge. -1 bedeutet, dass der Standardwert des LDAP-Servers verwendet wird. Das serverseitige Limit kann nicht überschritten werden. |
| $timelimit | int | -1 | Maximale Suchdauer in Sekunden. -1 bedeutet, dass der Standardwert des LDAP-Servers gilt. |
| $deref | int | LDAP_DEREF_NEVER | Steuert die Alias-Auflösung. Mögliche Werte: LDAP_DEREF_NEVER, LDAP_DEREF_SEARCHING, LDAP_DEREF_FINDING, LDAP_DEREF_ALWAYS. |
| $controls | array|null | null | Array mit LDAP-Serversteuerungen (Server Controls), die mit der Anfrage gesendet werden sollen. Kann z. B. für Paginierung (LDAP_CONTROL_PAGEDRESULTS) verwendet werden. |
Rückgabewert
LDAP\Result-Objekt (ab PHP 8.1), das mit ldap_get_entries o. ä. ausgelesen werden kann. Bei Mehrfachsuchen ein Array von LDAP\Result-Objekten. Im Fehlerfall wird false zurückgegeben.Beispiele
Einfache Benutzersuche im LDAP-Verzeichnis
<?php
$ldap = ldap_connect('ldap://ldap.example.com');
if (!$ldap) {
die('Verbindung zum LDAP-Server fehlgeschlagen.');
}
ldap_set_option($ldap, LDAP_OPT_PROTOCOL_VERSION, 3);
// Anonymes Bind (oder mit Credentials: ldap_bind($ldap, 'cn=admin,dc=example,dc=com', 'geheim'))
if (!ldap_bind($ldap)) {
die('LDAP-Bind fehlgeschlagen: ' . ldap_error($ldap));
}
$baseDn = 'dc=example,dc=com';
$filter = '(uid=jdoe)';
$attrs = ['cn', 'mail', 'uid'];
$result = ldap_search($ldap, $baseDn, $filter, $attrs);
if ($result === false) {
die('Suche fehlgeschlagen: ' . ldap_error($ldap));
}
$entries = ldap_get_entries($ldap, $result);
echo 'Gefundene Einträge: ' . $entries['count'] . PHP_EOL;
for ($i = 0; $i < $entries['count']; $i++) {
echo 'CN : ' . ($entries[$i]['cn'][0] ?? '-') . PHP_EOL;
echo 'Mail : ' . ($entries[$i]['mail'][0] ?? '-') . PHP_EOL;
}
ldap_unbind($ldap);
?>
Paginierte Suche mit LDAP_CONTROL_PAGEDRESULTS
<?php
$ldap = ldap_connect('ldap://ldap.example.com');
ldap_set_option($ldap, LDAP_OPT_PROTOCOL_VERSION, 3);
ldap_bind($ldap, 'cn=admin,dc=example,dc=com', 'geheim');
$baseDn = 'dc=example,dc=com';
$filter = '(objectClass=inetOrgPerson)';
$attrs = ['cn', 'mail'];
$pageSize = 100;
$cookie = '';
do {
$controls = [
[
'oid' => LDAP_CONTROL_PAGEDRESULTS,
'iscritical' => false,
'value' => ['size' => $pageSize, 'cookie' => $cookie],
]
];
$result = ldap_search($ldap, $baseDn, $filter, $attrs, 0, 0, 0, LDAP_DEREF_NEVER, $controls);
if ($result === false) {
echo 'Fehler: ' . ldap_error($ldap);
break;
}
$entries = ldap_get_entries($ldap, $result);
echo 'Seite enthält ' . $entries['count'] . ' Einträge.' . PHP_EOL;
foreach (range(0, $entries['count'] - 1) as $i) {
echo ' - ' . ($entries[$i]['cn'][0] ?? '?') . PHP_EOL;
}
// Cookie für nächste Seite auslesen
ldap_parse_result($ldap, $result, $errcode, $matcheddn, $errmsg, $refs, $responseControls);
$cookie = $responseControls[LDAP_CONTROL_PAGEDRESULTS]['value']['cookie'] ?? '';
} while (!empty($cookie));
ldap_unbind($ldap);
?>
// Wichtig · Fallstricke
Sicherheit: Benutzereingaben dürfen niemals ungeprüft in LDAP-Filter eingefügt werden, da dies zu LDAP-Injection führen kann. Sonderzeichen wie (, ), *, \ und das Null-Byte müssen mit ldap_escape($input, '', LDAP_ESCAPE_FILTER) maskiert werden.
Sizelimit: Wenn $sizelimit kleiner ist als das serverseitige Limit, wird der kleinere Wert verwendet. Das serverseitige Limit kann jedoch nicht durch den Client überschritten werden. Bei großen Verzeichnissen empfiehlt sich die paginierte Suche über LDAP_CONTROL_PAGEDRESULTS.
PHP 8.1: Ab PHP 8.1 gibt ldap_search ein LDAP\Result-Objekt statt einer Ressource zurück. Code, der explizit auf den Typ resource prüft, muss angepasst werden.
Encoding: LDAP verwendet UTF-8 als Zeichenkodierung. PHP-Strings müssen daher korrekt kodiert sein, bevor sie als Filter oder DN verwendet werden.