我们相信:世界是美好的,你是我也是。平行空间的世界里面,不同版本的生活也在继续...

本文讨论ldap的数据搜索函数ldap_search(),这个函数的功用其实就是个数据匹配外加个分页的功能,就像是传统网站的文章分类页面。本文的ldap_search()和上文的ldap_bind()函数,虽然经常在一起使用,但是两者之间并没有必须的联系。也就是说,这个ldap_search()的使用方式,并不需要必须执行ldap_bind()函数。两者都需要一个ldap_connection对象。

苏南大叔:php如何使用ldap_search搜索目标用户的条目的字段数据? - 搜索目标数据条目
php如何使用ldap_search搜索目标用户的条目的字段数据?(图7-1)

苏南大叔的“平行空间笔记本”博客,记录苏南大叔的代码编程经验文章。本文测试环境:win10nginx@1.15.11php@8.2.9ntsphp_ldap.soopenldap@2.4.32

函数原型

官网文档,参考链接:

ldap_search(
    LDAP\Connection|array $ldap,
    array|string $base,
    array|string $filter,
    array $attributes = [],
    int $attributes_only = 0,
    int $sizelimit = -1,
    int $timelimit = -1,
    int $deref = LDAP_DEREF_NEVER,
    ?array $controls = null
): LDAP\Result|array|false

参数比较多,本文仅仅涉及前几个参数,后续参数待后续文章讨论。所以原型简化为:

ldap_search(
    LDAP\Connection|array $ldap,
    array|string $base,
    array|string $filter,
    array $attributes = []
): LDAP\Result|false

这几个参数的时候,返回值就两种情况。

  • 第一种情况是返回一个result对象(实际效果上类似一个指针),无法直接读取到有用数据。
  • 第二种情况就是返回值false,表明确实没有数据。(实践表面:返回的是result的时候,也可能是count0)。

龙套数据

可以通过下面的两个方式,来制造本文的龙套数据,用户条目。参考文章:

苏南大叔:php如何使用ldap_search搜索目标用户的条目的字段数据? - 测试数据
php如何使用ldap_search搜索目标用户的条目的字段数据?(图7-2)

代码框架

这里先放一下代码的框架,代码如下:

$con = @ldap_connect('ldap://127.0.0.1', 389);
ldap_set_option($con, LDAP_OPT_PROTOCOL_VERSION, 3);
ldap_set_option($con, LDAP_OPT_REFERRALS, 0);
if ($con) {
  // 本文主体代码在这里
}

苏南大叔:php如何使用ldap_search搜索目标用户的条目的字段数据? - 数据查询
php如何使用ldap_search搜索目标用户的条目的字段数据?(图7-3)

搜索之精准匹配

$basedn = "ou=People,dc=my-domain,dc=com";
// $basedn = "dc=my-domain,dc=com";
// $basedn = "dc=com";         // 没有数据
$filter = "uid=hacker";
$filter = "cn=Sergio";
$filter = "sn=Hacker";
$filter = "mail=info@matear.eu";
$filter = "uidNumber=1561";
$filter = "objectClass=top"; // 返回多个
$result = @ldap_search($con, $basedn, $filter);
if ($result) {
    $info = ldap_get_entries($con, $result);
    var_dump($result);
    var_dump($info["count"]);
    var_dump($info);
} else {
    echo "没有数据";
}

苏南大叔:php如何使用ldap_search搜索目标用户的条目的字段数据? - 数据搜索代码一
php如何使用ldap_search搜索目标用户的条目的字段数据?(图7-4)

这个里面要设定basedn,这个就类似一个作用域的设置。值得注意的是:

  • dn里面的作用域里面有两个dc=。如果仅仅在basedn里面仅仅写一个dc=,是查询不到任何数据的。
  • 对于objectClass=top这个条件,实际上所有的节点都符合,所以是返回多个节点数据。
  • ldap_search()的结果LDAP\Result只是个指针,并不是现实的数据,因此需要再次解析。

大范围模糊匹配

除了精准的条件匹配外,filter还支持模糊匹配。下面的例子中,filter是另外的写法。

$basedn = "ou=People,dc=my-domain,dc=com";
$filter = "(|(sn=hack*)(cn=hack*))";
$filter = "(&(sn=hack*)(uid=hack*))";
$result = ldap_search($con, $basedn, $filter);
if ($result) {
    $info = ldap_get_entries($con, $result);
    var_dump($result);
    var_dump($info["count"]);
    var_dump($info);
} else {
    echo "没有数据";
}

苏南大叔:php如何使用ldap_search搜索目标用户的条目的字段数据? - 数据搜索代码二
php如何使用ldap_search搜索目标用户的条目的字段数据?(图7-5)

控制匹配结果的字段

默认返回所有的条目字段,事实上可以通过参数$attributes来控制返回的字段范围。例子:

$basedn = "ou=People,dc=my-domain,dc=com";
$filter = "objectClass=top";
$attributes = ["cn", "mail"];
$result = ldap_search($con, $basedn, $filter, $attributes);
if ($result) {
    $info = ldap_get_entries($con, $result);
    var_dump($result);
    var_dump($info["count"]);
    var_dump($info);
} else {
    echo "没有数据";
}

这个拿到了四个返回值,即使某个节点没有mail属性,也是没有问题的。

苏南大叔:php如何使用ldap_search搜索目标用户的条目的字段数据? - 数据搜索代码三
php如何使用ldap_search搜索目标用户的条目的字段数据?(图7-6)

重大误解

并不是返回了LDAP\Result,就一定找到了数据,也有可能查到的数据count0,实际效果上就等同于返回值false
例如下面的这个例子:

$basedn = "ou=People,dc=my-domain,dc=com";
$filter="(&(sn=hack*)(cn=hack*))";
$result = ldap_search($con, $basedn, $filter);
if ($result) {
    $info = ldap_get_entries($con, $result);
    var_dump($result);
    var_dump($info["count"]);
    var_dump($info);

} else {
    echo "没有数据";
}

苏南大叔:php如何使用ldap_search搜索目标用户的条目的字段数据? - 没有数据的标准
php如何使用ldap_search搜索目标用户的条目的字段数据?(图7-7)

返回值是:

object(LDAP\Result)#2 (0) {
}
int(0)
array(1) {
  ["count"]=>
  int(0)
}

ldap_get_entries()

LDAP\Result进行具体数据解析的函数是:

  • ldap_get_entries($con, $result)
  • ldap_first_entry($con, $result)
  • ldap_get_attributes($con, $entry)
  • ldap_get_dn($con, $entry)

参考代码:

$basedn = "ou=People,dc=my-domain,dc=com";
$filter="(|(sn=hack*)(cn=hack*))";
$result = ldap_search($con, $basedn, $filter);  // object(LDAP\Result)#2 (0) {}
if ($result) {

    // ## 获取所有条目 ##
    // $info = ldap_get_entries($con, $result);
    // var_dump($result);
    // var_dump($info["count"]);
    // var_dump($info);
    // if($info["count"]<=0){
    //     echo "没有数据2";
    // }

    // ## 仅获取第一条条目数据 ##
    $entry = ldap_first_entry($con, $result);
    // object(LDAP\ResultEntry)#3 (0) {}
    if($entry){
        $attrs = ldap_get_attributes($con, $entry);
        var_dump($attrs);
        $user_dn = ldap_get_dn($con, $entry);
        var_dump($user_dn);
        // string(40) "uid=hacker,ou=People,dc=my-domain,dc=com"
    }
} else {
    echo "没有数据";
}

参考文章

结语

更多ldap的经验文章,可以参考苏南大叔的文章链接:

如果本文对您有帮助,或者节约了您的时间,欢迎打赏瓶饮料,建立下友谊关系。
本博客不欢迎:各种镜像采集行为。请尊重原创文章内容,转载请保留作者链接。

 【福利】 腾讯云最新爆款活动!1核2G云服务器首年50元!

 【源码】本文代码片段及相关软件,请点此获取更多信息

 【绝密】秘籍文章入口,仅传授于有缘之人   php    ldap