上下文:
我正在使用域名地址尝试检查与域控制器的连接,但并非所有域控制器都可以从运行PHP的服务器访问。因此,我使用一个循环来查看是否有域控制器使用fsockopen进行响应。
Domain.ad指向15个可能的域控制器。server.domain.ad、server2.domain.ad等
...
$i = 0;
do
{
$fp = fsockopen("domain.ad", 389, $errno, $errstr, 1);
$i++;
}
while(!$fp && $i < 15);
...
//$ip = $fp->getAddress(); or something like that.
问题:
是否有一种方法可以从成功连接的IP地址/域控制器的fsockopen连接中找出,以便稍后在代码中使用以完成LDAP绑定?或者有没有更好的方法可以在不使用1个域控制器的情况下做到这一点?
我不确定你想在那里实现什么。fsockopen
尝试在给定端口上打开与给定服务器的连接。您也在设置超时。但你是循环的。因此,您尝试连续打开连接15次,并在每次运行时将到服务器的超时时间增加1秒。但据我所知,有多个域控制器可用。根据网络设置的不同,第一个可用的应该做出反应并充当"您的"端点。作为该系统的用户,您不应该检查哪个可以访问,哪个不能访问。当你做ldap_connect('ldap://domain.ad:389);
的时候,你应该得到一个句柄。
或者,您可以通过gethostbyname('domain.ad')
对域控制器进行DNS查询,该查询将为您提供给定主机的IP地址。但正如我所说,当你的网络得到妥善维护时,就不应该有这样的必要。
当您有多个服务器名时,您可以在空格分隔的列表中使用它们作为ldap_connect
的参数,如下所示:
ldap_connect('ldap://domain.ad:389 ldap://domain2.ad:389 ldaps://domain.ad:123');
它应该连接到第一个可用的服务器。
尽管您必须注意一个问题:ldap_connect
不连接!连接通常首先在ldap_bind
上打开!因此,连接问题将不会出现在ldap_connect
上。如果您得到一个false
,这仅仅意味着所提供的参数不符合预期!这就是为什么我通常首先使用fsockopen
来检查服务器是否可用(如果这是一个问题),这样我就可以快速失败。
我的域控制器迭代解决方案。
$ipDomain = dns_get_record("domain.ad", DNS_A);
$i = 0;
do
{
$fp = fsockopen($ipDomain[$i]['ip'], 389, $errno, $errstr, 1);
if(!$fp)
{
$i++;
if($i >= sizeof($ipDomain))
{
break;
//die();
}
}
}
while(!$fp);
...
ldap_connect($ipDomain[$i]['ip']);
...