PHP-从ldap_connect()捕获超时异常

PHP-从ldap_connect()捕获超时异常,php,timeout,ldap,ldapconnection,Php,Timeout,Ldap,Ldapconnection,我用PHP编写了一个小的监视脚本,它应该监视一个虚拟目录及其活动目录。一切正常,但当虚拟目录服务冻结时,我的ldap_connect()无法连接,但也不会返回错误。所以我的整个剧本都停滞不前了。我认为ldap_connect函数会返回一个超时时间(比如当您尝试ping一个IP时,它无法访问) 这是我的connect命令: $connection = ldap_connect($hostname, $port) or die("Could not connect to {$hostname});

我用PHP编写了一个小的监视脚本,它应该监视一个虚拟目录及其活动目录。一切正常,但当虚拟目录服务冻结时,我的ldap_connect()无法连接,但也不会返回错误。所以我的整个剧本都停滞不前了。我认为ldap_connect函数会返回一个超时时间(比如当您尝试ping一个IP时,它无法访问)

这是我的connect命令:

$connection = ldap_connect($hostname, $port) or die("Could not connect to {$hostname});
我在ldap_connect()的手册中还没有找到关于timelimit参数的内容,在该参数中,可以定义函数在中止之前应该尝试连接多长时间

然而,我还是不能想出一个解决方案,比如
try
catch
或者类似的东西。我也不想使用
set\u time\u limit()
函数,因为我的脚本需要一直运行到最后

我感谢你的帮助:) 谢谢和问候 蒂姆

特别注意以下选项:-

LDAP_OPT_NETWORK_TIMEOUT
LDAP_OPT_TIMELIMIT

您需要使用支持超时的API。LDAP(协议)不以本机方式支持连接超时。
timelimit
是客户端请求的参数,它表示目录处理搜索请求的时间,与“连接超时”不同。


如果您不希望您的PHP程序在某个公司DC失败时等待XXX秒才放弃,请尝试在0中设置LDAP_OPT_引用,
由于
ldap\u connect()
没有在用户指定的时间超时的机制

这是我的变通方法,它显示了出色的实际效果

function serviceping($host, $port=389, $timeout=1)
{
   $op = fsockopen($host, $port, $errno, $errstr, $timeout);
   if (!$op) return 0; //DC is N/A
   else {
      fclose($op); //explicitly close open socket connection
      return 1; //DC is up & running, we can safely connect with ldap_connect
   }
}

// ##### STATIC DC LIST, if your DNS round robin is not setup
//$dclist = array('10.111.222.111', '10.111.222.100', '10.111.222.200');

// ##### DYNAMIC DC LIST, reverse DNS lookup sorted by round-robin result
$dclist = gethostbynamel('domain.name');

foreach ($dclist as $k => $dc) if (serviceping($dc) == true) break; else $dc = 0;
//after this loop, either there will be at least one DC which is available at present, or $dc would return bool false while the next line stops program from further execution

if (!$dc) exit("NO DOMAIN CONTROLLERS AVAILABLE AT PRESENT, PLEASE TRY AGAIN LATER!"); //user being notified


//now, ldap_connect would certainly connect succesfully to DC tested previously and no timeout will occur
$ldapconn = ldap_connect($dc) or die("DC N/A, PLEASE TRY AGAIN LATER.");
同样,通过这种方法,您可以获得一个非常好的故障转移功能

以一家公司为例,一打DC-a分布在遥远的地方


这样,如果当前至少有一个DC处于活动状态,您的PHP程序将始终具有高可用性。

但是当ldap_connect()在超时结束时是否也会引发异常?我在异常处理手册中没有看到任何内容,其中说明超时或类似事件会引发异常。所以我认为不会。我又调试了一点,发现我的ldap_bind()函数正在运行超时。我用ldap_set_option()尝试了你的想法(使用ldap_OPT_NETWORK_TIMEOUT和ldap_OPT_TIMELIMIT),但不知怎么的,它仍然超时。。。我甚至在bind通话前后都试过了。。。但也许我做错了什么,我没有发现这两个选项的任何示例…我认为设置超时只能在建立连接时设置,而在您的情况下,您总是无法连接,这会成为某种死锁,需要再次修改。我再次检查,连接已建立(使用ldap_connect),我发现,由于我的php版本,LDAP_OPT_NETWORK_TIMEOUT选项无法工作。。。我必须检查我是否可以更新它。。。但是非常感谢您的帮助:)我做了更新,并使用选项NETWORK\u TIMEOUT再次测试了它,它工作得非常好(遇到一个php错误,说他无法绑定ldap\u服务器)非常感谢您这很酷,但是,如果服务器从未对主机和端口做出响应,那么连接将挂起,我们将永远听不到回复。例如,如果服务器处于DoS下,可能会发生这种情况。ldap\u connect实际上没有连接到ldap,它只是准备连接。超时是一个ini设置,它发生在调用另一个ldap方法时,通常是ldap_bind(),因为他使用的是PHP,所以“另一个API”建议不起作用。