PHP Conference Japan 2024

ldap_get_entries

(PHP 4, PHP 5, PHP 7, PHP 8)

ldap_get_entries取得所有結果條目

描述

ldap_get_entries(LDAP\Connection $ldap, LDAP\Result $result): array|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 link 資源
8.1.0 result 參數現在需要一個 LDAP\Result 實例;先前,需要有效的 ldap result 資源

參見

新增筆記

使用者貢獻的筆記 19 則筆記

15
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"]=>
...
4
reaper at sci dot fi
21 年前
如果您正在處理 Active Directory,並且需要取得像 'lastlogon'、'pwdlastset' 或類似的值,您會注意到 AD 將這些值以 Windows FILETIME 時間戳記的形式提供。這表示這些值是自 1600 年 1 月 1 日 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); // 1600 年 1 月 1 日 -> 1970 年 1 月 1 日的秒數差
return $unix_timestamp;
}
7
mackstann / mack%at%incise%dot%org
21 年前
我發現這些陣列中的 ["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;
}
7
tomas dot hampl at gmail dot com
12 年前
在下面的評論中已提及,但 <?php ldap_get_entries($connection,$result) ?> 總是將所有屬性轉換為小寫。我從慘痛的經驗中發現,如果我針對企業 AD 執行 LDAP 查詢,然後想要顯示某些結果,除非屬性名稱是小寫,否則實際上不會顯示任何內容。

範例

<?php
// 連線到 AD
include('ad_con.php');
// 限制我們想要搜尋的屬性
$attributes_ad = array("displayName","description","cn","givenName","sn","mail","co","mobile","company","displayName");
// 定義基礎 DN
$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]

}

?>
1
Mauro
2 年前
要移除第一個惱人的條目(count),只需使用 array_shift()。
0
peter dot mlich at volny dot cz
4 年前
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 條目格式化為更好的陣列

陣列 (大小=2)
'count' => int 1
0 =>
陣列 (大小=14)
'ou' =>
陣列 (大小=2)
'count' => int 1
0 => string '03024' (長度=5)
0 => string 'ou' (長度=2)
'mail' =>
陣列 (大小=2)
'count' => int 1
0 => string 'name.surname@myfirm.cz' (長度=22)
1 => string 'mail' (長度=4)
'telephonenumber' =>
陣列 (大小=2)
'count' => int 1
0 => string '+420123456781' (長度=13)
2 => string 'telephonenumber' (長度=15)
'personaltitle' =>
陣列 (大小=2)
'count' => int 1
0 => string 'Ing.|' (長度=4)
3 => string 'personaltitle' (長度=13)
'sn' =>
陣列 (大小=2)
'count' => int 1
0 => string 'MySurname' (長度=6)
4 => string 'sn' (長度=2)
'givenname' =>
陣列 (大小=2)
'count' => int 1
0 => string 'MyName' (長度=5)
5 => string 'givenname' (長度=9)
'count' => int 6
'dn' => string 'cn=mynickid,ou=users,o=mydepartmentid' (長度=24)

陣列 (大小=1)
0 =>
陣列 (大小=7)
'ou' =>
陣列 (大小=1)
0 => string '03024' (長度=5)
'mail' =>
陣列 (大小=1)
0 => string 'name.surname@myfirm.cz' (長度=22)
'telephonenumber' =>
陣列 (大小=1)
0 => string '+420123456781' (長度=13)
'personaltitle' =>
陣列 (大小=1)
0 => string 'Ing.|' (長度=4)
'sn' =>
陣列 (大小=1)
0 => string 'MySurname' (長度=6)
'givenname' =>
陣列 (大小=1)
0 => string 'MyName' (長度=5)
'dn' => string 'cn=mynickid,ou=users,o=mydepartmentid' (長度=24)
*/
1
john at petbrain dot com
23 年前
請注意:多維陣列就像陣列中的陣列... 你的 myArray[2]-> 可以參考像 dc=americas,dc=icm,dc=org 這樣的東西

基本上,在父陣列 [] 的一個元素中,你有多個元素被埋藏在其中,myArray[2]

所以,這就是你看到 myArray[1]["dn"][0] ... 從 myArray[1] 中取出第一個元素,並將其第一個元素取出。
0
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;
}
?>
0
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 的條目和這個條目。
0
Jim Granger <tenor at jimgranger.com>
19 年前
忽略最後一個空條目的另一種方法是從迭代計數中減一,如下所示

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

Helmut 的方法本身更優雅,但我所做的是將上述方法與他建議的空值測試結合起來。看起來可能有點過頭,但安全總比後悔好。
0
c dot green at its dot uq dot edu dot au
23 年前
針對第一個訊息 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;
0
oscara at hinux dot hin dot no
23 年前
注意:即使未找到任何結果,ldap_get_entries 也會傳回 true,像這樣

echo $entries=ldap_get_entries(...);

將會列印 Array。

你必須像這樣檢查陣列中的列數

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

希望這對某些人有所幫助...
-1
Ovidiu Geaboc <ogeaboc at rdanet.com>
21 年前
我發現 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);
do {
$attributes = ldap_get_attributes($this->conn, $entry);
for($j=0; $j<$attributes['count']; $j++) {
$values = ldap_get_values_len($this->conn, $entry,$attributes[$j]);
$this->rawData[$i][$attributes[$j]] = $values;
}
$i++;
}
while ($entry = ldap_next_entry($this->conn, $entry));
// 完成
return ($this->rawData);
-1
pmichaud at pobox dot com
22 年前
實際上,ldap_get_entries 將屬性名稱傳回為小寫這一點真的很煩人,因為 ldap_get_attributes 顯然不會。這真的很惱人,尤其是當擁有屬性名稱的陣列並且必須擔心哪個呼叫用於從 LDAP 擷取條目時。
-1
cbrent at orix dot com dot au
24 年前
請注意,ldap_get_entries 會傳回一個關聯陣列,其中屬性為小寫。例如,givenName ldap 屬性與 $ldap[0]["givenname"][0] 關聯(對於第一個結果的第一個名字),這起初有點令人困惑。
-2
asohn at aircanopy dot net
17 年前
我整理了一些程式碼。也許你們可以從中受益。

<?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);
}
?>
-4
Sebastien Troiani
14 年前
看起來傳回的物件數量有限制 - 陣列中只會放入 1000 個項目
-1
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;
...
}
-2
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