ZetCode

PHP pfsockopen 函数

最后修改于 2025 年 4 月 4 日

PHP pfsockopen 函数用于打开一个持久的 Internet 或 Unix 域套接字连接。它类似于 fsockopen,但会在请求之间维护连接。

基本定义

pfsockopen 建立到指定主机和端口的持久套接字连接。该连接在多个脚本执行过程中保持打开状态。

语法:pfsockopen(string $hostname, int $port = -1, int &$errno = null, string &$errstr = null, float $timeout = ini_get("default_socket_timeout"))。成功时返回文件指针,失败时返回 false。

基本 HTTP 请求

此示例演示了如何使用 pfsockopen 进行简单的 HTTP GET 请求。

http_request.php
<?php

declare(strict_types=1);

$fp = pfsockopen("www.example.com", 80, $errno, $errstr, 30);

if (!$fp) {
    echo "Error: $errstr ($errno)";
} else {
    $out = "GET / HTTP/1.1\r\n";
    $out .= "Host: www.example.com\r\n";
    $out .= "Connection: Close\r\n\r\n";
    
    fwrite($fp, $out);
    
    while (!feof($fp)) {
        echo fgets($fp, 128);
    }
    
    fclose($fp);
}

这会连接到端口 80 上的 example.com 并发送一个基本的 HTTP GET 请求。响应被逐行读取并输出。连接是持久的。

SMTP 邮件发送

此示例展示了如何使用 pfsockopen 通过 SMTP 发送电子邮件。

smtp_email.php
<?php

declare(strict_types=1);

$smtp = pfsockopen("mail.example.com", 25, $errno, $errstr, 30);

if (!$smtp) {
    die("Error: $errstr ($errno)");
}

function smtp_command($socket, $cmd) {
    fwrite($socket, $cmd . "\r\n");
    return fgets($socket, 512);
}

echo smtp_command($smtp, "EHLO localhost");
echo smtp_command($smtp, "MAIL FROM: <sender@example.com>");
echo smtp_command($smtp, "RCPT TO: <recipient@example.com>");
echo smtp_command($smtp, "DATA");
echo smtp_command($smtp, "Subject: Test\r\n\r\nHello World\r\n.");
echo smtp_command($smtp, "QUIT");

fclose($smtp);

这会连接到 SMTP 服务器并发送一封基本邮件。连接在命令之间保持不变。每个 SMTP 命令都会收到服务器的响应。

自定义 TCP 服务器通信

此示例演示了与自定义 TCP 服务器的通信。

custom_tcp.php
<?php

declare(strict_types=1);

$socket = pfsockopen("tcp://127.0.0.1", 9000, $errno, $errstr, 30);

if (!$socket) {
    die("Error: $errstr ($errno)");
}

fwrite($socket, "PING\r\n");
$response = fgets($socket, 1024);

echo "Server response: $response";

fwrite($socket, "QUIT\r\n");
fclose($socket);

这会连接到端口 9000 上的本地 TCP 服务器。它发送一个 PING 命令并读取响应。连接会保持打开状态以供后续请求。

带上下文的 HTTPS 连接

此示例展示了如何建立安全的 HTTPS 连接。

https_connection.php
<?php

declare(strict_types=1);

$context = stream_context_create([
    'ssl' => [
        'verify_peer' => false,
        'verify_peer_name' => false
    ]
]);

$fp = pfsockopen('ssl://www.example.com', 443, $errno, $errstr, 30, $context);

if (!$fp) {
    die("Error: $errstr ($errno)");
}

$out = "GET / HTTP/1.1\r\n";
$out .= "Host: www.example.com\r\n";
$out .= "Connection: Close\r\n\r\n";

fwrite($fp, $out);

while (!feof($fp)) {
    echo fgets($fp, 128);
}

fclose($fp);

这会使用 SSL 建立安全的 HTTPS 连接。流上下文允许配置 SSL 参数。连接会保持不变以便重复使用。

Unix 域套接字通信

此示例演示了与 Unix 域套接字的通信。

unix_socket.php
<?php

declare(strict_types=1);

$socket = pfsockopen("unix:///var/run/myservice.sock", 0, $errno, $errstr, 30);

if (!$socket) {
    die("Error: $errstr ($errno)");
}

fwrite($socket, "STATUS\r\n");
$response = fgets($socket, 1024);

echo "Service status: $response";

fclose($socket);

这会连接到位于 /var/run/myservice.sock 的 Unix 域套接字。它发送一个 STATUS 命令并读取响应。连接保持持久。

最佳实践

来源

PHP pfsockopen 文档

本教程通过针对各种使用持久连接的网络通信场景的实际示例,涵盖了 PHP pfsockopen 函数。

作者

我的名字是 Jan Bodnar,我是一名充满激情的程序员,拥有丰富的编程经验。我自 2007 年以来一直在撰写编程文章。迄今为止,我已撰写了 1400 多篇文章和 8 本电子书。我在教授编程方面拥有十多年的经验。

列出 所有 PHP 网络函数