我正在使用PHP创建LDAP目录搜索。
我能够成功搜索并返回结果。
我希望能够根据层次结构对结果进行排序。 现在我有:
ou=HR,ou=Employees,ou=People,dc=instatsport,dc=com
ou=IT,ou=Employees,ou=People,dc=instatsport,dc=com
ou=Video,ou=Employees,ou=People,dc=instatsport,dc=com
ou=HR1,ou=HR,ou=Employees,ou=People,dc=instatsport,dc=com
ou=aHR1,ou=HR,ou=Employees,ou=People,dc=instatsport,dc=com
ou=HR2,ou=HR1,ou=HR,ou=Employees,ou=People,dc=instatsport,dc=com
使用php.net/manual/en/function.ldap-sort.php
应该使用哪种过滤器来获得此结果?:
ou=HR,ou=Employees,ou=People,dc=instatsport,dc=com
ou=HR1,ou=HR,ou=Employees,ou=People,dc=instatsport,dc=com
ou=HR2,ou=HR1,ou=HR,ou=Employees,ou=People,dc=instatsport,dc=com
ou=aHR1,ou=HR,ou=Employees,ou=People,dc=instatsport,dc=com
ou=IT,ou=Employees,ou=People,dc=instatsport,dc=com
ou=Video,ou=Employees,ou=People,dc=instatsport,dc=com
答案 0 :(得分:0)
您不能使用ldap_sort
。
此函数的作用是对返回的条目的属性应用strcmp
。
在这里,您尝试订购所返回条目的DN,而不是按字母顺序排序,而是在层级级别。
你必须实现这一点(或找到已经这样做的人)。
最简单的实现是创建一个包含所有RDN的树,并将该树从root用户打印到leaf,并用逗号递归地插入每个RDN。
编辑:
我花了一些时间尝试快速实现它,这不是你能找到的最好的代码,但它可以成为你想要实现的基础:
function hierarchySort ($a, $b){
$rdn1 = ldap_explode_dn($a,0);
$rdn2 = ldap_explode_dn($b,0);
$count = $rdn1["count"] < $rdn2["count"] ? $rdn1["count"] : $rdn2["count"];
for ($i=0; $i<$count; $i++) {
$j1 = $rdn1["count"] - 1 - $i;
$j2 = $rdn2["count"] - 1 - $i;
$ret = strnatcasecmp($rdn1[$j1], $rdn2[$j2]);
if ($ret != 0) break;
}
if ($rdn1["count"] == $rdn2["count"]) {
return $ret;
}else {
if ($ret != 0) return $ret;
else return $rdn1["count"] < $rdn2["count"] ? -1 : 1;
}
}
// Some simulated LDAP result
$entries = [
0 => [ "dn" => "ou=HR,ou=Employees,ou=People,dc=instatsport,dc=com" ],
1 => [ "dn" => "ou=IT,ou=Employees,ou=People,dc=instatsport,dc=com" ],
2 => [ "dn" => "ou=Video,ou=Employees,ou=People,dc=instatsport,dc=com" ],
3 => [ "dn" => "ou=HR1,ou=HR,ou=Employees,ou=People,dc=instatsport,dc=com" ],
4 => [ "dn" => "ou=aHR1,ou=HR,ou=Employees,ou=People,dc=instatsport,dc=com" ],
5 => [ "dn" => "ou=HR2,ou=HR1,ou=HR,ou=Employees,ou=People,dc=instatsport,dc=com" ],
"count" => 6
];
for ($i=0; $i<$entries['count']; $i++) {
$e = $entries[$i];
$dns[] = $e["dn"];
}
print_r($dns);
usort($dns, 'hierarchySort');
print_r($dns);
输出:
Array
(
[0] => ou=HR,ou=Employees,ou=People,dc=instatsport,dc=com
[1] => ou=IT,ou=Employees,ou=People,dc=instatsport,dc=com
[2] => ou=Video,ou=Employees,ou=People,dc=instatsport,dc=com
[3] => ou=HR1,ou=HR,ou=Employees,ou=People,dc=instatsport,dc=com
[4] => ou=aHR1,ou=HR,ou=Employees,ou=People,dc=instatsport,dc=com
[5] => ou=HR2,ou=HR1,ou=HR,ou=Employees,ou=People,dc=instatsport,dc=com
)
Array
(
[0] => ou=HR,ou=Employees,ou=People,dc=instatsport,dc=com
[1] => ou=aHR1,ou=HR,ou=Employees,ou=People,dc=instatsport,dc=com
[2] => ou=HR1,ou=HR,ou=Employees,ou=People,dc=instatsport,dc=com
[3] => ou=HR2,ou=HR1,ou=HR,ou=Employees,ou=People,dc=instatsport,dc=com
[4] => ou=IT,ou=Employees,ou=People,dc=instatsport,dc=com
[5] => ou=Video,ou=Employees,ou=People,dc=instatsport,dc=com
)
答案 1 :(得分:0)
ldap_sort
现在已弃用,因为它只对服务器返回的结果集进行排序。对于可能不是问题的小结果集,但是对于较大(分页)的结果集,这意味着您从&#34; a&#34;得到结果。到&#34; z&#34;在第一页上,然后将进行排序。在第二页上,您还将获得&#34; a&#34;的结果。到&#34; z&#34;然后将进行排序等等。因此,这种排序并不是大多数人所期望的。
ldap_sort
也只能对实际检索到的字段进行排序。因此,您无法仅检索&#34;名字&#34;并按&#34;第二名&#34;排序。
回答你的问题:我会编写一个类似下面的排序函数,并使用f.e. usort:
function sortByDn($a, $b) {
return strnatcasecmp($a['dn'], $b['dn']);
}
$result = ldap_get_Entries($handle, $resulthandle);
unset($result['count']);
usort($result, 'sortByDn');
这些方面的某些内容实际上可能有所帮助;)
根据您要按排序功能排序的内容,可能需要有所不同!