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

这里的技术是共享的

You are here

php ldap_get_entries 最大条目数 只有一千一万 1000 10000 如何让条目数超过 10000 使用分页功能 有大用 有大大用 有大大大用

下面的方法,无法实现  超过 10000 , 见 /node-admin/19329  有大用 有大大用


php - 如何在 PHP 8 中获取分页 LDAP 查询并读取超过 1000 个条目?

标签 php windows active-directory ldap    


       

我需要获取当前 LDAP 搜索返回的超过 1000 个条目。目前,我在装有 IIS 和 PHP 7.4 的 Windows 服务器上运行,但很快就会升级到 8.0。

到目前为止我尝试过的是:

# Connect to the LDAP server
$ldap = ldap_connect("ldaps://my.ldap.server:636");
ldap_set_option($ldap, LDAP_OPT_PROTOCOL_VERSION, 3);
ldap_set_option($ldap, LDAP_OPT_REFERRALS, 0);
$ldapBind = ldap_bind($ldap, "UserName", "Password");

# Do a search
$searchResult = ldap_search($ldap, "DC=something1,DC=something2", "LDAP query);
$countEntries += ldap_count_entries($ldap, $searchResult);
$info = ldap_get_entries($ldap, $searchResult);

# Process each found LDAP data row - this will be a maximum of 1000 rows
for($i=0; $i < $info["count"]; $i++) {
    # do something ...
}
       

这只会给我前 1000 行,但我需要至少阅读 30000 行。使用像 mail=a* 和 mail=b* 这样的“命名查询”不是一个可行的解决方案,因为那里可能有超过 1000 个条目,所以我需要某种可信的分页方法 - 一页接一页。

我可以看到我很可能应该使用 LDAP controls因为 ldap_control_paged_result 在 PHP 7.4 之后不再是一个选项,但我真的不明白 - 如何使用它?

任何人都可以提供一些关于在这里做什么的提示吗? :-)


       

最佳答案        


       

PHP documentation 中有一个示例(参见示例 #5)关于如何在 PHP 7.4+ 中从 LDAP 获取和分页数据。

官方文档中的以下代码片段已调整为每页 750 项的页面大小。

// $link is an LDAP connection

$cookie = '';

do {
    $result = ldap_search(
        $link, 'dc=example,dc=base', '(cn=*)', ['cn'], 0, 0, 0, LDAP_DEREF_NEVER,
        [['oid' => LDAP_CONTROL_PAGEDRESULTS, 'value' => ['size' => 750, 'cookie' => $cookie]]]
    );
    ldap_parse_result($link, $result, $errcode , $matcheddn , $errmsg , $referrals, $controls);
    // To keep the example short errors are not tested
    $entries = ldap_get_entries($link, $result);
    foreach ($entries as $entry) {
        echo "cn: ".$entry['cn'][0]."\n";
    }
    if (isset($controls[LDAP_CONTROL_PAGEDRESULTS]['value']['cookie'])) {
        // You need to pass the cookie from the last call to the next one
        $cookie = $controls[LDAP_CONTROL_PAGEDRESULTS]['value']['cookie'];
    } else {
        $cookie = '';
    }
    // Empty cookie means last page
} while (!empty($cookie));
       


       

关于php - 如何在 PHP 8 中获取分页 LDAP 查询并读取超过 1000 个条目?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68275972/        

来自  https://www.coder.work/article/7892630



How to get paged LDAP queries in PHP 8 and read more than 1000 entries?


4
           

I need to get more than the 1000 entries returned by my current LDAP search. Currently I am running on a Windows server with IIS and PHP 7.4 but will soon upgrade to 8.0.

What I have tried so far is this:

# Connect to the LDAP server
$ldap = ldap_connect("ldaps://my.ldap.server:636");
ldap_set_option($ldap, LDAP_OPT_PROTOCOL_VERSION, 3);
ldap_set_option($ldap, LDAP_OPT_REFERRALS, 0);
$ldapBind = ldap_bind($ldap, "UserName", "Password");

# Do a search
$searchResult = ldap_search($ldap, "DC=something1,DC=something2", "LDAP query);
$countEntries += ldap_count_entries($ldap, $searchResult);
$info = ldap_get_entries($ldap, $searchResult);

# Process each found LDAP data row - this will be a maximum of 1000 rows
for($i=0; $i < $info["count"]; $i++) {
    # do something ...
}
               

This will only give me the first 1000 rows but I need to read at least 30000 rows. Using "named queries" like mail=a* and mail=b* is not a viable solution as there could be more than 1000 entries in there, so I need some kind of trusted paged approach - one page by another.

I can see that I most likely should use LDAP controls as ldap_control_paged_result is no longer an option after PHP 7.4 but I really don't get that - how to use this?

Would anyone have a few hints on what to do here? :-)

                               
   

1 Answer  正确答案                

   
8
               

There is an example in the PHP documentation (see example #5) on how to fetch and paginate data from LDAP in PHP 7.4+.

The following code snippet from the official documentation has been adjusted to a page size of 750 items per page.

// $link is an LDAP connection

$cookie = '';

do {
    $result = ldap_search(
        $link, 'dc=example,dc=base', '(cn=*)', ['cn'], 0, 0, 0, LDAP_DEREF_NEVER,
        [['oid' => LDAP_CONTROL_PAGEDRESULTS, 'value' => ['size' => 750, 'cookie' => $cookie]]]
    );
    ldap_parse_result($link, $result, $errcode , $matcheddn , $errmsg , $referrals, $controls);
    // To keep the example short errors are not tested
    $entries = ldap_get_entries($link, $result);
    foreach ($entries as $entry) {
        echo "cn: ".$entry['cn'][0]."\n";
    }
    if (isset($controls[LDAP_CONTROL_PAGEDRESULTS]['value']['cookie'])) {
        // You need to pass the cookie from the last call to the next one
        $cookie = $controls[LDAP_CONTROL_PAGEDRESULTS]['value']['cookie'];
    } else {
        $cookie = '';
    }
    // Empty cookie means last page
} while (!empty($cookie));
               
                                   
  • This was exactly what I needed and I am not sure why I didn't find this info myself but thanks a lot for highlighting it. 
    – Beauvais                                    
     Sep 30, 2021 at 15:41                                
  • In case for some reason you don't get a new cookie from ldap_parse_result(), try github.com/FreeDSx/LDAP; A pure PHP LDAP implementation. 
    – Henk Poley                                    
     Jun 23, 2022 at 9:33                                
   

Your Answer

来自  https://stackoverflow.com/questions/68275972/how-to-get-paged-ldap-queries-in-php-8-and-read-more-than-1000-entries        


       

LDAP Controls ¶            

Here are some examples of using LDAP Controls with PHP >= 7.3.0.

示例 #1 Bind with policy information                

<?php

$user  
= 'cn=admin,dc=example,dc=com';
$passwd = 'adminpassword';

$ds = ldap_connect('ldap://localhost');

if (
$ds) {
   
$r = ldap_bind_ext($ds, $user, $passwd, [['oid' => LDAP_CONTROL_PASSWORDPOLICYREQUEST]]);

   if (
ldap_parse_result($ds, $r, $errcode, $matcheddn, $errmsg, $referrals, $ctrls)) {
       if (
$errcode != 0) {
           die(
"Error: $errmsg ($errcode)");
       }
       if (isset(
$ctrls[LDAP_CONTROL_PASSWORDPOLICYRESPONSE])) {
           
$value = $ctrls[LDAP_CONTROL_PASSWORDPOLICYRESPONSE]['value'];
           echo
"Expires in: ".$value['expire']." seconds\n";
           echo
"Number of auth left: ".$value['grace']."\n";
           if (isset(
$value['error'])) {
               echo
"Policy error code: ".$value['error'];
           }
       }
   }
} else {
   die(
"Unable to connect to LDAP server");
}
?>
                   

示例 #2 Modify description only if it's not empty                

<?php
// $link is an LDAP connection

$result = ldap_mod_replace_ext(
   
$link,
   
'o=test,dc=example,dc=com',
   [
'description' => 'New description'],
   [
       [
           
'oid'         => LDAP_CONTROL_ASSERT,
           
'iscritical'  => TRUE,
           
'value'       => ['filter' => '(!(description=*))']
       ]
   ]
);

// Then use ldap_parse_result
?>
                   

示例 #3 Read some values before deletion                

<?php
// $link is an LDAP connection

$result = ldap_delete_ext(
   
$link,
   
'o=test,dc=example,dc=com',
   [
       [
           
'oid'         => LDAP_CONTROL_PRE_READ,
           
'iscritical'  => TRUE,
           
'value'       => ['attrs' => ['o', 'description']]
       ]
   ]
);

// Then use ldap_parse_result
?>
                   

示例 #4 Delete a reference                

<?php
// $link is an LDAP connection

// Without the control it would delete the referenced node
// Make sure to set the control as critical to avoid that
$result = ldap_delete_ext(
   
$link,
   
'cn=reference,dc=example,dc=com',
   [[
'oid' => LDAP_CONTROL_MANAGEDSAIT, 'iscritical' => TRUE]]
);

// Then use ldap_parse_result
?>
                   

示例 #5 Use pagination for a search  分页结果 有大用                

<?php
// $link is an LDAP connection

$cookie = '';

do {
   
$result = ldap_search(
       
$link, 'dc=example,dc=base', '(cn=*)', ['cn'], 0, 0, 0, LDAP_DEREF_NEVER,
       [[
'oid' => LDAP_CONTROL_PAGEDRESULTS, 'value' => ['size' => 2, 'cookie' => $cookie]]]
   );
   
ldap_parse_result($link, $result, $errcode , $matcheddn , $errmsg , $referrals, $controls);
   
// To keep the example short errors are not tested
   
$entries = ldap_get_entries($link, $result);
   foreach (
$entries as $entry) {
       echo
"cn: ".$entry['cn'][0]."\n";
   }
   if (isset(
$controls[LDAP_CONTROL_PAGEDRESULTS]['value']['cookie'])) {
       
// You need to pass the cookie from the last call to the next one
       
$cookie = $controls[LDAP_CONTROL_PAGEDRESULTS]['value']['cookie'];
   } else {
       
$cookie = '';
   }
   
// Empty cookie means last page
} while (!empty($cookie));
?>
                   


       

add a note                

User Contributed Notes 1 note                

up                        
down                        
3
snapplez ¶                    
1 year ago                    
LDAP pagination requires protocol version 3+. If the LDAP_CONTROL_PAGEDRESULTS LDAP control is not working for you, try setting the LDAP protocol version before binding:

<?php

$ldapconn
= ldap_connect($ldapuri) or die("That LDAP-URI was not parseable");

ldap_set_option($ldapconn, LDAP_OPT_PROTOCOL_VERSION, 3);

?>

                       


       

来自  https://www.php.net/manual/zh/ldap.examples-controls.php        


       


       



普通分类: