ldap_get_entries

(PHP 4、PHP 5、PHP 7、PHP 8)

ldap_get_entries获取所有结果条目

描述

ldap_get_entries(LDAP\Connection $ldap, LDAP\Result $result): 数组|false

读取指定结果中的多个条目,然后读取属性和多个值。

参数

ldap

一个 LDAP\Connection 实例,由 ldap_connect() 返回。

result

一个 LDAP\Result 实例,由 ldap_list()ldap_search() 返回。

返回值

成功时,返回一个包含多维数组中的完整结果信息;或在失败时,返回 false

数组的结构如下:多维数组中的键名由属性索引转换而来,并转换为小写。(对于目录服务器来说,属性不区分大小写,但作为数组索引时区分大小写。)

return_value["count"] = number of entries in the result
return_value[0] : refers to the details of first entry

return_value[i]["dn"] =  DN of the ith entry in the result

return_value[i]["count"] = number of attributes in ith entry
return_value[i][j] = NAME of the jth attribute in the ith entry in the result

return_value[i]["attribute"]["count"] = number of values for
                                        attribute in ith entry
return_value[i]["attribute"][j] = jth value of attribute in ith entry

变更记录

版本 描述
8.1.0 ldap 参数现在期望一个 LDAP\Connection 实例,以前它期望一个有效的 ldap 链接 资源
8.1.0 result 参数现在期望一个 LDAP\Result 实例,以前它期望一个有效的 ldap 结果 资源

另请参见

添加注释

用户贡献的注释 19 份注释

chl
15 年前
markus 函数的递归形式,因此它可以直接采用 ldap_get_entries 的结果
<?php
function cleanUpEntry( $entry ) {
$retEntry = array();
for (
$i = 0; $i < $entry['count']; $i++ ) {
if (
is_array($entry[$i])) {
$subtree = $entry[$i];
//此条件应该是多余的,所以请根据您的情况适应递归调用以提高性能。
if ( ! empty($subtree['dn']) and ! isset($retEntry[$subtree['dn']])) {
$retEntry[$subtree['dn']] = cleanUpEntry($subtree);
}
else {
$retEntry[] = cleanUpEntry($subtree);
}
}
else {
$attribute = $entry[$i];
if (
$entry[$attribute]['count'] == 1 ) {
$retEntry[$attribute] = $entry[$attribute][0];
} else {
for (
$j = 0; $j < $entry[$attribute]['count']; $j++ ) {
$retEntry[$attribute][] = $entry[$attribute][$j];
}
}
}
}
return
$retEntry;
}
?>

结果采用如下格式
array(256) {
["uid=doe,ou=People,dc=example,dc=net"]=>
array(3) {
["uid"]=>
string(4) "doe"
["cn"]=>
string(14) "John Doe"
["telephonenumber"]=>
string(4) "1234"
}
["uid=foo,ou=People,dc=example,dc=net"]=>
...
reaper at sci dot fi
21 年前
如果您要处理 Active Directory 并需要获取“lastlogon”、“pwdlastset”或类似的值,您会注意到 AD 给出的值是 Windows FILETIME 时间戳。这意味着,值是自 1.1.1600 00:00:00 起经过的 100 纳秒单位。

要将这些值转换为 PHP 日期函数可以理解的 Unix 时间戳,一种简单的方法如下

function win_filetime_to_timestamp ($filetime) {

$win_secs = substr($filetime,0,strlen($filetime)-7); // 除以 10 000 000 以获得秒
$unix_timestamp = ($win_secs - 11644473600); // 1.1.1600 -> 1.1.1970 秒差
return $unix_timestamp;
}
mackstann / mack%at%incise%dot%org
20 年前
我发现这些数组中的 ["count"] 项非常烦人,所以我制作了一个函数来递归地删除它们

function rCountRemover($arr) {
foreach($arr as $key=>$val) {
# (int)0 == "count”,所以我们需要使用 ===
if($key === "count")
unset($arr[$key]);
elseif(is_array($val))
$arr[$key] = rCountRemover($arr[$key]);
}
return $arr;
}
tomas dot hampl at gmail dot com
12 年前
下方的评论中已经提到,但 <?php ldap_get_entries($connection,$result) ?> 总会将所有属性变为小写。我以非常困难的方式发现这一点,即如果我针对公司 AD 运行 ldap 查询,然后想要显示一些结果,则除非属性名称 area 为小写,否则实际上不显示任何内容。

示例

<?php
// 连接 AD
include('ad_con.php');
// 限制要查找的属性
$attributes_ad = array("displayName","description","cn","givenName","sn","mail","co","mobile","company","displayName");
// 定义基准
$base ="";

// 在我的脚本中,我根据电子邮件进行搜索,$email 变量从表单传递
$result = ldap_search($conn, $base, "mail=$email*", $attributes_ad) or die ("搜索查询出错");

// 将搜索结果放入数组中($conn 变量在包含的 'ad_con.php' 中定义)
$info = ldap_get_entries($conn, $result);

//现在,显示我们想要的结果:
for ($i=0; $i<$info["count"]; $i++)
{
// 显示属性 displayName(注意大小写!)
echo $info[$i]["displayname"][0]

}

?>
Mauro
两年前
要移除烦人的第一个条目(count),只需使用 array_shift()。
peter dot mlich at volny dot cz
四年前
public function entriesToArray($entries=array())
{
$list = array();
for($i=0;$i<$entries['count'];$i++)
{
$row = array();
$dn = $entries[$i]['dn'];
unset($entries[$i]['count']);
unset($entries[$i]['dn']);
foreach($entries[$i] as $key=>$value)
{
if (is_int($key))
{continue;}
$list_in_col = array();
foreach($value as $key2=>$value2)
{
if (!is_int($key2))
{continue;}
$list_in_col[] = $value2;
}
$row[$key] = $list_in_col;
}
$row['dn'] = $dn;
$list[$i] = $row;
}
return $list;
}

/*
将 ldap 条目格式化为更好的数组

array (size=2)
“计数” => 整数型1
0 =>
数组(大小=14)
'ou' =>
array (size=2)
“计数” => 整数型1
0 => 字符串'03024' (长度=5)
0 => 字符串'ou' (长度=2)
'mail' =>
array (size=2)
“计数” => 整数型1
0 => 字符串'[email protected]' (长度=22)
1 => 字符串'mail' (长度=4)
'telephonenumber' =>
array (size=2)
“计数” => 整数型1
0 => 字符串'+420123456781' (长度=13)
2 => 字符串'telephonenumber' (长度=15)
'personaltitle' =>
array (size=2)
“计数” => 整数型1
0 => 字符串'Ing.|' (长度=4)
3 => 字符串'personaltitle' (长度=13)
'sn' =>
array (size=2)
“计数” => 整数型1
0 => 字符串'MySurname' (长度=6)
4 => 字符串'sn' (长度=2)
'givenname' =>
array (size=2)
“计数” => 整数型1
0 => 字符串'MyName' (长度=5)
5 => 字符串'givenname' (长度=9)
“计数” => 整数型6
'dn' => 字符串'cn=mynickid,ou=users,o=mydepartmentid' (长度=24)

数组(大小=1)
0 =>
数组(大小=7)
'ou' =>
数组(大小=1)
0 => 字符串'03024' (长度=5)
'mail' =>
数组(大小=1)
0 => 字符串'[email protected]' (长度=22)
'telephonenumber' =>
数组(大小=1)
0 => 字符串'+420123456781' (长度=13)
'personaltitle' =>
数组(大小=1)
0 => 字符串'Ing.|' (长度=4)
'sn' =>
数组(大小=1)
0 => 字符串'MySurname' (长度=6)
'givenname' =>
数组(大小=1)
0 => 字符串'MyName' (长度=5)
'dn' => 字符串'cn=mynickid,ou=users,o=mydepartmentid' (长度=24)
*/
john at petbrain dot com
23年前
只需要注意:多维数组就像数组中的一个数组....你可以像这样引用dc=americas,dc=icm,dc=org,即myArray[2]->

基本上,你拥有更多深埋在父数组[]的一个元素中的元素,例如myArray[2]

因此,这就是为什么你会看到myArray[1]["dn"][0]....跳过myArray[1]中的第一个元素,并在它当中滚动第一个元素。
markus dot schabel at tgm dot ac dot at
18年前
当您喜欢以ldap_add()的相同风格从LDAP中获取条目时,可以使用以下函数转换此条目。

<?php
/**
* 从 LDAP 中提取关联数组。
*
* 此函数采用 ldap_get_entries() 样式的 LDAP 项,
* 并将其转换为 ldap_add() 所需的关联数组。
*
* @param array $entry 为要转换的项。
*
* @return array 为转换后的项。
*/
function cleanUpEntry( $entry ) {
$retEntry = array();
for (
$i = 0; $i < $entry['count']; $i++ ) {
$attribute = $entry[$i];
if (
$entry[$attribute]['count'] == 1 ) {
$retEntry[$attribute] = $entry[$attribute][0];
} else {
for (
$j = 0; $j < $entry[$attribute]['count']; $j++ ) {
$retEntry[$attribute][] = $entry[$attribute][$j];
}
}
}
return
$retEntry;
}
?>
reuben dot helms at gmail dot com
18年前
Helmuts 编程示例不正确。

PHP 数组从零开始,因此第一个项为 $entry[0],最后一个项为 $entry[$entry["count"] - 1]。

$entry[$entry["count"]] 将永远不会存在,因此他不使用 is_null。

Helmuts 使用 is_null 的方法并不优雅,这只是对数组理解不透彻的表现。

为避免混淆,可以删除 Helmuts 的项和此项。
Jim Granger <tenor at jimgranger.com>
19 年前
另一种忽略最后一个 null 项的方法是减去一次迭代计数,如下所示:

for($i = 0; $i < count($result_array) - 1; $i++)
{
...
}

Helmut 的方法本身更优雅,但我的做法是他建议的上述方法与 null 测试的组合。可能这看起来有点小题大做,但总有备无患。
c dot green at its dot uq dot edu dot au
22 年前
针对第一个消息 ldap_get_entries,我认为对于 php 的动态类型有些困惑。

如果结果是一个字符串,则执行 $foo[0] 将返回该字符串的第一个字符。

如果是数组,则 $foo[0] 将返回整个第一个元素。

它与特定“dn”无关,而是由于 dn 是标量值(即字符串)而不是数组,并且在每种情况下索引工作的不同。

出于调试目的,我建议使用类似内容:

$value = is_array($foo) ? $foo[0] : $foo;



$value = is_array($foo) ? implode($foo, $delimiter) : $foo;
oscara at hinux dot hin dot no
23年前
注意:即使没有找到结果,ldap_get_entries 也会返回 true,如下所示

echo $entries=ldap_get_entries(...);

将打印 Array。

你需要检查 Array 中的行数,如下所示

if($entries["count"]==0) return false;

希望有人受到了帮助...
Ovidiu Geaboc <ogeaboc at rdanet.com>
20 年前
我发现 ldap_get_entries() 函数不能正确处理二进制数据。我不得不用 ldap_get_values_len() 编写我自己的函数。

// 将使用 ldap_get_values_len() 并且构建数组
// 注释:这与以下函数返回的数组类似
// ldap_get_entries() 不同之处在于它没有“count”元素
$i=0;
$entry = ldap_first_entry($this->conn, $this->srchRslt);
执行 {
$attributes = ldap_get_attributes($this->conn, $entry);
对 $j=0;$j<$attributes['count'];$j++ 执行 {
$values = ldap_get_values_len($this->conn, $entry,$attributes[$j]);
$this->rawData[$i][$attributes[$j]] = $values;
}
$i++;
}
当 $entry = ldap_next_entry($this->conn, $entry) 时执行;
// 我们完成了
返回 ($this->rawData);
pmichaud at pobox dot com
22 年前
实际上,ldap_get_entries 将属性名称返回为小写这一事实非常烦人,因为 ldap_get_attributes 显然不会这样做。这真的很烦人,尤其是在拥有属性名称数组并且不得不担心是使用哪个调用从 LDAP 检索条目的情况下。
cbrent at orix dot com dot au
24 年前
请注意,ldap_get_entries 返回一个关联数组,其中属性以小写形式表示。因此,例如,给定名称 ldap 属性与 $ldap[0]["givenname"][0] 关联(针对第一个结果的第一个给定名称),这起初有点令人困惑。
asohn at aircanopy dot net
16 年前
我拼凑出的一些代码。也许 yall 可以从中受益。

<?php
function search_results($info) {
foreach (
$info as $inf) {
if (
is_array($inf)) {
foreach (
$inf as $key => $in) {
if ((
count($inf[$key]) - 1) > 0) {
if (
is_array($in)) {
unset(
$inf[$key]["count"]);
}
$results[$key] = $inf[$key];
}
}
}
}
$results["dn"] = explode(',', $info[0]["dn"]);
return
$results;
}

$user = "asohn";

$ds = ldap_connect("ldap://DOMAIN.net");
if (
$ds) {
$r = ldap_bind($ds);
$sr = ldap_search($ds, "ou=customers,dc=DOMAIN,dc=net", "uid=".$user);
$info = ldap_get_entries($ds, $sr);

echo
$info["count"]." Search Result(s) for \"".$user."\"\n";

$results = search_results($info);
foreach (
$results as $key => $result) {
echo
" ".$key."\n";
if (
is_array($result)){
foreach(
$result as $res){
echo
" ".$res."\n";
}
}
}
ldap_close($ds);
}
?>
Sebastien Troiani
14 年前
看起来返回对象存在限制,数组中只放置了 1000 个项目。
helmut dot patay at scandio dot de
20 年前
如果您遍历条目,如
$entries = ldap_get_entries( $ds, $sr );
注意!
您必须使用 is_null 检查最后一个条目
因为您将比搜索找到的条目多一个条目,
但最后一个条目将为 null
因此,如果您这样做,则很安全
for ( $i = 0; $i < count( $entries ); $i++ ) {
if ( is_null( $entries[ $i ] ) ) continue;
...
}
plonky at gmail dot com
15 年前
希望这可以帮助其他人将属性和值打印在同一行上。当然,这是基本代码

<?php

$ldap_con
= ldap_connect($ldap_server) or die("无法连接到服务器。错误是 " .ldap_error($ldap_con));
$ldap_bd = ldap_bind($ldap_con, $root_dn, $root_pw) or die("无法绑定到服务器。错误是 " .ldap_error($ldap_con));
$result = ldap_search($ldap_con, $personnel_base, "(uid=*)") or die ("查询错误");

$data = ldap_get_entries($ldap_con, $result);

for (
$i=0; $i<=$data["count"];$i++) {
for (
$j=0;$j<=$data[$i]["count"];$j++){
echo
$data[$i][$j].": ".$data[$i][$data[$i][$j]][0]."\n";
}
}
ldap_close($ldap_con);
?>
To Top