欢迎各位兄弟 发布技术文章

这里的技术是共享的

You are here

php ad ldap filter 过滤 示例 AG chatgpt 有大用 有大大用

<?php
#php 代码中  $filter 过滤器的表示用
$filter = "(objectClass=*)"; //选择器                                  表示所有
$filter = "(&(sAMAccountName=11111111))"; //选择器  & 就是且符号,与符号 ,,,,,,,,,,, 工号为11111111    #注意sAMAccountName 最好区分大小写, 第一个为小写,否则可能会报错,或取不到数据
$filter = "(sAMAccountName=11111111)"; //选择器       工号为11111111
$filter = "SamAccountName=" . '11111111'; //选择器    工号为11111111
$filter="(|(sn=小明*)(givenname=小明*))"; //选择器         |  就是或符号,,,,,,,,,,,,表示 姓(sn)小明开头 或 名(givename)以小明开头
$filter = "(&(sAMAccountName=11111111)(objectClass=user))";    & 就是且符号,与符号 ,,,,,,,,,,, 表示工号为11111111 ,且对象类别为用户   objectClass=user 详解见   /node-admin/22639
$filter = "(sAMAccountName=*11111*)";   //选择器       表示模糊查询工号中包含有 11111
?>














$filter = "(objectClass=*)";//选择器        $filter = "(&(sAMAccountName=小明))";//选择器        $filter = "SamAccountName=" . $gh; //根据工号 比如 11111111        $filter="(|(sn=小明*)(givenname=小明*))"; 区别

在 LDAP 查询中,过滤器($filter)的构建非常重要,它会直接影响查询结果。以下是几种常见过滤器用法的区别和适用场景:

1. (objectClass=*) - 匹配所有对象

php                    
$filter = "(objectClass=*)";                    
               
  • 作用:查询所有类型的对象(用户、计算机、组等)

  • 特点

    • 最宽泛的查询,会返回指定搜索基中的所有条目

    • 性能消耗大,不建议在生产环境中使用

    • 通常用于测试连接或获取目录结构

2. (&(sAMAccountName=小明)) - 精确匹配用户登录名

php                    
$filter = "(&(sAMAccountName=小明))";                    
               
  • 作用:精确匹配 sAMAccountName 属性为"小明"的用户

  • 特点

    • sAMAccountName 是 AD 中的登录名(通常等同于用户名或前缀)

    • 精确匹配(区分大小写),不匹配部分值

    • 最高效的用户查询方式之一

    • 注意这里的 & 是多余的,可以直接写 (sAMAccountName=小明)

3. (SamAccountName=11111111) - 按工号查询

php                    
$filter = "(sAMAccountName=" . $gh . ")";  // 注意正确大小写是 sAMAccountName                    
               
  • 作用:查询工号为指定值的用户(假设工号作为登录名)

  • 特点

    • 类似上一个,但使用变量构造查询

    • 需注意属性名大小写(正确应为 sAMAccountName

    • 适合员工工号与登录名相同的场景

4. (|(sn=小明*)(givenname=小明*)) - 模糊匹配姓名

php                    
$filter = "(|(sn=小明*)(givenname=小明*))";                    
               
  • 作用:查询姓氏(sn)或名字(givenname)包含"小明"的用户

  • 特点

    • | 表示 OR 逻辑(或)

    • 使用通配符 * 进行模糊匹配(匹配开头)

    • sn (Surname) 是姓氏

    • givenname 是名字

    • 适合中文姓名查询,但不如下面方式精确

最佳实践建议

  1. 精确查询(效率最高):

    php                            
    $filter = "(sAMAccountName=11111111)";  // 用工号作为登录名时                            

                           

                           

                           

                       

  2. 中文姓名查询

    php                            
    $filter = "(displayName=小明*)";  // 显示名模糊匹配(常用) // 或 $filter = "(cn=小明*)";  // 通用名匹配                            

                           

                           

                           

                       

  3. 复合查询(多个条件):

    php                            
    $filter = "(&(objectCategory=person)(objectClass=user)(sn=史*))";                            

                           

                           

                           

                       

重要区别总结

过滤器类型匹配方式适用场景性能
(objectClass=*)                            所有对象测试/调试
(sAMAccountName=x)                            精确匹配登录名用户认证
(sAMAccountName=工号)                            精确匹配工号员工查询
`((sn=x*)(givenname=x*))`模糊匹配姓名中文名搜索

在实际应用中,尽量使用精确查询(如 sAMAccountName)以提高性能,模糊查询应谨慎使用通配符(尤其特别是开头通配符如 *小明 会导致性能问题)。

$filter = "(objectClass=*)";//选择器        $filter = "(&(sAMAccountName=小明))";//选择器        $filter = "SamAccountName=" . $gh; //根据工号 比如 11111111  $filter = "(SamAccountName=*11111*)";//选择器        $filter="(|(sn=小明*)(givenname=小明*))"; 区别

在 PHP LDAP 查询中,$filter 决定了搜索条件。不同的 $filter 写法会影响查询的结果和效率。以下是每种写法的区别和适用场景:


1. (objectClass=*) — 查询所有对象                

php                    
$filter = "(objectClass=*)";                    
               
  • 作用:返回所有对象(用户、计算机、组等)。

  • 特点

    • 最宽泛的查询,无任何过滤条件。

    • 会返回 OU(组织单位)下的所有条目。

    • 性能非常差,不建议在生产环境中使用(可能会返回数千条记录)。

  • 适用场景

    • 测试 LDAP 连接是否正常。

    • 目录结构遍历(如获取某个 OU 下的所有对象)。


2. (&(sAMAccountName=小明)) — 精确匹配用户登录名                

php                    
$filter = "(&(sAMAccountName=小明))";                    
               
  • 作用:查询 sAMAccountName(AD 登录名)完全匹配 "小明" 的用户。

  • 特点

    • sAMAccountName 是 AD 的标准登录名(Windows 用户名)。

    • & 是 逻辑与 运算符,但这里单独使用时与 (sAMAccountName=小明) 效果相同。

    • 精确匹配(区分大小写)。

    • 查询效率高(推荐用于用户认证)。

  • 适用场景

    • 精确查找某个用户(如 sAMAccountName = "zhangsan")。


3. (SamAccountName=11111111) — 按工号查询                

php                    
$gh = "11111111"; $filter = "(sAMAccountName=" . $gh . ")";                    
               

⚠ 注意: 正确写法是 sAMAccountName(注意大小写),SamAccountName 是错误的(可能导致查询失败)。

  • 作用:查找 sAMAccountName 完全匹配 "11111111" 的用户。

  • 特点

    • 如果员工登录名与工号相同(如 11111111),则可直接用它查询。

    • 最高效的用户查询方式之一(比模糊查询快得多)。

  • 适用场景

    • 员工工号作为登录名的查询(如 "11111111")。


4. (sAMAccountName=*11111*) — 模糊匹配工号                

php                    
$filter = "(sAMAccountName=*11111*)";                    
               
  • 作用:查找 sAMAccountName 包含 "11111" 的用户(如 "js11111111" 或 "11111abc")。

  • 特点

    • * 是 通配符,表示任意字符(0 或多个)。

    • 模糊匹配,效率低于精确查询(特别是 * 在开头时)。

  • 适用场景

    • 部分匹配工号(如 11111 可能是部门编号前缀)。


5. (|(sn=小明*)(givenname=小明*)) — 模糊匹配姓氏或名字                

php                    
$filter = "(|(sn=小明*)(givenname=小明*))";                    
               
  • 作用:查找 sn(姓氏)  givenName(名字) 开头 为 "小明" 的用户。

  • 特点

    • | 是 逻辑或 运算符。

    • sn = Surname(姓氏),givenName = 名字

    • 适合中文姓名查询(但效率低于 sAMAccountName 精确查询)。

    • * 在结尾(如 小明*)比在开头(如 *小明)效率更高。

  • 适用场景

    • 按中文姓名模糊查询(如 "张"、“李"、“王")。


总结与最佳实践                

查询方式示例效率适用场景
所有对象                            (objectClass=*)                            ❌ 极差调试 / 获取所有对象
精确登录名                            (sAMAccountName=小明)                            ✅ 最高用户认证
精确工号                            (sAMAccountName=11111111)                            ✅ 最高按工号查询
模糊工号                            (sAMAccountName=*11111*)                            ⚠ 中等部分匹配工号
模糊姓名                            `((sn=史*)(givenname=史*))`⚠ 较差

🚀 最佳实践建议

  • 尽量使用 sAMAccountName 精确查询(最快)。

  • 模糊查询 避免 * 放在开头(如 *小明 会很慢)。

  • 中文姓名查询可用 (displayName=史*) 或 (cn=史*)(比 (|(sn=...)(givenname=...)) 更高效)。

$filter = "SamAccountName=" . $gh;  与  $filter = "(sAMAccountName=" . $gh . ")" 区别

在 LDAP 查询 中,$filter = "SamAccountName=" . $gh; 和 $filter = "(sAMAccountName=" . $gh . ")"; 看似相似,但关键区别在于 () 及属性名大小写,具体分析如下:


1. 语法格式区别                

写法示例是否规范解析结果
$filter = "SamAccountName=" . $gh;                            SamAccountName=11111111                            ❌ 错误缺少括号 (),属性名大小写错误(正确应为 sAMAccountName
$filter = "(sAMAccountName=" . $gh . ")";                            (sAMAccountName=11111111)                            ✅ 正确带括号,属性名大小写正确

2. 影响与后果                

(1) 缺少括号 ()                

  • 错误写法 SamAccountName=11111111

    • ❌ 直接导致查询失败,因为 LDAP 过滤器必须用 () 包裹条件(除非是复杂逻辑组合)。

    • 等效于 "(SamAccountName=11111111)"(但属性名仍错误)。

(2) 属性名大小写错误                

  • SamAccountName 是错误的(正确应为 sAMAccountName)。

    • Active Directory 中,该属性 严格区分大小写,必须为 sAMAccountName

    • 错误的写法可能导致 查询返回空结果(即使数据存在)。


3. 正确的写法                

如果要查询工号 $gh(如 11111111),必须:

php                    
$filter = "(sAMAccountName=" . $gh . ")";  // ✅ 规范写法                    
               

或(PHP 8.0+ 可用更简洁的字符串插值):

php                    
$filter = "(sAMAccountName=$gh)";  // ✅ 现代写法                    
               

4. 其他注意事项                

  1. 变量安全

  • 如果 $gh 来自用户输入,应过滤特殊字符(如 *()),防止 LDAP 注入:

    php                                
    $gh = ldap_escape($gh, "", LDAP_ESCAPE_FILTER);                                

                               

                               

                               

                           

  • 通配符查询

    • 如果需要 模糊匹配(如部分工号),可加 *

      php                                
      $filter = "(sAMAccountName=*$gh*)";  // 匹配包含工号的登录名                                

                                 

                                 

                                 

                             


    总结                

    区别点错误写法 "SamAccountName=".$gh                            正确写法 "(sAMAccountName=".$gh.")"                            
    括号                            ❌ 缺失✅ 包含
    属性名大小写                            ❌ SamAccountName(错误)✅ sAMAccountName(正确)
    查询结果                            失败/无结果正常返回匹配数据

    🔹 结论:必须使用 (sAMAccountName=xxx) 格式,确保括号和大小写正确!

    $filter = "SamAccountName=" . $gh; 为什么我在 php 看能查到结果

    如果 $filter = "SamAccountName=" . $gh; 在你的 PHP 代码中能查到结果,可能有几个原因:

    可能原因分析

    1. PHP-LDAP 的宽松处理

    • 某些 PHP 版本的 LDAP 扩展可能会自动补全缺失的括号(但这不是标准行为)

    • 类似 MySQL 的宽松模式,某些错误写法仍可能被"宽容"执行

  • LDAP 服务器端的自动修正

    • 某些 LDAP 服务器(如 OpenLDAP)可能会自动修正简单的语法错误

    • Active Directory 通常更严格,但特定配置下可能也允许这种写法

  • 测试数据巧合

    • 如果你恰好测试的是 "(objectClass=*)" 或默认查询

    • 服务器可能返回了所有对象,而你的代码刚好匹配到了结果

  • 属性名大小写的特殊情况

    • 虽然规范是 sAMAccountName,但某些 LDAP 实现可能不区分大小写

    • 这是非标准的,不建议依赖这种行为

    验证方法

    php                    
    // 测试1:打印最终生成的过滤器 echo "实际使用的过滤器: " . $filter . "\n"; // 测试2:使用规范写法对比 $correctFilter = "(sAMAccountName=" . $gh . ")"; $searchCorrect = ldap_search($ldapConn, $baseDn, $correctFilter); $entriesCorrect = ldap_get_entries($ldapConn, $searchCorrect); // 比较结果 echo "错误写法结果数: " . $entries["count"] . "\n"; echo "正确写法结果数: " . $entriesCorrect["count"] . "\n";                    
                   

    建议

    1. 始终使用规范写法

      php                            
      $filter = "(sAMAccountName=" . $gh . ")";                            

                             

                             

                             

                         

    2. 添加错误检查

      php                            
      if (!ldap_search($ldapConn, $baseDn, $filter)) {    echo "搜索失败: " . ldap_error($ldapConn); }                            

                             

                             

                             

                         

    3. 防止LDAP注入

      php                            
      $gh = ldap_escape($gh, "", LDAP_ESCAPE_FILTER);                            

                             

                             

                             

                         

    即使当前能工作,这种写法存在风险:

    • 不同LDAP服务器可能表现不同

    • PHP版本升级可能导致不再兼容

    • 存在潜在的安全风险

    最佳实践是严格按照LDAP过滤器规范编写查询条件。

    $filter = "(&(sAMAccountName=小明))"; 与  $filter = "(sAMAccountName=小明)";  区别

    $filter = "(&(sAMAccountName=小明))"; vs $filter = "(sAMAccountName=小明)"; 的区别

    1. 语法结构差异

    • (&(sAMAccountName=小明))

      • 表示一个逻辑与(&)操作的单一条件

      • 语法正确但冗余,因为单个条件不需要用&包裹

    • (sAMAccountName=小明)

      • 标准的单一条件过滤

      • 简单直接,是推荐写法

    2. 实际效果

    在实际查询中,两者效果完全相同,都会:

    • 精确匹配sAMAccountName等于"小明"的记录

    • 查询性能无差异

    • 返回相同结果

    3. 何时需要&运算符

    &(逻辑与)只在多个条件组合时才需要:

    php                    
    // 正确用例:查询同时满足两个条件的记录 $filter = "(&(sAMAccountName=小明)(objectClass=user))";                    
                   

    4. 最佳实践

    1. 单一条件时应使用简单格式:

    php                    
    $filter = "(sAMAccountName=小明)";  // ✅推荐                    
                   
    1. 多个条件组合时才使用&

    php                    
    $filter = "(&(条件1)(条件2)(条件3))";                    
                   

    5. 为什么第一种写法也能工作?

    虽然&在单条件时是冗余的,但:

    • LDAP协议允许这种语法

    • 服务器会自动解析去除冗余

    • 不影响最终查询结果

    结论

    两种写法都能正确查询,但从代码规范角度:

    • **(sAMAccountName=小明)**更简洁规范,推荐使用

    • &的写法虽能工作,但增加了不必要的复杂度

    $filter = "(&(sAMAccountName=小明)(objectClass=user))"; 这是两个同时满足,,,只要有一个满足 怎么写

    LDAP 查询:同时满足 vs. 任意一个满足的条件写法

    在 LDAP 查询中,使用不同的逻辑运算符来控制多个条件之间的关系。

    1. 需要同时满足(AND 逻辑)

    php                    
    $filter = "(&(sAMAccountName=小明)(objectClass=user))";                    
                   
    • 解释

      • & 是逻辑 AND(与)运算符

      • 查询同时满足:sAMAccountName 是"小明"  objectClass 是"user"的记录

      • 两个条件必须都满足才会返回结果

    2. 需要任意一个满足(OR 逻辑)

    php                    
    $filter = "(|(sAMAccountName=小明)(objectClass=user))";                    
                   
    • 解释

      • | 是逻辑 OR(或)运算符

      • 查询满足:sAMAccountName 是"小明" 或者 objectClass 是"user"的记录

      • 只要满足任一条件就会返回结果

    3. 更复杂的组合示例

    php                    
    // 查找:(sAMAccountName=小明 或 11111111) 且必须是用户 $filter = "(&(|(sAMAccountName=小明)(sAMAccountName=11111111))(objectClass=user))"; // 查找:姓氏为"史" 或 名字包含"平忠",且必须是用户 $filter = "(&(|(sn=史*)(givenName=*平忠*))(objectClass=user))";                    
                   

    注意事项

    1. 运算符优先级

    • LDAP 过滤器从左到右评估

    • 可以用嵌套括号控制优先级

  • 性能考虑

    • OR 查询通常比 AND 查询慢

    • 避免在开头使用通配符(如 *小明

  • 安全提醒

    php                            
    $name = ldap_escape($_GET['name'], "", LDAP_ESCAPE_FILTER); $filter = "(|(sn=$name*)(givenName=$name*))";                            

                           

                           

                           

                       

    • 对外部输入使用 ldap_escape() 防止注入

    推荐在大多数情况下使用明确的 AND/OR 逻辑使查询意图更清晰。


    普通分类: