如何使用LDAP过滤器对LDAP结果进行排序?

时间:2017-10-02 18:18:53

标签: php sorting ldap

我正在使用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 

2 个答案:

答案 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');

这些方面的某些内容实际上可能有所帮助;)

根据您要按排序功能排序的内容,可能需要有所不同!