我经常在 php 文档中阅读用户没有检查 php 函数的返回值,在 socket_write 的情况下,我没有看到这里有人费心阅读服务器回复的套接字。
然后一个用户认为在 smtp 连接上的 socket_write 之后使用 usleep 是一个好主意。
实际上,如果您检查服务器回复,不仅它会给服务器时间在您再次写入套接字之前进行回复,而且这也是一个检查服务器回复了什么的绝佳机会。
例如,对于 smtp 连接
在这个例子中,MAIL_SERVER、MAIL_PORT 和 DEBUG 是我定义的常量。
<?php
function sendmail( $param )
{
$from = &$param[ 'from' ];
$to = &$param[ 'to' ];
$message = &$param[ 'data' ];
$isError = function( $string )
{
if( preg_match( '/^((\d)(\d{2}))/', $string, $matches ) )
{
if( $matches[ 2 ] == 4 || $matches[ 2 ] == 5 ) return( $matches[ 1 ] );
}
else
{
return( false );
}
};
try
{
$socket = null;
if( ( $socket = socket_create( AF_INET, SOCK_STREAM, SOL_TCP ) ) == false )
{
throw new Exception( sprintf( "无法创建套接字: %s", socket_strerror( socket_last_error() ) ) );
}
if( !socket_connect( $socket, MAIL_SERVER, MAIL_PORT ) )
{
throw new Exception( sprintf( "无法连接到服务器 %s: %s", MAIL_SERVER, socket_strerror( socket_last_error() ) ) );
}
$read = socket_read( $socket, 1024 );
if( $read == false )
{
throw new Exception( sprintf( "无法从套接字读取: %s", socket_strerror( socket_last_error() ) ) );
}
if( socket_write( $socket, sprintf( "HELO %s\r\n", gethostname() ) ) === false )
{
throw new Exception( sprintf( "无法写入套接字: %s", socket_strerror( socket_last_error() ) ) );
}
$read = socket_read( $socket, 1024 );
if( $read == false )
{
throw new Exception( sprintf( "无法从套接字读取: %s", socket_strerror( socket_last_error() ) ) );
}
else
{
if( ( $errCode = $isError( $read ) ) ) throw new Exception( "服务器响应了错误代码 $errCode" );
}
if( socket_write( $socket, sprintf( "MAIL FROM: %s\r\n", $from ) ) === false )
{
throw new Exception( sprintf( "无法写入套接字: %s", socket_strerror( socket_last_error() ) ) );
}
$read = socket_read( $socket, 1024 );
if( $read == false )
{
throw new Exception( sprintf( "无法从套接字读取: %s", socket_strerror( socket_last_error() ) ) );
}
else
{
if( ( $errCode = $isError( $read ) ) ) throw new Exception( "服务器响应了错误代码 $errCode" );
}
return( $totalWriten );
}
catch( Exception $e )
{
$ERROR = sprintf( "发送邮件消息时在第 %d 行出现错误。 ", $e->getLine() ) . $e->getMessage();
return( false );
}
}