Search code examples
phpldap

How to replace ldap_sort?


I'm porting an app to PHP8 and having an issue with ldap_sort no longer being available. I can retrieve the data from my ldap server and am able to sort on sn, then givenname but I get a warning on each term. I assume this is to do with incomplete data in some ldap records, but not sure. My code is below and the warning I get is:

Warning: Trying to access array offset on value of type int in C:\inetpub\wwwroot\inc\queries_php\ldap\qryldap.php on line 50

Warning: Trying to access array offset on value of type int in C:\inetpub\wwwroot\inc\queries_php\ldap\qryldap.php on line 51

Where line 50 is the one beginning $lastname and 51 is $givenname. I'm struggling to figure out a way to loop through the results in a way that prevents the warning showing. Any ideas please?

Calum

    function QueryLDAP() {
    // -------------- CHANGE VARIABLES TO SUIT YOUR ENVIRONMENT  --------------
    //LDAP server address
        $server = "ldap://192.168.1.1";

    //domain user to connect to LDAP
        $user = "administrator@company.com";
        
    //user password
            $psw = "p@55w0rd!";

    //FQDN path where search will be performed. OU - organizational unit / DC - domain component
        $dn = "OU=Users,DC=Company,DC=local";
    //Search query. CN - common name (CN=* will return all objects)
        $search = "(&(objectCategory=person)(objectClass=user)(company=Company))";
        $attributes = array("objectSid", "sAMAccountName", "givenname", "sn", "cn", "mail", "department", "telephonenumber", "mobile", "company", "title", "facsimileTelephoneNumber", "description");

    // connecting to LDAP server
        $ds=ldap_connect($server);
        $r=ldap_bind($ds, $user , $psw); 

    // performing search
        $sr=ldap_search($ds, $dn, $search, $attributes);

    // Sort by lastname
    //  ldap_sort($ds, $sr, 'sn');  ldap_sort deprecated in PHP8 - see below!!

    $GLOBALS['ldap'] = ldap_get_entries($ds, $sr);  // allows this variable to be used in functions

    // Sort the array by lastname, firstname ascending:
    //  from example 3, https://www.php.net/manual/en/function.array-multisort.php
        foreach ($GLOBALS['ldap'] as $key => $row) {
            $lastname[$key]  = $row['sn'];
            $firstname[$key] = $row['givenname'];
        }
        array_multisort($lastname, SORT_ASC, $firstname, SORT_ASC, $GLOBALS['ldap']);

    // close connection
        ldap_close($ds);
}

Solution

  • ldap_get_entries returns an array with an additional field 'count'. This 'count' field contains an integer value that is obviously not an array. Due to that ldap_get_entries() result is not really a multiarray.

    To operate on those entries as a multiarray one quick way is to save count field remove it then sort, once done you can add count field, or not if you don't need it.

    This is how i proceeded for https://github.com/ltb-project/ltb-ldap/blob/main/src/Ltb/Ldap.php

    Many other solutions exists for ldap_sort removal : What is a replacement for LDAP_sort() method which is deprecated?