PHP调用LDAP_Search返回空结果问题求助
问题背景
我是LDAP新手,正尝试让PHP Web应用对接公司的Active Directory服务器。使用如下PHP代码(PHP版本8.3.9,运行于Windows机器):
$ldap_server = 'ldap://server.domain.local'; $ldap_domain = '@domain.local'; $ldapport = 389; $ldap_admin_user = "admin_user"; $ldap_admin_password = 'admin_password'; try { $ldapconn = ldap_connect($ldap_server); ldap_set_option($ldapconn, LDAP_OPT_REFERRALS, 0); ldap_set_option($ldapconn, LDAP_OPT_PROTOCOL_VERSION, 3); $bind = ldap_bind($ldapconn, $ldap_admin_user.$ldap_domain, $ldap_admin_password); if ($bind) { $arr = array('cn', 'sAMAccountName'); $ldapsearch = (object)[]; $ldapsearch = ldap_search( $ldapconn, 'OU=Users,DC=domain,DC=local', "(objectClass=person)", $arr ) or die ("Error trying to bind: ".ldap_error($ldapconn)); var_dump ($ldapsearch); //$entries = ldap_get_entries($ldap, $ldapsearch); } else { echo "SyncError: LDAP bind failed"; } } catch (\Exception $e) { echo "SyncError: LDAP connection failed"; }
执行后得到结果:
object(LDAP\Result)#24 (0) { }
但使用同一机器上的JXplorer LDAP浏览器,用相同凭据、协议和过滤字符串可正常查询到结果。我已尝试修改过滤字符串、更换管理员账号、在ldap_connect中显式指定端口,但均无改善。另外想咨询:若用户嵌套在Users OU下的两个子OU(Group1和Group2)中,当前设置的基准DN(OU=Users,DC=domain,DC=local)是否会影响查询结果?
问题排查与解答
1. LDAP\Result对象并非空结果
你看到的object(LDAP\Result)#24 (0) { }是PHP返回的LDAP结果句柄,它本身不直接存储条目数据,只是指向服务器结果的引用,所以var_dump显示为空对象是正常现象。要获取实际的用户条目,必须用ldap_get_entries函数解析这个句柄。
2. 代码中的变量错误
你注释掉的ldap_get_entries行存在变量名错误:第一个参数写的是$ldap,但实际的LDAP连接句柄是$ldapconn,修正后取消注释即可获取结果:
$entries = ldap_get_entries($ldapconn, $ldapsearch); var_dump($entries);
3. 嵌套子OU的查询范围问题
当前设置的基准DNOU=Users,DC=domain,DC=local不会影响子OU(Group1、Group2)的查询结果。因为PHP的ldap_search函数默认使用**LDAP_SCOPE_SUBTREE**搜索范围,会递归遍历基准DN下的所有层级(包括所有子OU)。只有使用ldap_list函数时,才会只查询基准DN的直接子节点,不会递归子OU。
4. 额外排查建议
- 在
ldap_search后添加错误检查,确认是否存在搜索层面的错误:if (!$ldapsearch) { die("LDAP search failed: " . ldap_error($ldapconn)); } - 确认
ldap_connect是否成功,建议添加判断:if (!$ldapconn) { die("LDAP connection failed: " . ldap_error($ldapconn)); }
内容的提问来源于stack exchange,提问作者Trieu Nguyen-Tran

