Le débogage est souvent un mal de tête lors du développement de programmes de serveurs basés sur des douilles à l'aide de PHP. Surtout face à des défaillances de connexion inexplicables, à des interruptions de réception de données ou à des problèmes de délai d'expiration, les développeurs s'appuient généralement sur socket_last_error () et socket_streror () pour suivre la source des erreurs. Cependant, ces deux fonctions à elles seules ne peuvent pas fournir le contexte d'erreur le plus clair, et socket_clear_error () est particulièrement critique pour le moment.
Dans PHP Socket Programming, socket_last_error () est une fonction de requête d'état qui renvoie le dernier code d'erreur . Mais cette "dernière fois" n'est peut-être pas le "fonctionnement actuel" que vous avez imaginé. Étant donné que l'état d'erreur de socket de PHP est réservé à l'échelle mondiale , tant qu'il n'est pas explicitement effacé, même si vous avez effectué une nouvelle opération, il peut toujours renvoyer le code d'erreur laissé par l'opération précédente .
Par exemple, le code suivant:
$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
socket_connect($socket, '127.0.0.1', 8080);
$errCode = socket_last_error($socket);
echo socket_strerror($errCode);
Si une erreur se produit dans socket_create () et que vous obtenez le code d'erreur immédiatement après socket_connect () , ce que vous obtenez peut être l'erreur laissée par socket_create () . Cela provoquera une grande erreur dans le débogage.
Pour éviter les interférences de cet "état d'erreur historique", nous pouvons appeler socket_clear_error () avant chaque opération de socket critique pour effacer explicitement l'état d'erreur précédent. Le plus grand avantage de cela est de s'assurer que le prochain socket_last_error () renvoie le code d'erreur généré par l'opération actuelle .
Par exemple:
$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
// Effacer l'état d'erreur précédent
socket_clear_error($socket);
// Essayez de se connecter
if (!socket_connect($socket, '127.0.0.1', 8080)) {
$errorCode = socket_last_error($socket);
$errorMsg = socket_strerror($errorCode);
error_log("Échec de la connexion:[$errorCode] $errorMsg");
}
L'avantage de l'écriture de cette façon est que si la connexion échoue, vous savez que le code d'erreur doit être causé par cette opération de connexion plutôt que par une erreur héritée.
Dans les grands services, les développeurs ont tendance à pousser les journaux de débogage à un service de journal ou un panneau d'affichage, par exemple:
$url = 'http://m66.net/log/record.php';
$params = [
'event' => 'socket_connect_fail',
'error' => socket_strerror(socket_last_error($socket)),
];
file_get_contents($url . '?' . http_build_query($params));
Si vous n'utilisez pas à l'avance socket_clear_error () , le message d'erreur passé ici peut n'avoir rien à voir avec l'événement de défaillance actuel, ce qui rend finalement l'exploitation forestière "propre mais non fiable".
Lors de l'emballage des opérations de socket à l'aide de la structure de capture d'essai, il est également recommandé d'appeler socket_clear_error () avant que chaque exception ne se produise. Cela rendra le message d'erreur que vous obtenez dans le bloc de capture plus "précis" et évitera de confondre les points d'erreur réels en raison des erreurs successives de plusieurs opérations de socket.
socket_clear_error () est un outil de débogage qui est facilement négligé dans la programmation de socket PHP. En l'utilisant rationnellement, la précision du débogage et la crédibilité du journal peuvent être considérablement améliorées, en particulier lorsqu'ils traitent de connexions simultanées élevées ou de logique de communication non bloquante complexe. Les développeurs devraient développer l'habitude d'appeler cette fonction avant les opérations clés du socket, créant ainsi un système de débogage plus clair et plus fiable.