使用Simple Paged Results仍遇LDAP Size limit exceeded问题求助
问题原因及解决方法
可能原因
你的问题核心是LDAP服务器设置了分页查询的总结果数限制,而非仅单请求大小限制。很多主流LDAP服务(比如Active Directory、OpenLDAP)会额外配置maxPagedResults(或类似参数),限制分页查询能返回的总条目数——哪怕你用小pageSize分页,总结果也会被卡到500条,此时服务器会返回空Cookie并抛出"Size limit exceeded"错误。
另外,部分服务器对Simple Paged Results的兼容性有限,但你更换PHP和Symfony版本后问题依旧,因此服务器端限制的可能性远大于组件本身的问题。
解决方法
1. 改用Virtual List View (VLV) 查询
如果LDAP服务器支持VLV(大部分主流服务均支持),可以用VLV替代Simple Paged Results。VLV通过索引属性(如uid、cn)分段获取结果,部分服务器对VLV的总结果数限制更宽松,甚至无限制。
在Symfony Ldap中,可通过LdapQueryBuilder手动添加VLV控制:
use Symfony\Component\Ldap\Adapter\ExtLdap\Control\VirtualListViewControl; use Symfony\Component\Ldap\LdapQueryBuilder; // 初始化查询构建器 $qb = $ldap->createQueryBuilder('ou=Users,dc=example,dc=com'); $qb->where('objectClass=user'); // 添加VLV控制:起始位置0,每页100条,请求返回总条目数 $vlvControl = new VirtualListViewControl(0, 100, VirtualListViewControl::BEFORE_AFTER); $qb->addControl($vlvControl); // 循环获取所有分页结果 do { $currentPage = $qb->execute()->toArray(); // 处理当前页数据 // 更新VLV起始位置,继续下一页 $vlvControl->setOffset($vlvControl->getOffset() + count($currentPage)); } while (count($currentPage) > 0);
2. 基于属性范围拆分查询
绕过分页机制,直接通过用户属性的范围拆分查询,确保每个子查询的结果数不超过500条。常见拆分方式:
- 按
uid/cn首字母拆分:依次查询uid>=a且uid<b、uid>=b且uid<c等区间 - 按数值型属性(如
employeeNumber)拆分:查询employeeNumber>=1且employeeNumber<=500、employeeNumber>=501且employeeNumber<=1000等区间
示例代码(按首字母拆分):
$letters = range('a', 'z'); $allUsers = []; foreach ($letters as $index => $letter) { $nextLetter = isset($letters[$index+1]) ? $letters[$index+1] : 'z'; $qb = $ldap->createQueryBuilder('ou=Users,dc=example,dc=com'); $qb->where('objectClass=user') ->andWhere('uid >= :start') ->andWhere('uid < :end') ->setParameter('start', $letter) ->setParameter('end', $nextLetter); $users = $qb->execute()->toArray(); $allUsers = array_merge($allUsers, $users); }
这种方法完全不依赖服务器的分页支持,只要每个子查询结果数低于500即可,适合服务器限制严格的场景。
3. 联系LDAP管理员调整分页限制(备选)
虽然你提到无法调整单请求大小,但可以确认服务器是否存在maxPagedResults这类总分页结果限制,请求管理员放宽该限制。这是最直接的解决方式,但取决于管理员的权限和意愿。
内容的提问来源于stack exchange,提问作者AnKl
相关产品推荐
相关产品推荐

