在使用 PHP 进行基于 Socket 的编程时,socket_accept() 是一个关键函数,它用于接受来自客户端的连接。然而,如果该函数调用失败,可能会抛出错误,导致程序中断或产生不可预期的行为。因此,捕捉这些错误并将其记录在日志中,对于调试和运维来说是非常必要的。
本文将详细介绍如何捕捉 socket_accept() 函数的错误,并将其记录到日志文件中。
以下是一个基础的 Socket 服务端示例:
<?php
$host = '0.0.0.0';
$port = 8080;
$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
if ($socket === false) {
error_log("socket_create() failed: " . socket_strerror(socket_last_error()) . "\n", 3, "/var/log/php_socket_error.log");
exit;
}
if (!socket_bind($socket, $host, $port)) {
error_log("socket_bind() failed: " . socket_strerror(socket_last_error($socket)) . "\n", 3, "/var/log/php_socket_error.log");
exit;
}
if (!socket_listen($socket, 5)) {
error_log("socket_listen() failed: " . socket_strerror(socket_last_error($socket)) . "\n", 3, "/var/log/php_socket_error.log");
exit;
}
socket_accept() 会在失败时返回 false。为了捕捉错误代码并记录日志,你可以如下处理:
while (true) {
$clientSocket = @socket_accept($socket);
if ($clientSocket === false) {
$errCode = socket_last_error($socket);
$errMsg = socket_strerror($errCode);
error_log("socket_accept() failed with error [$errCode]: $errMsg\n", 3, "/var/log/php_socket_error.log");
// 根据需要可以选择继续或者终止循环
continue;
}
// 接收到连接后的处理逻辑
$msg = "Hello from server on http://m66.net\n";
socket_write($clientSocket, $msg, strlen($msg));
socket_close($clientSocket);
}
在这段代码中:
使用了 @ 运算符来抑制 socket_accept() 抛出的默认警告;
socket_last_error() 获取最近一次 Socket 操作的错误代码;
socket_strerror() 将错误代码转化为人类可读的字符串;
error_log() 将错误写入 /var/log/php_socket_error.log 文件。
注意:确保你有权限写入日志文件路径,并且日志文件的父目录存在。
你也可以将错误日志封装成一个函数,以便复用和统一格式输出:
function log_socket_error($socket, $context = '') {
$errCode = socket_last_error($socket);
$errMsg = socket_strerror($errCode);
$timestamp = date('Y-m-d H:i:s');
$logEntry = "[$timestamp] [$context] Error [$errCode]: $errMsg\n";
error_log($logEntry, 3, "/var/log/php_socket_error.log");
}
使用方式如下:
$clientSocket = @socket_accept($socket);
if ($clientSocket === false) {
log_socket_error($socket, 'socket_accept');
continue;
}
通过上述方法,你可以在使用 socket_accept() 时有效捕捉和记录错误,避免服务端静默失败或调试困难。同时,将日志写入文件也便于后续的运维排查和自动监控系统的集成。在实际生产环境中,也建议使用类似 ELK 或其他集中式日志方案进一步增强可观测性。