LDAP 的全稱是「輕量級目錄訪問協議(Lightweight Directory Access Protocol)」,是一種簡單的目錄協議。所謂目錄,是一種專門的數據庫,能夠用來服務於任何應用程序。在企業應用中使用 LDAP可讓企業範圍內的全部應用程序LDAP 目錄中獲取信息,應用程序能夠從網絡上直接從 LDAP 目錄獲取信息,而不侷限於操做系統與服務器的類型。這裏主要介紹如何使用 PHP 來訪問 LDAP。 php
LDAP目錄中的信息是是按照樹型結構組織,具體信息存儲在條目(entry)的數據結構中。條目至關於關係數據庫中表的記錄;條目是具備區別名DN (Distinguished Name)的屬性(Attribute),DN是用來引用條目的,DN至關於關係數據庫表中的關鍵字(Primary Key)。
數據庫
LDAP簡稱對應 數組
1.o-organization 服務器
2.ou-organization unit 網絡
3.c- countryName 數據結構
4.dc-domainComponent dom
5.sn-suer name 函數
6.cn-common name ui
PHP中用於鏈接LDAP服務器的函數時ldap_connect,其語法格式以下所示。 spa
ldap_connect([string hostname [, int port]])其中,hostname是LDAP服務器所在的主機地址,port是LDAP服務器的端口號。如下代碼實現了對位於192.168.3.1地址的服務器鏈接。
<?PHP $ldap_host = "ldap:192.168.3.1";//LDAP服務器地址 $ldap_port = "389"; $ldap_conn = ldap_connect($ldap_host,$ldap_port) or die ("Can't connect to LDAP server");//創建與LDAP服務器鏈接 ?>
綁定 LDAP 服務器的含義是使用特定的用戶名或密碼來登錄 LDAP 服務器。PHP 中用於綁定 LDAP服務器的函數是 ldap_bind,其語法格式以下所示。
ldap_bind(ldap_conn[,string username [, string password]])其中ldap_conn是前面鏈接LDAP服務器時建立的鏈接對象,username是登錄LDAP服務器時使用的用戶名,password是登錄時所用的密碼。如下代碼實現了對位於198.168.3.1地址的LDAP服務器的綁定。
<?php $ldap_host = "ldap:192.168.3.1";//LDAP服務器 $ldap_port = "386";//LDAP服務器端口號 $ldap_user = "";//設定服務器用戶名 $ldap_pwd = "";//設定服務器密碼 $ldap_conn = ladp_connect($ldap_host,$ladp_port) or die("Can't connect to the LDA server."); $ldap_bind($ldap_conn,$ldap_user,$ldap_pwd) or die("Can't bind to LDAP server."); ?>斷開LDAP服務器
與LDAP服務器斷開的過程與綁定LDAP服務器相反,PHP中用於綁定LDAP服務器的函數時ldap_unbind,其語法格式以下
ldap_unbind(ldap_conn)
其中,ldap_conn 是前面鏈接 LDAP 服務器時建立的鏈接對象。如下代碼在綁定了對位於 192.168.3.1地址的 LDAP 服務器後與其斷開鏈接。
<?PHP $ldap_host = "ldap://192.168.3.1"; $ldap_user = ""; $ldap_pwd = "";//設定服務器密碼 $ldap_conn = ldap_connect($ldap_host, $ldap_port) or die("Can't connect to LDAP server"); ldap_bind($ldap_conn, $ldap_user, $ldap_pwd) or die("Can't bind to LDAP server."); ldap_unbind($ldap_conn) or die("Can't unbind from LDAP server."); ?>
查詢LDAP目錄使用ldap_search函數來實現,其語法格式以下所示。
ldap_search(ldap_conn,base_dn,conditions)其中,ldap_conn是前面鏈接LDAP服務器時建立的鏈接對象。base_dn是LDAP服務器的查詢主鍵。conditions是用於LDAP目錄查詢所用的條件。該函數返回一個結果對象,該結果對象保存查詢到的全部記錄。對於這個結果對象,可使用ldap_get_entries函數進行簡單的讀取,其語法格式以下所示。
ldap_get_entries(ldap_conn,result)其中,ldap_conn 是前面鏈接 LDAP 服務器時建立的鏈接對象,result 是前面查詢 LDAP 目錄時返回的對象。該函數返回一個數組,包含全部的結果記錄。如下代碼實現了對服務器上的內容進行查詢。
<?php $ldap_host = "ldap://192.168.3.1";//LDAP 服務器地址 $ldap_port = "389";//LDAP 服務器端口號 $ldap_user = "";//設定服務器用戶名 $ldap_pwd = "";//設定服務器密碼 $ldap_conn = ldap_connect($ldap_host, $ldap_port) or die("Can't connect to LDAP server");//創建與 LDAP 服務器的鏈接 ldap_bind($ldap_conn, $ldap_user, $ldap_pwd) or die("Can't bind to LDAP server.");//與服務器綁定 $base_dn = "ou=company,o=depart";//定義要進行查詢的目錄主鍵 $filter_col = "mail";//定義用於查詢的列 $filter_val = "phptester@163.com";//定義用於匹配的值 $result= ldap_search($ldap_conn, $base_dn, "($filter_col=$filter_val)"); $entry= ldap_get_entries($ldap_conn, $result);//得到查詢結果 print_r($entry); ldap_unbind($ldap_conn) or die("Can't unbind from LDAP server."); //與服務器斷開鏈接 ?>
運行結果以下所示。
Array ( [count] => 1 [0] => Array ( [objectclass] => Array ( [count] => 5 [0] => person [1] => organizationalPerson [2] => companyPerson [3] => departPerson [4] => top ) [0] => objectclass [ou] => Array ( [count] => 1 [0] => company ) [1] => ou [o] => Array ( [count] => 1 [0] => depart ) [2] => o [employeeserialnumber] => Array ( [count] => 1 [0] => 100001 ) [3] => employeeserialnumber [givenname] => Array ( [count] => 2 [0] => Peng Cheng [1] => Peng ) [4] => givenname [mail] => Array ( [count] => 1 [0] => phptester@163.com ) [5] => mail [count] => 6 [dn] => uid=672100001,c=cn,ou=company,o=depart ) )能夠看出,訪問LDAP服務器與查詢數據庫中的記錄很類似。事實上,在實際應用中,LDAP服務器也與數據庫服務器有着類似的做用。除了上面的用法外,ldap_search函數還支持通配符使用。例如,將前面的用於LDAP服務器查詢的代碼修改以下。
<?php $filter_val = "*@163.com";//定義用於匹配的值 $result= ldap_search($ldap_conn, $base_dn, "($filter_col=$filter_val)");//執行查詢 ?>這裏就會將全部包含以「@163.com」結尾的郵件地址的記錄返回。
上面的例子完整的得到了LDAP服務器查詢結果的信息,這樣,根據數組中的值就能夠進行其餘操做了。除此以外,PHP還提供了專門用於得到查詢結果值的方法。首先介紹一種與ldap_get_entries類似的函數--ldap_first_entry,函數僅得到結果對象中的第一條記錄,其語法格式以下。
ldap_first_entry(ldap_conn, result)其中,ldap_conn 是前面鏈接 LDAP 服務器時建立的鏈接對象,result 是前面查詢 LDAP 目錄時返回的對象。獲取結果中的值的函數爲 ldap_get_values,該函數的語法格式以下所示。
ldap_get_values(ldap_conn, entry, column)其中,ldap_conn 是前面鏈接 LDAP 服務器時建立的鏈接對象,entry 是前面查詢查詢結果時返回的對象,column 是要返回的值所在的列的名稱。該函數返回一個僅包含該列信息的數組。如下代碼返回了前面數組的 givenname 列。
<?php $ldap_host = "ldap://192.168.3.1"; //LDAP 服務器地址 $ldap_port = "389"; //LDAP 服務器端口號 $ldap_user = ""; //設定服務器用戶名 $ldap_pwd = ""; //設定服務器密碼 $ldap_conn = ldap_connect($ldap_host, $ldap_port) or die("Can't connect to LDAP server");//創建與 LDAP 服務器的鏈接 ldap_bind($ldap_conn, $ldap_user, $ldap_pwd) or die("Can't bind to LDAP server.");//與服務器綁定 $base_dn = "ou=company,o=depart";//定義要進行查詢的目錄 $filter_col = "mail";//定義用於查詢的列 $filter_val = "phptester@163.com";//定義用於匹配的值 $result= ldap_search($ldap_conn, $base_dn, "($filter_col=$filter_val)");//執行查詢 $entry = ldap_first_entry($ldap_conn, $result);//得到第一個查詢結果 $firstname = ldap_get_values($ldap_conn, $entry, "givenname");//得到查詢結果中的值 print_r($firstname);//輸出 ldap_unbind($ldap_conn) or die("Can't unbind from LDAP server.");//與服務器斷開鏈接 ?>運行結果以下所示。
Array ( [0] => Peng Cheng [1] => Peng [count] => 2 )
計算查詢結果中的記錄數ldap_count_entries函數來實現,該函數的語法格式以下所示、
ldap_count_entries(ldap_conn, result)其中,ldap_conn是前面鏈接LDAP服務器時建立的鏈接對象 ,result 是前面查詢 LDAP 目錄時返回的對象。如下代碼計算出了查詢結果中的記錄數。
<?php $ldap_host = "ldap://192.168.3.1";//LDAP 服務器地址 $ldap_port = "389";//LDAP 服務器端口號 $ldap_user = "";//設定服務器用戶名 $ldap_pwd = "";//設定服務器密碼 $ldap_conn = ldap_connect($ldap_host, $ldap_port) or die("Can't connect to LDAP server");//創建與 LDAP 服務器的鏈接 ldap_bind($ldap_conn, $ldap_user, $ldap_pwd) or die("Can't bind to LDAP server.");//與服務器綁定 $base_dn = "ou=company,o=depart";//定義要進行查詢的目錄 $filter_col = "mail";//定義用於查詢的列 $filter_val = "*@163.com";//定義用於匹配的值 $result = ldap_search($ldap_conn, $base_dn, "($filter_col=$filter_val)");//執行查詢 $count = ldap_count_entries($ldap_conn, $result);//計算查詢結果中的記錄數 echo "Total records count: ".$count;//輸出查詢結果中的記錄數 ldap_unbind($ldap_conn) or die("Can't unbind from LDAP server.");//與服務器斷開鏈接 ?>須要注意的是這裏使用了通配符進行 LDAP 數據庫的查詢,所以,可能會有多條記錄被返回。
向 LDAP 添加一條新記錄使用 ldap_add 函數來完成。
ldap_add(ldap_conn, base_dn, entry)
其中,ldap_conn 是前面鏈接 LDAP 服務器時建立的鏈接對象,base_dn 是 LDAP 服務器的查詢主鍵,entry 是儲存新記錄的數組。如下代碼實現了向 LDAP 服務器添加一條新記錄的功能。
<?php $ldap_host = "ldap://192.168.3.1";//LDAP 服務器地址 $ldap_port = "389";//LDAP 服務器端口號 $ldap_user = "";//設定服務器用戶名 $ldap_pwd = "";//設定服務器密碼 $ldap_conn = ldap_connect($ldap_host, $ldap_port) or die("Can't connect to LDAP server");//創建與 LDAP 服務器的鏈接 ldap_bind($ldap_conn, $ldap_user, $ldap_pwd) or die("Can't bind to LDAP server."); //與服務器綁定 $base_dn = "ou=company,o=depart"; //定義要進行查詢的目錄 $entry["givenname"] = "Simon"; //定義新記錄數組 $entry["company"] = "PHP workshop"; $entry["mail"] = "pch1982cn@cn.yahoo.com"; $entry["serial_no"] = "100001"; ldap_add($ldap_conn, $base_dn, $entry) or die("Can't add new entry!"); ldap_unbind($ldap_conn) or die("Can't unbind from LDAP server."); //與服務器斷開鏈接 ?>
更新LDAP中的一條記錄
更新LDAP中的一條記錄使用ldap_modify函數來完成
ldap_modify(ldap_conn, base_dn, entry)
<?php $ldap_host = "ldap://192.168.3.1";//LDAP 服務器地址 $ldap_port = "389";//LDAP 服務器端口號 $ldap_user = "";//設定服務器用戶名 $ldap_pwd = "";//設定服務器密碼 $ldap_conn = ldap_connect($ldap_host, $ldap_port) or die("Can't connect to LDAP server"); //創建與 LDAP 服務器的鏈接 ldap_bind($ldap_conn, $ldap_user, $ldap_pwd) or die("Can't bind to LDAP server."); //與服務器綁定 $base_dn = "ou=company,o=depart"; //定義要進行查詢的目錄 $entry = array("company" => "PHP Workshop", "mail" => "pengcheng.sun@yahoo.com");//設定要修改的記錄屬性 ldap_modify($ldap_conn, $base_dn, $entry) or die("Can't modify entry."); //修改記錄 ldap_unbind($ldap_conn) or die("Can't unbind from LDAP server."); //與服務器斷開鏈接 ?>
刪除 LDAP 中的一條記錄使用 ldap_delete 函數來完成。
ldap_modify(ldap_conn, base_dn)
<?php $ldap_host = "ldap://192.168.3.1";//LDAP 服務器地址 $ldap_port = "389";//LDAP 服務器端口號 $ldap_user = "";//設定服務器用戶名 $ldap_pwd = "";//設定服務器密碼 $ldap_conn = ldap_connect($ldap_host, $ldap_port) or die("Can't connect to LDAP server"); //創建與 LDAP 服務器的鏈接 ldap_bind($ldap_conn, $ldap_user, $ldap_pwd) or die("Can't bind to LDAP server.");//與服務器綁定 $base_dn = "ou=company,o=depart"; //定義要進行查詢的目錄 ldap_delete($ldap_conn, $base_dn) or die("Can't delete entry."); //修改記錄 ldap_unbind($ldap_conn) or die("Can't unbind from LDAP server."); //與服務器斷開鏈接 ?>
PHP 還提供了對 LDAP 操做的錯誤處理的方法。主要包括 3 個函數——ldap_errno、ldap_error 和ldap_err2str。ldap_errno 的語法格式以下所示。int ldap_errno(resource)其中 resource 是在 LDAP 操做中產生的對象,該函數將返回一個錯誤代碼。ldap_error 的語法格式以下所示。
string ldap_error(resource)
string ldap_error(int errno)
<!--?php <br ?--> $ldap_host = "ldap://192.168.3.44";//LDAP 服務器地址 $ldap_port = "389";//LDAP 服務器端口號 $ldap_user = "";//設定服務器用戶名 $ldap_pwd = "";//設定服務器密碼 $ldap_conn = ldap_connect($ldap_host, $ldap_port);//創建與 LDAP 服務器的鏈接 @ldap_bind($ldap_conn, $ldap_user, $ldap_pwd);//與服務器綁定 echo "Error number: ".ldap_errno($ldap_conn)." ";//輸出錯誤代碼 echo "Error message: ".ldap_error($ldap_conn)." ";//輸出錯誤信息 echo ldap_err2str(ldap_errno($ldap_conn));//輸出錯誤信息 ?>
在實際應用中,可能會須要多個應用使用一個共同的用戶名和密碼來登錄。例如,一個企業使用多個系統來處理員工的平常操做,全部的系統均使用來自同一個LDAP目錄的用戶信息進行身份驗證。這樣,就不須要在每一個系統中保存不一樣的密碼,只須要在LDAP目錄中保存一個密碼便可。使用LDAP驗證用戶身份的原理與上一節中介紹的綁定LDAP服務器的方法相同。不一樣的驗證時的用戶名和密碼來自用戶的輸入。完整代碼以下
<?php if (!isset($_SERVER['PHP_AUTH_USER'])) { Header("WWW-Authenticate: Basic realm=\"login\""); Header("HTTP/1.0 401 Unauthorized"); } else { $ldap_host = "ldap://192.168.3.1"; $ldap_port = "389"; $ldap_user = $_SERVER['PHP_AUTH_USER']; $ldap_pwd = $_SERVER['PHP_AUTH_PW']; $ldap_conn = ldap_connect($ldap_host, $ldap_port) or die("Can't connect to LDAP server"); @ldap_bind($ldap_conn, $ldap_user, $ldap_pwd);if(ldap_errno($ldap_conn)!=0) { echo "Can't log in! ".ldap_error($ldap_conn)."<br>"; } else { echo "Welcome $ldap_user"; } } ?>