pfsockopen

(PHP 4、PHP 5、PHP 7、PHP 8)

pfsockopen打开持久性 Internet 或 Unix 域套接字连接

说明

pfsockopen(
    string $hostname,
    int $port = -1,
    int &$error_code = null,
    string &$error_message = null,
    ?float $timeout = null
): resource|false

此函数与 fsockopen() 的行为完全一致,不同之处在于,脚本执行完毕后,连接不会关闭。它是 fsockopen() 的持久版本。

参数

有关参数信息,请参见 fsockopen() 文档。

返回值

pfsockopen() 返回一个文件指针,可与其他文件函数一起使用(例如 fgets()fgetss()fwrite()fclose()feof()),或在失败后返回 false

Changelog

版本 说明
8.0.0 timeout 现在可以为可空值。

另请参见

  • fsockopen() - 打开 Internet 或 Unix 域套接字连接

添加备注

用户贡献的备注 6 个备注

zuraw
12 年前
在 IIS/Windows7 安装上,pfsockopen() 运行非常棒,它保持连接处于打开状态,这会提升性能。然而,有一个需要注意的地方:当连接因网络物理故障而中断时,pfsockopen() 会返回一个连接正常工作的句柄。后续对 fwrite() 的调用会返回 false,因此您会收到有关错误的信息。问题在于,在物理网络连接恢复之后,情况并不会改变:pfsockopen() 仍会返回句柄,而 fwrite() 会返回 false。换句话说,PHP 会坚持使用不可用的旧连接(如果您改用 fsockopen(),则可以正常连接)。在 PHP 关闭未使用的连接 30 分钟后,情况才会恢复正常。
解决此问题的方法是在 fwrite() 返回 false 时对套接字句柄调用 fclose()。
k dot andris at gmail dot com
15 年前
若要查看是否是新的连接还是重复利用的连接,可以使用 ftell() - 然后查看连接上是否有任何流量。如果大于 0,则表示该连接是重复利用的连接。
pulstar at ig dot com dot br
20 年前
在套接字或数据库中的持久连接只应在限制明确的服务器中使用。例如,数据库中允许的连接数必须大于 Apache 的进程数,否则数据库会拒绝连接(如果您使用持久连接,则肯定会发生这种情况)。套接字连接也可能会出现这种情况。这取决于服务配置。我认为,持久连接只会在您能够完全控制涉及的一个或多个服务器时才有用,例如,在负载较重的专用服务器上,那里的少量性能提升值得使用此类连接。在共享服务器中切勿使用它们。
php dot net at domainofdarkness dot com
23 年前
好的,关于 p* 函数在已经存在一个连接时打开一个新连接的情况。我理解的是(无论如何都是 Apache),这是针对每个进程的。如果您在服务器上执行“ps auxw|grep httpd”,您将看到不止一个进程。p* 所做的是只在一个进程上创建一个 p 连接,即实际处理您请求的那个进程。很可能当您再次打开这个页面时,它会由不同的进程应答。我猜想如果您不断刷新页面,您最终会返回到最初的进程,并且不会有错误消息或打开第二个连接。无论如何,所有 p* 函数都是如此;它们不是在每个服务器打开一个连接,而是在每个服务器 _进程_ 打开一个连接。
bimal dot das at maxartists dot com
18 年前
以下是将表单操作 POST 到 SSL 服务器的 cgi 并通过 pfsockopen 检索输出的方法

<?php

$host
= gethostbyaddr($_SERVER['REMOTE_ADDR']);

# working vars
$host = 'www.example.com';
$service_uri = '/cgi-bin/processACT';
$vars ='code=22&act=TEST';

# compose HTTP request header
$header = "Host: $host\r\n";
$header .= "User-Agent: PHP Script\r\n";
$header .= "Content-Type: application/x-www-form-urlencoded\r\n";
$header .= "Content-Length: ".strlen($vars)."\r\n";
$header .= "Connection: close\r\n\r\n";

$fp = pfsockopen("ssl://".$host, 443, $errno, $errstr);
if (!
$fp) {
echo
"$errstr ($errno)<br/>\n";
echo
$fp;
} else {
fputs($fp, "POST $service_uri HTTP/1.1\r\n");
fputs($fp, $header.$vars);
fwrite($fp, $out);
while (!
feof($fp)) {
echo
fgets($fp, 128);
}
fclose($fp);
}

?>
ludvig dot ericson at gmail dot com
17 年前
在使用所有“持久”版本函数时无法明确何时 PHP 会启动新连接,这取决于用户运行 PHP 的方式。
在真正的 CGI 模式(即每个脚本一个进程)下,持久性函数将执行
以下操作:

在启用永久连接时,CGI 模式下,每个脚本将
与其“临时”等效项完全相同。如果你有线程安全 Apache
MPM,此持久性将为每个线程打开一个连接,但并不会立即执行。
把它当作每个线程的一个 PHP 实例即可。

如果你运行 prefork,将 Apache 服务器分叉到多个
accept()ing 子进程的 MPM,你将有每个进程一个 PHP 实例。

这并不总是正确的,因为我可能遗漏了一些难以解决的问题,但一般而言,
知道一个持久性只能尝试保持持久性。

至于 greywyvern dot moc 中的 grey:一个 cronjob 对
此更适合,并定期更新索引,而不是每次有人搜索就请求约 200 页,至少
从你描述的内容来看是这样的。
To Top