PHP Conference Japan 2024

pfsockopen

(PHP 4, PHP 5, PHP 7, PHP 8)

pfsockopen打开持久化互联网或 Unix 域套接字连接

描述

pfsockopen(
    字符串 $hostname,
    整数 $port = -1,
    整数 &$error_code = null,
    字符串 &$error_message = null,
    ?浮点数 $timeout = null
): 资源|false

此函数的行为与 fsockopen() 完全相同,区别在于脚本结束后连接不会关闭。它是 fsockopen() 的持久化版本。

参数

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

返回值

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

变更日志

版本 描述
8.0.0 timeout 现在可以为 null。

参见

  • fsockopen() - 打开互联网或 Unix 域套接字连接

添加注释

用户贡献的注释 5 条注释

zuraw
12 年前
pfsockopen() 在 IIS/Windows7 安装中运行良好,它保持连接打开,这有利于性能。但是,有一个需要注意的地方:当由于物理网络故障导致连接中断时,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
21 年前
套接字或数据库中的持久连接仅应在限制明确定义的服务器中使用。例如,数据库中允许的连接数必须大于 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 年前
以下是使用 pfsockopen 将表单操作 POST 到 SSL 服务器的 cgi 并检索输出的方法

<?php

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

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

# 组成 HTTP 请求头
$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);
}

?>
To Top