php的LDAP扩展为php操作ldap提供了大量便捷的函数,通过调用这些函数,可以方便地使用php编程来进行LDAP的管理操作。
1、PHP配置LDAP扩展
PHP默认并没有启用LDAP扩展,为了启用LDAP扩展模块,对于Linux的操作系统,可以使用远程包管理工具安装php-ldap的相关rpm包,如果需要编译安装PHP,那就需要在编译之初使用参数—with-ldap来编译LDAP模块,同时,在php.ini中需要去掉启用ldap扩展配置前的注释才能使设置生效。对于windows系统,同样要在php.ini中启用php_ldap.dll扩展,才能确保模块真正生效。具体配置的方法这里不再详述。
配置成功以后,通过phpinfo函数打印的PHP模块信息中就能看到LDAP模块的信息,如图。
PHP官方提供的说明手册中对该模块提供的函数有详细的说明,具体参考http://php.net/manual/zh/book.ldap.php,现就项目中具体用到函数进行粗略总结,如果需要了解更为详细的说明,强烈推荐通过阅读php的官方手册来获取。
2、PHP连接LDAP服务器
与PHP和关系型数据库建立连接的过程类似,PHP连接LDAP服务器通常也是经过连接、认证(绑定管理员)、操作、关闭的过程。
PHP与LDAP建立连接主要用到的函数有:
(1)、ldap_connect( $hostname, $port )
:与指定的LDAP主机建立连接
$hostname
:表示主机名(IP);$port
:表示连接的端口号,由于LDAP默认使用的端口号是389,因此,如果省略此参数,表示默认连接指定服务器的389端口;
$host="ldap.messikiller.cn";
$port="389";
$link=ldap_connect( $hostname, $port ) or die( "Can’t connect to ldap server!" );
(2)、ldap_get_option( $link, $option )
:获取已经建立连接的配置信息;
ldap_set_option( $link, $option, $value )
:为建立的连接配置相关信息
$link
:之前已经与LDAP建立的连接资源;$option
:LDAP配置项名称,具体的配置项可以参考PHP官方说明,这里主要说明一下LDAP_OPT_PROTOCOL_VERSION
选项,这个选项主要是指定了连接中LDAP的版本,LDAP当前存在LDAPv2和LDAPv3两种版本,PHP默认的连接版本是LDAPv2,如果需要指定建立LDAPv3的连接,则需要使用函数ldap_set_option
进行配置;
注意:由于一些PHP操作LDAP高级函数只能使用在LDAPv3中,因此一定要指定连接版本为LDAPv3才能使用这些高级函数
$value
:配置项的取值,可以是布尔值或者整数。
ldap_set_option( $link, LDAP_OPT_PROTOCOL_VERSION, 3 ); //指定LDAP连接版本为LDAPv3
(3)、ldap_bind( $link, $manager, $password )
:为建立的连接绑定管理员账号
$link
:之前已经与LDAP建立的连接资源;$manager
:管理员dn名称;$password
:管理员认证密码;
$manager="cn=manager,dc=messikiller,dc=cn";
$password="123456";
ldap_bind( $manager, $password ) or die( "Can’t bind manager to connection!" );
(3)、ldap_unbind( $link )
/ ldap_close( $link )
:关闭已经建立的LDAP连接,ldap_unbin()
与ldap_close()
在操作上没有区别,相互为别名关系。
ldap_close( $link ); //关闭LDAP连接
3、PHP获取LDAP数据
PHP与LDAP建立的可用的连接之后,就可以在连接的基础上进行查询操作来获取LDAP数据库中的信息。
(1)、ldap_search( $link, $base_dn, $filter )
:指定的过滤条件下,搜索base_dn及其子树的全部记录,并返回搜索结果为结果集。
$link
:之前已经建立的LDAP连接资源;$base_dn
:要搜索的的根dn名称,通常是整个LDAP域的根dn,如"dc=messikiller,dc=cn";$filter
:搜索的过滤条件,支持"*"通配符,具体的用法可以参考PHP官方手册。
//搜索dc=messikiller,dc=cn及其子树中givenName值以messi开头的条目
$results=ldap_search( $link, "dc=messikiller,dc=cn", "givenName=messi*" );
(2)、ldap_get_entries( $link, $result )
:读取搜索后获得的结果集中具体的记录,并返回结果到一个多维数组中。
$link
:建立的LDAP连接;$result
:通过搜索获取到的结果集;
ldap_get_entries()
函数返回的多维数组中存放了具体的条目信息,下面列出了多维数组中存放的具体信息:
array["count"]
:结果集中获取到的记录条数;array[n]["dn"]
:结果集中第n+1项的dn值;array[n]["count"]
:结果集中第n+1项的全部属性总数;array[n]["attr"]["count"]
:结果集中第n+1项记录中"attr"属性所有取值的个数;array[n]["attr"][m]
:结果集中第n+1项记录中"attr"属性的第m+1个值;array[n][m]
:第n+1项中第m+1个位置的属性。
//获取搜索结果到数组
$entries=ldap_get_entries( $link, $results );
//确定搜索到的记录数目
$count=$entries["count"];
//循环输出所有搜索到的记录的givenname属性
for( $i=0; $i < $count; $i++ )
{
echo "givenName:".$entries[$i]["givenName"][0]."<br />";
}
//关闭连接
ldap_close( $link );
(3)、ldap_read( $link, $base_dn, $filter )
:通过过滤条件只搜索一个特定的记录项base_dn
,并返回结果为结果集。
$link
:已经建立的连接资源;$base_dn
:要搜索的dn名称;$filter
:本次搜索的过滤条件。
注意:与ldap_search()
不同,ldap_read()
函数只能搜索并读取一条特定的记录,并不去遍历并搜索base_dn
的子树。
//获取搜索结果到数组
$entries=ldap_get_entries( $link, $results );
//确定搜索到的记录数目
$count=$entries["count"];
//输出搜索到的记录的givenname属性
echo "givenName:".$entries[0]["givenName"][0]."<br />"
//关闭连接
ldap_close( $link );
(4)、ldap_count_entries( $link, $result )
:直接获取结果集中的全部记录总数,效果与ldap_get_entries()
函数返回的$entries["count"]
一样,举例略。
4、PHP操作LDAP数据(增加、删除、修改)
(1)、ldap_add( $link, $dn, $entry )
:向ldap中添加具有$entry
指定属性的新dn。添加成功返回true,否则返回false。
$link
:已经建立的连接;$dn
:要新增的dn名称;$entry
:新dn具有的属性名称和具体的值,该变量为数组形式。
//新dn名称
$new_dn="uid=people,dc=messikiller,dc=cn";
//指定新dn的属性
$entry=array( "cn"=>"people", "mail"=>"messikiller@aliyun.com" );
//添加dn到LDAP
ldap_add( $link, $new_dn, $entry ) or die( "Can’t add new dn!" );
//关闭ldap连接
ldap_close( $link );
(2)、ldap_mod_replace( $link, $dn, $entry )
/ ldap_modify( $link, $dn, $entry )
:修改已经存在的dn项的特定属性的值,要修改的属性和修改后的值由数组$entry指定。修改成功返回true,否则返回false。ldap_mod_replace()
与ldap_modify()
互为别名关系。
$link
:已经建立的连接;$dn
:要修改的具体dn名称;$entry
:修改的属性的修改后的值,该变量为数组形式。
//要修改的dn
$dn="uid=people,dc=messikiller,dc=cn";
//要修改的属性和修改后的属性值
$entry=array( "cn"=>"new_people", "mail"=>"messikiller@163.com" );
//修改属性,否则报错
ldap_mod_replace( $link, $dn, $entry ) or die ("Can’t modify attrs!");
(3)、ldap_mod_add( $link, $dn, $entry )
:向指定的dn添加新的属性,新的属性名和属性值由数组$entry
指定。
$dn="uid=people,dc=messikiller,dc=cn";
$entry=array( "dispalyName"=>"person", "age"=>"25" );
ldap_mod_add( $link, $dn, $entry ) or die ("Can’t add attrs!");
(4)、ldap_rename( $link, $dn, $new_rdn, $new_parent, $is_delete_old_rdn )
:复制指定的dn,并修改指定dn的rdn名称。
$link
:已经建立的连接;
$dn
:要进行复制和重命名的dn名称;
$new_rdn
:重命名后的新rdn名称;
$new_parent
:复制后新dn的父节点dn;
$is_delete_old_rdn
:复制后是否删除旧dn,该变量为布尔值。
注意:ldap_rename()
函数只能在LDAPv3版本下执行,因此$link
必须指定为LDAPv3版本。由于该函数在今后ldap结构迁移的项目中还会多次用到,这里不再举例。
(5)、ldap_mod_del( $link, $dn, $entry )
:删除指定dn中的指定的属性,要删除的属性由数组$entry
指定。
$link
:已经建立的连接;
$dn
:指定的dn;
$entry
:定义要删除的具体属性,该变量为数组。
//要删除属性的dn
$dn="uid=people,dc=messikiller,dc=cn";
//要删除的属性名称
$entry=array( "dispalyName", "age" );
//删除指定的属性,负责报错
ldap_mod_del( $link, $dn, $entry ) or die ("Can’t delete attrs!");
(6)、ldap_delete( $link, $dn )
:删除指定的dn实体。
//要删除的dn
$dn="uid=people,dc=messikiller,dc=cn";
//删除dn,否则报错
ldap_delete ( $link, $dn ) or die ("Can’t delete the dn!");
使用以上介绍的函数,基本可以实现通过PHP脚本来完成LDAP的增删改查,二次封装成具体需要的函数后,就能使用PHP完成一些较为复杂的LDAP操作,今后PHP脚本的编写基本都是建立在这些函数的基础之上。