A straightforward way that returns a complete array after pulling all pages follows. This solution improves on a similar one posted on SO, by reusing the base methods as much as possible. However, I feel that:
Unfortunately, I've not had luck with a design that addresses these concerns. Ideas welcome.
public function searchAllEntries(
$filter, $basedn = null, $scope = self::SEARCH_SCOPE_SUB,
array $attributes = [], $sort = null, $collectionClass = null,
$sizelimit = 0, $timelimit = 0
)
{
// calculate page size, then remove it from the filter as we need
// ldap_search to grab as many as it can, per page
$pagesz = ($filter['sizelimit'] ?: ($sizelimit ?: 500));
unset($filter['sizelimit']);
// run the loop, grabbing pages
$ldap = $this->getResource();
$result = [];
$cookie = '';
ErrorHandler::start(E_WARNING);
ldap_set_option($ldap, LDAP_OPT_PROTOCOL_VERSION, 3);
do {
ldap_control_paged_result($ldap, $pagesz, true, $cookie);
// run the search and add in the results
$collection = $this->search(
$filter, $basedn, $scope, $attributes, $sort, $collectionClass,
null, // no size limit: we need maximum per page
$timelimit
);
$result = array_merge($result, $collection->toArray());
// get that pesky search result resource handle, which is a
// private member of the collection's inner iterator
$inner = $collection->getInnerIterator();
$steal = function (DefaultIterator $it) { return $it->resultId; };
$steal = \Closure::bind($steal, null, $inner);
$entry = $steal($inner);
// get the next page cookie
ldap_control_paged_result_response($ldap, $entry, $cookie);
} while (! empty($cookie));
// ensure that subsequent reads don't attempt to use paging
ldap_control_paged_result($ldap, 0);
ErrorHandler::stop();
return $result;
}