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

发布于 2024-12-20 00:15:26 字数 581 浏览 1 评论 0原文

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

这是我的连接命令:

$connection = ldap_connect($hostname, $port) or die("Could not connect to {$hostname});

我在 ldap_connect() 手册中没有找到任何内容 (手册)关于时间限制参数,您可以在其中定义函数应尝试连接多长时间直至中止。

然而我不太能用 trycatch 或类似的东西想出一个解决方案。我也不想使用 set_time_limit() 函数,因为我的脚本需要运行到最后。

我感谢每一个帮助:) 感谢和问候 蒂姆

I've written a little monitoring script in PHP, which should monitor a virtual directory and it's active directories. Everything works fine but when the virtual directory service freezes is my ldap_connect() not able to connect but also doesn't get an error back. So my whole script stands still. I think that the ldap_connect function gets a timeout back (like when you try to ping an IP and it's not reachable).

That's my connect command:

$connection = ldap_connect($hostname, $port) or die("Could not connect to {$hostname});

And I haven't found something in the manual for ldap_connect() (manual) about a timelimit parameter in which you could define how long the function should try to connect until it aborts.

How ever I wasn't quite able to come up with a solution with try and catch or something like this. I also didn't wanted to use the set_time_limit() function because my script needs to be run until the end.

I appreciate every help :)
Thanks and greetings
Tim

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

流年已逝 2024-12-27 00:15:26

http://www.php.net/manual/en/function .ldap-set-option.php

特别是以下选项:-

LDAP_OPT_NETWORK_TIMEOUT
LDAP_OPT_TIMELIMIT

http://www.php.net/manual/en/function.ldap-set-option.php

particular the following options :-

LDAP_OPT_NETWORK_TIMEOUT
LDAP_OPT_TIMELIMIT
海拔太高太耀眼 2024-12-27 00:15:26

如果您不希望您的 PHP 程序在您的公司 DC 之一出现故障时等待 XXX 秒才放弃,

由于ldap_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 的公司为例,这些 DC 分布在较远的地方。

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

If you don't want your PHP program to wait XXX seconds before giving up in a case when one of your corporate DC's have failed,

and since ldap_connect() does not have a mechanism to timeout on a user specified time,

this is my workaround which shows excellent practical results.

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.");

Also with this approach, you get a real nice fail over functionality.

Take for an example a company with a dozen of DC-a distributed along distant places.

This way your PHP program will always have high availability if at least one DC is active at present.

寄意 2024-12-27 00:15:26

您需要使用支持超时的 API。 LDAP(协议)本身不支持连接超时。 timelimit 是客户端请求的参数,指的是目录将花费多长时间来处理搜索请求,与“连接超时”不同。

You'll need to use an API that supports time-outs. Connection time-outs are not supported in a native fashion by LDAP (the protocol). The timelimit is a client-requested parameter that refers to how long the directory will spend processing a search request, and is not the same as a "connect time-out".

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文