LDAP_sort()方法已被弃用,有什么替代方法?

6
正如标题所说,当我尝试使用ldap_sort()方法时,它返回已弃用的方法
为什么?有没有等效的方法?
此外,在过滤器中是否可以按A-Z排序?
4个回答

5

ldap_sort是基于一个C函数的,这个函数已经被淘汰多年了。由于ldap_sort通常不会实现大多数人认为的功能,我们决定弃用PHP函数。

特别是当结果也可以通过用户自定义代码实现时。请查看https://github.com/zendframework/zend-ldap/blob/master/src/Collection/DefaultIterator.php#L379-L403,了解我们如何在zend-ldap中解决此问题。您可以使用任何排序函数来获得所需的排序,而不必受限于在ldap_sort中实现的排序算法,但没有人真正知道它是如何排序的。

当您使用用户自定义的函数进行排序时,可以根据您特定的情况实现所需的排序方式。按多个属性排序,按大小写敏感排序等等。

替代方案是使用服务器端排序,

a) 需要我们在PHP的C代码中实现LDAP-COntrols(目前还未完成)和 b) 服务器需要实现该控件

由于我们尚未(尚)成功完成该功能,因此此功能目前在PHP中不可用。这是更好的解决方案,但由于服务器上可能没有此功能,因此您可能仍然希望在客户端上进行排序。当您使用分页结果多次搜索时,仍需要手动对结果进行排序。

因此,ldap_sort因某些原因被弃用,但仍然可用。它将在所有PHP 7.x分支中提供。但是,您应该使用不同的排序解决方案。我们希望能够在PHP 8中提供服务器端排序(尽管不知道何时会到来),但这可能对您没有帮助,因为它取决于服务器的功能。

因此,获取您的结果,将它们添加到数组中并为该数组实现排序函数是您可以做的最简单的事情,并且该排序算法正是想要的!

免责声明:我是实现“DEPRECATED-Warning”的人


目前我已经在一个数组上使用了array_multisort()函数(在服务器端排序),它对我的帮助很大,但是需要花费相当长的执行时间。我的数组中有约3500行数据。感谢您的回答。 - Srithovic
我知道它不是完美的。但是ldap_sort在那种情况下也无法帮助您。不过,我不确定usort(或uasort)是否比array_multisort更快,但这是另一回事......对于排序那么多条目,只能使用服务器端排序,而这并不是当前可用的功能...不过我们正在努力解决。 - heiglandreas
需要注意的是,您所引用的用户空间实现不处理UTF8字符。如果有人想要使用UTF8对数据进行排序,您可能需要查看Intl扩展并使用Collator类。 - ChadSikorra
我认为这取决于你注入的排序器。我会使用usort或uasort,并注入我想要的排序算法。无论它是否与UTF-8兼容完全取决于我自己。是的,我可能需要检查zend-ldap中的排序。我只是举了一个例子... - heiglandreas

2
$sr=ldap_search($test_ldap, $base, $filter, $attrs, 0, -1, -1, LDAP_DEREF_NEVER, [['oid' => LDAP_CONTROL_SORTREQUEST, 'value' => [['attr'=>'samaccountname']]]]);

将执行服务器端排序。

与分页搜索结果结合使用时,它看起来像这样:

$cookie = '';
do {
 $request_controls=[['oid' => LDAP_CONTROL_PAGEDRESULTS, 'value' => ['size' => 2, 'cookie' => $cookie]], ['oid' => LDAP_CONTROL_SORTREQUEST, 'value' => [['attr'=>'samaccountname']]]];
 $sr = ldap_search($ldap, $base, $filter, $attribs, 0, 0, 0, LDAP_DEREF_NEVER, $request_controls  );
 ldap_parse_result($ldap, $sr, $errcode , $matcheddn , $errmsg , $referrals, $response_controls);
 $results = ldap_get_entries($ldap, $sr);
 for ($i=0; $i<$results["count"]; $i++) {
  echo($results[$i]['samaccountname'][0]); echo('<br>');
 }
 if (isset($response_controls[LDAP_CONTROL_PAGEDRESULTS]['value']['cookie'])) {$cookie = $response_controls[LDAP_CONTROL_PAGEDRESULTS]['value']['cookie']; } else { $cookie = '';  }
} while (!empty($cookie));

1

纯PHP实现

// because PHP usort() cannot iterate using $array['count'], so need implement this quicksort()
function quickSort(&$array, $compare, $start, $end)
{
    $partition = function (&$array, $start, $end) use (&$partition, $compare) {
        if ($start >= $end) {
            return;
        }
        $pivot = $array[$start];
        $left = $start;
        $right = $end;
        while ($left <= $right) {
            while ($compare($array[$left], $pivot) < 0) {
                $left += 1;
            }
            while ($compare($array[$right], $pivot) > 0) {
                $right -= 1;
            }
            if ($left > $right) {
                break;
            }
            list($array[$left], $array[$right]) = [$array[$right], $array[$left]];
            $left += 1;
            $right -= 1;
        }
        $partition($array, $start, $right);
        $partition($array, $left, $end);
    };

    $partition($array, $start, $end);
}


function ldapSort(array &$entries, $key)
{
    $SORT_KEY = 'SortValue';

    $key = strtolower($key);

    for ($i = 0; $i < $entries['count']; $i++) {
        $entry = &$entries[$i];
        $attributes = array_change_key_case($entry, CASE_LOWER);

        $entry[$SORT_KEY] = isset($attributes[$key][0]) ?
            $attributes[$key][0] : null;
    }
    unset($entry);

    quickSort(
        $entries,
        function ($a, $b) use ($SORT_KEY) {
            $a = $a[$SORT_KEY];
            $b = $b[$SORT_KEY];
            if ($a == $b) {
                return 0;
            }
            return ($a < $b) ? -1 : 1;
        },
        0, // start
        $entries['count'] - 1 // end
    );
}

使用方法

$entries = ldap_get_entries($ldap, $result);
ldapSort($entries, 'displayname');

参考:PHP LDAP排序
以下是需要翻译的内容:

1
你可以看到,根据PHP ldap_sort文档
对由ldap_search()返回的LDAP搜索结果进行排序。
由于此函数在客户端端排序返回的值,因此可能会在达到服务器或ldap_search()中定义的大小限制时无法获得预期结果。 警告:自PHP 7.0.0起,此功能已被弃用。强烈不建议使用此功能。 此外,根据Github中的PHP Compatibility DeprecatedFunctionsSniff文档
    'ldap_sort' => array(
        '7.0' => false,
        'alternative' => null,
    ),

在这个测试用例中,ldap_sort将从PHP 7.0版本开始被弃用,并且它的alternative = NULL表示没有替代方法
回答你的另一个问题:
LDAP协议在RFC 2891中定义了LDAP控制扩展,用于服务器端排序搜索结果。您需要检查您使用的LDAP实现(因为它没有在问题中标记)是否实现了此控件来按A-Z进行排序。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接