国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁(yè) > 開發(fā) > PHP > 正文

使用PHP連接LDAP服務(wù)器

2024-05-04 23:04:13
字體:
供稿:網(wǎng)友

  本文將演示如何使用php連接一個(gè)ldap服務(wù)器。具體的例子是連接到一個(gè)公共的ldap服務(wù)器并且進(jìn)行搜索。這個(gè)例子模擬的是netscape communicator 4.*,通過自己的地址本連接到ldap資源。

  ldap介紹

  可能不少人已經(jīng)聽說過ldap,但是卻不了解它具體是什么東東和如何工作。在這里我將不會(huì)很詳細(xì)地介紹ldap,只是對(duì)該協(xié)議做一個(gè)簡(jiǎn)介。

  ldap是一個(gè)用來發(fā)布目錄信息到許多不同資源的協(xié)議。通常它都作為一個(gè)集中的地址本使用,不過根據(jù)組織者的需要,它可以做得更加強(qiáng)大。

  ldap最基本的形式是一個(gè)連接數(shù)據(jù)庫(kù)的標(biāo)準(zhǔn)方式。該數(shù)據(jù)庫(kù)為讀查詢作了優(yōu)化。因此它可以很快地得到查詢結(jié)果,不過在其它方面,例如更新,就慢得多。要特別注意的是,ldap通常作為一個(gè)hierarchal數(shù)據(jù)庫(kù)使用,而不是一個(gè)關(guān)系數(shù)據(jù)庫(kù)。因此,它的結(jié)構(gòu)用樹來表示比用表格好。正因?yàn)檫@樣,就不能用sql語(yǔ)句了。

  簡(jiǎn)單說來,ldap是一個(gè)得到關(guān)于人或者資源的集中、靜態(tài)數(shù)據(jù)的快速方式。

要求

   phpv.4(以前的版本也可以,不過沒有經(jīng)過測(cè)試),編譯支持ladp,即使用編譯時(shí)帶--with-ldap公共的ldap目錄。在例子中提供了兩個(gè)。

例子概覽

1.設(shè)置公共ldap服務(wù)器的信息
2.創(chuàng)建一個(gè)ldap查詢
3.連接到ldap服務(wù)器
4.如果連接成功,處理查詢
5.格式化輸出
6.關(guān)閉連接
7.設(shè)計(jì)搜索界面的html表格
8.顯示結(jié)果

設(shè)置公共ldap服務(wù)器的信息

  我們要做的第一件事情是定義所有欲搜索的ldap服務(wù)器的信息

"ldap_name" = 新的ldap項(xiàng)目的名字
"ldap_server" = 新的ldap項(xiàng)目的ip地址或者主機(jī)名
"ldap_root_dn" = 新的ldap項(xiàng)目的根的辨識(shí)名

<?php

$ldap_name[0] = "netscape net center";
$ldap_server[0] = "memberdir.netscape.com";
$ldap_root_dn[0] = "ou=member_directory,o=netcenter.com";

$ldap_name[1] = "bigfoot";
$ldap_server[1] = "ldap.bigfoot.com";
$ldap_root_dn[1] = "";


//如果沒有選擇服務(wù)器的話將它設(shè)置為0
if(!$server_id)
$server_id=0;

?>

  建立ldap查詢

  前面已經(jīng)提到,ldap查詢與sql查詢是不一樣的。因此,語(yǔ)句要受到一定的限制,以下是一個(gè)基本的例子。

//create query $ldap_query = "cn=$common";

  在我們的例子中,“cn”是我們要進(jìn)行搜索的屬性,而$common是由搜索的form中得到的字符串變量。ldap的查詢語(yǔ)句語(yǔ)句可使用通配符‘*’。例如‘$stanley’將可以找出‘dan stanley’。

連接到ldap服務(wù)器

  以下的函數(shù)連接到一個(gè)ldap資源,并且將連接的識(shí)別號(hào)賦給一個(gè)變量,就好象連接到一個(gè)通常的數(shù)據(jù)庫(kù)一樣,例如mysql。

<?php

//連接到ldap
$connect_id = ldap_connect($ldap_server[$server_id]);

?>

  在我們的例子中,“$connect_id”是連接的識(shí)別號(hào),$ldap_server是可能的ldap服務(wù)器數(shù)組,而$server_id是由搜索表格得到的ldap服務(wù)器變量。

如果連接成功,處理查詢

   如果連接成功的話,我們將得到一個(gè)有效的ldap連接識(shí)別號(hào),這樣我們就可以處理查詢。

<?php
if($connect_id)
{
//認(rèn)證
$bind_id = ldap_bind($connect_id);

//執(zhí)行搜索
$search_id = ldap_search($connect_id, $ldap_root_dn[$server_id], $ldap_query);

//將結(jié)果集合分配給一個(gè)數(shù)組
$result_array = ldap_get_entries($connect_id, $search_id);
}
else
{
//顯示連接錯(cuò)誤
echo "could not connect to ldap server: $ldap_server[$server_id]";
}

?>

  一旦我們與ldap服務(wù)器建立好連接,我們就必須進(jìn)行認(rèn)證。php在連接大多數(shù)的數(shù)據(jù)庫(kù)時(shí),都是通過發(fā)送用戶名和密碼來進(jìn)行的。不過,在ldap中,認(rèn)證是未知的,直到進(jìn)行一個(gè)bind操作。在我們的例子中,“$bind_id”是綁定連接的標(biāo)識(shí)符。我們是通過匿名綁定到公共的ldap服務(wù)器的。因此,在執(zhí)行l(wèi)dap_bind()時(shí),只使用連接識(shí)別號(hào)就可以了,無需其它的參數(shù)。

  在經(jīng)過認(rèn)證后(這里是匿名的),我們就可以使用ldap_search()函數(shù)來執(zhí)行查詢,產(chǎn)生的$search_id是我們搜索的連接識(shí)別符。

  然后,我們使用ldap_get_entries()函數(shù)將結(jié)果集賦給$result_array變量。這樣我們能夠以邏輯的方式排列信息,以便顯示。

格式化輸出

  在執(zhí)行完ldap搜索后,返回的數(shù)據(jù)是以查找的順序排列的。不過我們?cè)谂判驎r(shí)沒有sql這樣方便,使用order by語(yǔ)句就可以了。通常多數(shù)公共的ldap目錄都沒有標(biāo)準(zhǔn)的大小規(guī)范。排序是基于字符的ascii值,我們必須將字符全部格式化為小寫,以便按字母的順序輸出。

  要特別注意的是,返回的ldap結(jié)果集是一個(gè)多維的數(shù)組。因此,我們腳本中的$result_array的結(jié)構(gòu)如下:

$result_array[0]["cn"] [0] = "dannie stanley"
["dn"] [0] = "uid=dannie,dc=spinweb.net"
["givenname"][0] = "dannie"
["sn"] [0] = "stanley"
["mail"] [0] = "[email protected]"
$result_array[1]["cn"] [0] = "michael reynolds"
["dn"] [0] = "uid=michael,dc=spinweb.net"
["givenname"][0] = "michael"
["sn"] [0] = "reynolds"
["mail"] [0] = "[email protected]"

  數(shù)據(jù)以這種格式存放的原因是每個(gè)屬性都可能有超過一個(gè)值(象樹的結(jié)構(gòu))。例如,如果我的名字是‘dannie’,我還可以在ldap中增加一些屬性,例如:

$result_array[0]["cn"] [0] = "dannie stanley"
["dn"] [0] = "uid=dannie,dc=spinweb.net"
["givenname"][0] = "dannie"
["givenname"][0] = "dan"
["sn"] [0] = "stanley"
["mail"] [0] = "[email protected]"

  在我們的搜索中,我們只關(guān)心每個(gè)屬性的首個(gè)值,因此除了dn只有一個(gè)值外,其它我們只使用每個(gè)屬性中序號(hào)為0的值。以下就是屬性和它們含義的簡(jiǎn)單列表:

"cn" = common name
"dn" = distinguished name
"givenname" = first name
"sn" = last name
"mail" = email地址


<?php

//如果搜索成功,將結(jié)果排序
if($result_array)
{
for($i=0; $i {
$format_array[$i][0] = strtolower($result_array[$i]["cn"][0]);
$format_array[$i][1] = $result_array[$i]["dn"];
$format_array[$i][2] = strtolower($result_array[$i]["givenname"][0]);
$format_array[$i][3] = strtolower($result_array[$i]["sn"][0]);
$format_array[$i][4] = strtolower($result_array[$i]["mail"][0]);
}

//排序數(shù)組
sort($format_array, "sort_string");

for($i=0; $i {
$cn = $format_array[$i][0];
$dn = $format_array[$i][1];
$fname = ucwords($format_array[$i][2]);
$lname = ucwords($format_array[$i][3]);
$email = $format_array[$i][4];

if($dn && $fname && $lname && $email)
{
$result_list .= "$fname $lname";
$result_list .= " <}
elseif($dn && $cn && $email)
{
$result_list .= "<a href='/"ldap://$ldap_server[$server_id]/$dn/"'>$cn</a>";
$result_list .= " <a href='/"mailto:$email/"'>$email</a>
/n";
}
}
}
else
{
echo "result set empty for query: $ldap_query";
}


?>

  在我們的例子中,$format_array是我們建立的新數(shù)組,里面包括有查詢的結(jié)果,并且被格式化用作輸出。首先循環(huán)$result_array中的每個(gè)元素,并且將它分配給一個(gè)兩維的數(shù)組用作排序。同時(shí)我們使用strtolower()函數(shù)將所有的值變?yōu)樾憽?br>
  接著,我們使用php自帶的一個(gè)稱為sort()的函數(shù)進(jìn)行排序。首個(gè)參數(shù)是要排序的數(shù)組,另一個(gè)是要執(zhí)行的排序類型,該類型是由php的文檔定義的。由于我們根據(jù)字符串排序,我們使用“sort_string”。

  第三,我們循環(huán)已經(jīng)格式化好的數(shù)組,并且將它分配給一個(gè)名字為$result_list的輸出字符,該字符包含了html描述。要特別注意的是,在超鏈接中,我使用的是ldap的url格式。這個(gè)格式的例子類似:href="ldap://ldap.domain.net/uid=dannie,dc=domain.net"。

關(guān)閉連接

  現(xiàn)在我們所有的數(shù)據(jù)已經(jīng)包含在$result_list中了,我們可以安全地關(guān)閉ldap的連接。

<?php

//關(guān)閉連接
ldap_close($connect_id);

?>

定制搜索界面的html表格

  最后,我們要定制搜索用的html表格,它是用來給用戶執(zhí)行搜索的。

//定制表格
echo " <center><form action='/"$php_self/"' method='/"get/"'>";
echo "search in:<select name='/"server_id/"'>"; //循環(huán)以建立select選項(xiàng) for($i=0; $i<count($ldap_name); <br $i++)> echo "<o(jì)ption selected value='/"$i/"'>".$ldap_name[$i]."</option>"; echo "</select>
";
echo "search for:<input name='/"common/"' type='/"text/"'>";
echo "<input name='/"lookup/"' type='/"submit/"' value='/"go/"'>
";
echo "(you can use * for wildcard searches, ex. * stanley will find all stanleys)
";
echo "</form></center>";

?>

  代碼中的$php_self是一個(gè)全局的常量,代表的是腳本頁(yè)面自身,其中的循環(huán)是用來通過我們的$ldap_name變量創(chuàng)建select選項(xiàng)。

顯示結(jié)果

  現(xiàn)在所有的工作已經(jīng)完成了,我們將打印出結(jié)果集。如果沒有符合的結(jié)果,將會(huì)顯示"no results"的信息。

<?php

//顯示結(jié)果
if($result_list)
{
echo " <center><table border='/"1/"' cellpadding='/"10/"' cellspacing='/"0/"'
bgcolor=/"#ffffea/" width=/"450/"> <tbody><tr><td>$result_list</td></tr>
</tbody></table></center>";
}
else
echo "no results";


?>

源代碼

  以下是完整的源代碼,只要將它剪切并粘貼到一個(gè)html文檔,就可以嘗試一下了。

<?php

$ldap_name[0] = "netscape net center";
$ldap_server[0] = "memberdir.netscape.com";
$ldap_root_dn[0] = "ou=member_directory,o=netcenter.com";

$ldap_name[1] = "bigfoot";
$ldap_server[1] = "ldap.bigfoot.com";
$ldap_root_dn[1] = "";

//如果沒有選擇服務(wù)器的話將它設(shè)置為0
if(!$server_id)
$server_id=0;

//建立查詢
$ldap_query = "cn=$common";

//連接到ldap
$connect_id = ldap_connect($ldap_server[$server_id]);

if($connect_id)
{
//認(rèn)證
$bind_id = ldap_bind($connect_id);

//執(zhí)行搜索
$search_id = ldap_search($connect_id, $ldap_root_dn[$server_id], $ldap_query);

//將結(jié)果集合分配給一個(gè)數(shù)組
$result_array = ldap_get_entries($connect_id, $search_id);
}
else
{
//顯示連接錯(cuò)誤
echo "could not connect to ldap server: $ldap_server[$server_id]";
}

//如果搜索成功,將結(jié)果排序
if($result_array)
{
for($i=0; $i {
$format_array[$i][0] = strtolower($result_array[$i]["cn"][0]);
$format_array[$i][1] = $result_array[$i]["dn"];
$format_array[$i][2] = strtolower($result_array[$i]["givenname"][0]);
$format_array[$i][3] = strtolower($result_array[$i]["sn"][0]);
$format_array[$i][4] = strtolower($result_array[$i]["mail"][0]);
}

//排序數(shù)組
sort($format_array, "sort_string");

for($i=0; $i {
$cn = $format_array[$i][0];
$dn = $format_array[$i][1];
$fname = ucwords($format_array[$i][2]);
$lname = ucwords($format_array[$i][3]);
$email = $format_array[$i][4];

if($dn && $fname && $lname && $email)
{
$result_list .= "<a href='/"ldap://$ldap_server[$server_id]/$dn/"'>$fname $lname</a>";
$result_list .= " <
}
elseif($dn && $cn && $email)
{
$result_list .= "<a href='/"ldap://$ldap_server[$server_id]/$dn/"'>$cn</a>";
$result_list .= " <<a href='/"mailto:$email/"'>$email</a>
/n";
}
}
}
else
{
echo "result set empty for query: $ldap_query";
}

//關(guān)閉連接
ldap_close($connect_id);

//定制表格
echo " <center><form action='/"$php_self/"' method='/"get/"'>";
echo "search in:<select name='/"server_id/"'>"; //循環(huán)以建立select選項(xiàng) for($i=0; $i echo "<o(jì)ption selected value='/"$i/"'>".$ldap_name[$i]."</option>"; echo "</select>
";
echo "search for:<input name='/"common/"' type='/"text/"'>";
echo "<input name='/"lookup/"' type='/"submit/"' value='/"go/"'>
";
echo "(you can use * for wildcard searches, ex. * stanley will find all stanleys)
";
echo "</form></center>";

//顯示結(jié)果
if($result_list)
{
echo " <center><table border='/"1/"' cellpadding='/"10/"' cellspacing='/"0/"'
bgcolor=/"#ffffea/" width=/"450/"> <tbody><tr><td>$result_list</td></tr>
</tbody></table></center>";
}
else
echo "no results";
}

?>


發(fā)表評(píng)論 共有條評(píng)論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 汾阳市| 吴桥县| 涟源市| 介休市| 普定县| 满洲里市| 深圳市| 息烽县| 宁强县| 葵青区| 江孜县| 尤溪县| 囊谦县| 醴陵市| 高清| 益阳市| 桃园市| 义乌市| 垫江县| 灵寿县| 嘉善县| 罗山县| 泰安市| 江油市| 子长县| 桃园县| 上栗县| 松原市| 原阳县| 常宁市| 聂拉木县| 南昌县| 金坛市| 栖霞市| 新沂市| 通榆县| 临清市| 唐河县| 连江县| 本溪市| 壶关县|