<?xml version="1.0" encoding="UTF-8" ?>
<rss version="2.0">
<channel>
<title><![CDATA[向东博客 专注WEB应用 构架之美 --- 构架之美，在于尽态极妍 | 应用之美，在于药到病除]]></title> 
<link>http://www.jackxiang.com/index.php</link> 
<description><![CDATA[赢在IT，Playin' with IT,Focus on Killer Application,Marketing Meets Technology.]]></description> 
<language>zh-cn</language> 
<copyright><![CDATA[向东博客 专注WEB应用 构架之美 --- 构架之美，在于尽态极妍 | 应用之美，在于药到病除]]></copyright>
<item>
<link>http://www.jackxiang.com/post//</link>
<title><![CDATA[[ldap学习]使用PHP连接LDAP服务器]]></title> 
<author>jack &lt;xdy108@126.com&gt;</author>
<category><![CDATA[WEB2.0]]></category>
<pubDate>Fri, 10 Aug 2007 05:45:46 +0000</pubDate> 
<guid>http://www.jackxiang.com/post//</guid> 
<description>
<![CDATA[ 
	 &nbsp; &nbsp; &nbsp;本文将演示如何使用php连接一个ldap服务器。具体的例子是连接到一个公共的ldap服务器并且进行搜索。这个例子模拟的是netscape communicator 4.*，通过自己的地址本连接到ldap资源。<br/>ldap介绍<br/><br/>　　可能不少人已经听说过ldap，但是却不了解它具体是什么东东和如何工作。在这里我将不会很详细地介绍ldap，只是对该协议做一个简介。<br/><br/>　　ldap是一个用来发布目录信息到许多不同资源的协议。通常它都作为一个集中的地址本使用，不过根据组织者的需要，它可以做得更加强大。<br/><br/>　　ldap最基本的形式是一个连接数据库的标准方式。该数据库为读查询作了优化。因此它可以很快地得到查询结果，不过在其它方面，例如更新，就慢得多。要特别注意的是，ldap通常作为一个hierarchal数据库使用，而不是一个关系数据库。因此，它的结构用树来表示比用表格好。正因为这样，就不能用 sql语句了。<br/><br/>　　简单说来，ldap是一个得到关于人或者资源的集中、静态数据的快速方式。<br/><br/>要求<br/><br/>　　 phpv.4（以前的版本也可以，不过没有经过测试），编译支持ladp，即使用编译时带--with-ldap公共的ldap目录。在例子中提供了两个。<br/><br/>例子概览<br/><br/>1.设置公共ldap服务器的信息<br/>2.创建一个ldap查询<br/>3.连接到ldap服务器<br/>4.如果连接成功，处理查询<br/>5.格式化输出<br/>6.关闭连接<br/>7.设计搜索界面的html表格<br/>8.显示结果<br/><br/>设置公共ldap服务器的信息<br/><br/>　　我们要做的第一件事情是定义所有欲搜索的ldap服务器的信息<br/><br/>"ldap_name" = 新的ldap项目的名字<br/>"ldap_server" = 新的ldap项目的ip地址或者主机名<br/>"ldap_root_dn" = 新的ldap项目的根的辨识名<br/><br/>＜？php<br/><br/>$ldap_name[0] = "netscape net center";<br/>$ldap_server[0] = "memberdir.netscape.com";<br/>$ldap_root_dn[0] = "ou=member_directory,o=netcenter.com";<br/><br/>$ldap_name[1] = "bigfoot";<br/>$ldap_server[1] = "ldap.bigfoot.com";<br/>$ldap_root_dn[1] = "";<br/><br/> <br/><br/>//如果没有选择服务器的话将它设置为0<br/>if(!$server_id)<br/>$server_id=0;<br/><br/>？＞<br/><br/>建立ldap查询<br/><br/>　　前面已经提到，ldap查询与sql查询是不一样的。因此，语句要受到一定的限制，以下是一个基本的例子。<br/><br/>//create query $ldap_query = "cn=$common";<br/><br/>　　在我们的例子中，“cn”是我们要进行搜索的属性，而$common是由搜索的form中得到的字符串变量。ldap的查询语句语句可使用通配符‘*’。例如‘$stanley’将可以找出‘dan stanley’。<br/><br/>连接到ldap服务器<br/><br/>　　以下的函数连接到一个ldap资源，并且将连接的识别号赋给一个变量，就好象连接到一个通常的数据库一样，例如mysql。<br/><br/>＜？php<br/><br/>//连接到ldap<br/>$connect_id = ldap_connect($ldap_server[$server_id]);<br/><br/>？＞<br/><br/>　　在我们的例子中，“$connect_id”是连接的识别号，$ldap_server是可能的ldap服务器数组，而$server_id是由搜索表格得到的ldap服务器变量。<br/><br/>如果连接成功，处理查询<br/><br/>　　 如果连接成功的话，我们将得到一个有效的ldap连接识别号，这样我们就可以处理查询。<br/><br/>＜？php<br/><br/>if($connect_id)<br/>&#123;<br/>//认证<br/>$bind_id = ldap_bind($connect_id);<br/><br/>//执行搜索<br/>$search_id = ldap_search($connect_id, $ldap_root_dn[$server_id], $ldap_query);<br/><br/>//将结果集合分配给一个数组<br/>$result_array = ldap_get_entries($connect_id, $search_id);<br/>&#125;<br/>else<br/>&#123;<br/>//显示连接错误<br/>echo "could not connect to ldap server: $ldap_server[$server_id]";<br/>&#125;<br/><br/>？＞<br/><br/>　　一旦我们与ldap服务器建立好连接，我们就必须进行认证。php在连接大多数的数据库时，都是通过发送用户名和密码来进行的。不过，在ldap中，认证是未知的，直到进行一个bind操作。在我们的例子中，“$bind_id”是绑定连接的标识符。我们是通过匿名绑定到公共的ldap服务器的。因此，在执行ldap_bind()时，只使用连接识别号就可以了，无需其它的参数。<br/><br/>　　在经过认证后（这里是匿名的），我们就可以使用ldap_search()函数来执行查询，产生的$search_id是我们搜索的连接识别符。<br/><br/>　　然后，我们使用ldap_get_entries()函数将结果集赋给$result_array变量。这样我们能够以逻辑的方式排列信息，以便显示。<br/>格式化输出<br/><br/>　　在执行完ldap搜索后，返回的数据是以查找的顺序排列的。不过我们在排序时没有sql这样方便，使用order by语句就可以了。通常多数公共的ldap目录都没有标准的大小规范。排序是基于字符的ascii值，我们必须将字符全部格式化为小写，以便按字母的顺序输出。<br/><br/>　　要特别注意的是，返回的ldap结果集是一个多维的数组。因此，我们脚本中的$result_array的结构如下：<br/><br/>$result_array[0]["cn"] [0] = "dannie stanley"<br/>["dn"] [0] = "uid=dannie,dc=spinweb.net"<br/>["givenname"][0] = "dannie"<br/>["sn"] [0] = "stanley"<br/>["mail"] [0] = "danspam@spinweb.net"<br/>$result_array[1]["cn"] [0] = "michael reynolds"<br/>["dn"] [0] = "uid=michael,dc=spinweb.net"<br/>["givenname"][0] = "michael"<br/>["sn"] [0] = "reynolds"<br/>["mail"] [0] = "michaelspam@spinweb.net"<br/><br/>　　数据以这种格式存放的原因是每个属性都可能有超过一个值（象树的结构）。例如，如果我的名字是‘dannie’，我还可以在ldap中增加一些属性，例如：<br/><br/>$result_array[0]["cn"] [0] = "dannie stanley"<br/>["dn"] [0] = "uid=dannie,dc=spinweb.net"<br/>["givenname"][0] = "dannie"<br/>["givenname"][0] = "dan"<br/>["sn"] [0] = "stanley"<br/>["mail"] [0] = "danspam@spinweb.net"<br/><br/>　　在我们的搜索中，我们只关心每个属性的首个值，因此除了dn只有一个值外，其它我们只使用每个属性中序号为0的值。以下就是属性和它们含义的简单列表：<br/><br/>"cn" = common name<br/>"dn" = distinguished name<br/>"givenname" = first name<br/>"sn" = last name<br/>"mail" = email地址<br/><br/>＜？php<br/><br/>//如果搜索成功，将结果排序<br/>if($result_array)<br/>&#123;<br/>for($i=0; $i &#123;<br/>$format_array[$i][0] = strtolower($result_array[$i]["cn"][0]);<br/>$format_array[$i][1] = $result_array[$i]["dn"];<br/>$format_array[$i][2] = strtolower($result_array[$i]["givenname"][0]);<br/>$format_array[$i][3] = strtolower($result_array[$i]["sn"][0]);<br/>$format_array[$i][4] = strtolower($result_array[$i]["mail"][0]);<br/>&#125;<br/><br/>//排序数组<br/>sort($format_array, "sort_string");<br/><br/>for($i=0; $i &#123;<br/>$cn = $format_array[$i][0];<br/>$dn = $format_array[$i][1];<br/>$fname = ucwords($format_array[$i][2]);<br/>$lname = ucwords($format_array[$i][3]);<br/>$email = $format_array[$i][4];<br/><br/>if($dn && $fname && $lname && $email)<br/>&#123;<br/>$result_list .= "$fname $lname";<br/>$result_list .= " <$email><br/>";<br/>&#125;<br/>elseif($dn && $cn && $email)<br/>&#123;<br/>$result_list .= "＜a href='/"ldap://$ldap_server[$server_id]/$dn/"'＞$cn＜/a＞";<br/>$result_list .= " ＜a href='/"mailto:$email/"'＞$email＜/a＞<br/>";<br/>&#125;<br/>&#125;<br/>&#125;<br/>else<br/>&#123;<br/>echo "result set empty for query: $ldap_query";<br/>&#125;<br/><br/>？＞<br/>　　在我们的例子中，$format_array是我们建立的新数组，里面包括有查询的结果，并且被格式化用作输出。首先循环$result_array中的每个元素，并且将它分配给一个两维的数组用作排序。同时我们使用strtolower()函数将所有的值变为小写。<br/><br/>　　接着，我们使用php自带的一个称为sort()的函数进行排序。首个参数是要排序的数组，另一个是要执行的排序类型，该类型是由php的文档定义的。由于我们根据字符串排序，我们使用“sort_string”。<br/><br/>　　第三，我们循环已经格式化好的数组，并且将它分配给一个名字为$result_list的输出字符，该字符包含了html描述。要特别注意的是，在超链接中，我使用的是ldap的url格式。这个格式的例子类似：href="ldap://ldap.domain.net/uid=dannie,dc= domain.net"。<br/><br/>关闭连接<br/><br/>　　现在我们所有的数据已经包含在$result_list中了，我们可以安全地关闭ldap的连接。<br/><br/>＜？php<br/><br/>//关闭连接<br/>ldap_close($connect_id);<br/><br/>定制搜索界面的html表格<br/><br/>　　最后，我们要定制搜索用的html表格，它是用来给用户执行搜索的。<br/><br/>//定制表格<br/>echo " ＜center＞＜form action='"$php_self"' method='"get"'＞";<br/>echo "search in:＜select name='"server_id"'＞"; //循环以建立select选项 for($i=0; $i＜count($ldap_name); ＜br $i++)＞ echo "＜option selected value='"$i"'＞".$ldap_name[$i]."＜/option＞"; echo "＜/select＞<br/>";<br/>echo "search for:＜input name='"common"' type='"text"'＞";<br/>echo "＜input name='"lookup"' type='"submit"' value='"go"'＞<br/>";<br/>echo "(you can use * for wildcard searches, ex. * stanley will find all stanleys)<br/>";<br/>echo "＜/form＞＜/center＞";<br/><br/>？＞<br/><br/>　　代码中的$php_self是一个全局的常量，代表的是脚本页面自身，其中的循环是用来通过我们的$ldap_name变量创建select选项。<br/><br/>显示结果<br/><br/>　　现在所有的工作已经完成了，我们将打印出结果集。如果没有符合的结果，将会显示"no results"的信息。<br/><br/><<？>php<br/><br/>//显示结果<br/>if($result_list)<br/>&#123;<br/>echo " ＜center＞＜table border='"1"' cellpadding='"10"' cellspacing='"0"'<br/>bgcolor="#ffffea" width="450"＞ ＜tbody＞＜tr＞＜td＞$result_list＜/td＞＜/tr＞<br/>＜/tbody＞＜/table＞＜/center＞";<br/>&#125;<br/>else<br/>echo "no results";<br/><br/>？＞<br/><br/>源代码<br/><br/>　　以下是完整的源代码，只要将它剪切并粘贴到一个html文档，就可以尝试一下了。<br/><br/>＜？php<br/><br/>$ldap_name[0] = "netscape net center";<br/>$ldap_server[0] = "memberdir.netscape.com";<br/>$ldap_root_dn[0] = "ou=member_directory,o=netcenter.com";<br/><br/>$ldap_name[1] = "bigfoot";<br/>$ldap_server[1] = "ldap.bigfoot.com";<br/>$ldap_root_dn[1] = "";<br/><br/>//如果没有选择服务器的话将它设置为0<br/>if(!$server_id)<br/>$server_id=0;<br/><br/>//建立查询<br/>$ldap_query = "cn=$common";<br/><br/>//连接到ldap<br/>$connect_id = ldap_connect($ldap_server[$server_id]);<br/><br/>if($connect_id)<br/>&#123;<br/>//认证<br/>$bind_id = ldap_bind($connect_id);<br/><br/>//执行搜索<br/>$search_id = ldap_search($connect_id, $ldap_root_dn[$server_id], $ldap_query);<br/><br/>//将结果集合分配给一个数组<br/>$result_array = ldap_get_entries($connect_id, $search_id);<br/>&#125;<br/>else<br/>&#123;<br/>//显示连接错误<br/>echo "could not connect to ldap server: $ldap_server[$server_id]";<br/>&#125;<br/><br/>//如果搜索成功，将结果排序<br/>if($result_array)<br/>&#123;<br/>for($i=0; $i &#123;<br/>$format_array[$i][0] = strtolower($result_array[$i]["cn"][0]);<br/>$format_array[$i][1] = $result_array[$i]["dn"];<br/>$format_array[$i][2] = strtolower($result_array[$i]["givenname"][0]);<br/>$format_array[$i][3] = strtolower($result_array[$i]["sn"][0]);<br/>$format_array[$i][4] = strtolower($result_array[$i]["mail"][0]);<br/>&#125;<br/><br/>//排序数组<br/>sort($format_array, "sort_string");<br/><br/>for($i=0; $i &#123;<br/>$cn = $format_array[$i][0];<br/>$dn = $format_array[$i][1];<br/>$fname = ucwords($format_array[$i][2]);<br/>$lname = ucwords($format_array[$i][3]);<br/>$email = $format_array[$i][4];<br/><br/>if($dn && $fname && $lname && $email)<br/>&#123;<br/>$result_list .= "＜a href='/"ldap://$ldap_server[$server_id]/$dn/"'＞$fname $lname＜/a＞";<br/>$result_list .= " <$email><br/>";<br/>&#125;<br/>elseif($dn && $cn && $email)<br/>&#123;<br/>$result_list .= "＜a href='/"ldap://$ldap_server[$server_id]/$dn/"'＞$cn＜/a＞";<br/>$result_list .= " <＜a href='/"mailto:$email/"'＞$email＜/a＞<br/>";<br/>&#125;<br/>&#125;<br/>&#125;<br/>else<br/>&#123;<br/>echo "result set empty for query: $ldap_query";<br/>&#125;<br/><br/>//关闭连接<br/>ldap_close($connect_id);<br/><br/>//定制表格<br/>echo " ＜center＞＜form action='"$php_self"' method='"get"'＞";<br/>echo "search in:＜select name='"server_id"'＞"; //循环以建立select选项 for($i=0; $i echo "＜option selected value='"$i"'＞".$ldap_name[$i]."＜/option＞"; echo "＜/select＞<br/>";<br/>echo "search for:＜input name='"common"' type='"text"'＞";<br/>echo "＜input name='"lookup"' type='"submit"' value='"go"'＞<br/>";<br/>echo "(you can use * for wildcard searches, ex. * stanley will find all stanleys)<br/>";<br/>echo "＜/form＞＜/center＞";<br/><br/>//显示结果<br/>if($result_list)<br/>&#123;<br/>echo " ＜center＞＜table border='"1"' cellpadding='"10"' cellspacing='"0"'<br/>bgcolor="#ffffea" width="450"＞ ＜tbody＞＜tr＞＜td＞$result_list＜/td＞＜/tr＞<br/>＜/tbody＞＜/table＞＜/center＞";<br/>&#125;<br/>else<br/>echo "no results";<br/>&#125;<br/><br/>？＞ 
]]>
</description>
</item><item>
<link>http://www.jackxiang.com/post//#blogcomment</link>
<title><![CDATA[[评论] [ldap学习]使用PHP连接LDAP服务器]]></title> 
<author> &lt;user@domain.com&gt;</author>
<category><![CDATA[评论]]></category>
<pubDate>Thu, 01 Jan 1970 00:00:00 +0000</pubDate> 
<guid>http://www.jackxiang.com/post//#blogcomment</guid> 
<description>
<![CDATA[ 
	
]]>
</description>
</item>
</channel>
</rss>