Vannak helyzetek, mikor egy komplex rendszer működésének debugolásához még a Zend PDT sem elég, szeretnénk látni, hogy mi történik a háttérben, miközben kattintgatunk élesben. Erre az egyik számomra legszimpatikusabb módszer, ha indítunk egy TCP "szervert", és annak küldözgetjük rendszerünkből az infót.
Ehhez a kommunikációhoz kreálunk egy klienst is, ami képes az üzeneteinket egyszerűen továbbítani a szervernek. Van is egy a php freaks címről koppitott cucc, ami a fentebb írtakat tökéletesen lefedi. Vagyis apró módosítások hatására tökéletes része lehet rendszerünknek.
Alább a kódot láthatod. Az első maga a szerver, amivel nincs más teendő, csak el kell indítani konzolból, és lesni, hogy milyen infók jelennek meg rajta.
A második maga a "kliens", ami az én esetemben a BasicErrorHandler osztály tagja, meghívása pedig rém egyszerű. Pl. mikor készült a session handlerünk, akkor szerettük volna figyelemmel kísérni, hogy mikor íródnak be az adatbázisba ténylegesen a munkamenet adatok:
BasicErrorHandler::trace("Writing session, account is:" . self::$account);
De lássuk a "szerver" kódját:
#!/usr/bin/php -q <?php error_reporting(E_ALL); ini_set("display_errors", 0); /* Allow the script to hang around waiting for connections. */ set_time_limit(0); /* Turn on implicit output flushing so we see what we're getting * as it comes in. */ ob_implicit_flush(); $address = '127.0.0.1'; $port = 10002; if (($sock = socket_create(AF_INET, SOCK_STREAM, SOL_TCP)) === false) { echo "socket_create() failed: reason: " . socket_strerror(socket_last_error()) . "\n"; } if (socket_bind($sock, $address, $port) === false) { echo "socket_bind() failed: reason: " . socket_strerror(socket_last_error($sock)) . "\n"; } if (socket_listen($sock, 5) === false) { echo "socket_listen() failed: reason: " . socket_strerror(socket_last_error($sock)) . "\n"; } do { if (($msgsock = socket_accept($sock)) === false) { echo "socket_accept() failed: reason: " . socket_strerror(socket_last_error($sock)) . "\n"; break; } /* Send instructions. */ //$msg = "\nWelcome to the PHP Talkback server. \n" . //"To quit, type 'quit'. To shut down the server type 'shutdown'.\n"; //socket_write($msgsock, $msg, strlen($msg)); echo(date("Y-m-d H:i:s") . " Client connected.\n"); do { if (false === ($buf = socket_read($msgsock, 2048, PHP_NORMAL_READ))) { //echo "socket_read() failed: reason: " . socket_strerror(socket_last_error($msgsock)) . "\n"; break; } if (!$buf = trim($buf)) { continue; } if ($buf == 'quit') { break; } if ($buf == 'shutdown') { socket_close($msgsock); break 2; } //$talkback = "PHP: You said '$buf'.\n"; //socket_write($msgsock, $talkback, strlen($talkback)); echo str_replace("quit", "", $buf) . "\n"; } while (true); socket_close($msgsock); } while (true); socket_close($sock); ?>
Mint azt a kód legelején lehet látni, megmondtuk a rendszernek jól, hogy mivel futtassa a fájlt (shebang line), esetünkben ez ugye a php értelmező. Ebből következik, hogy unix rendszereken minden további nélkül szimplán csak le kell futtatni a fájlt.
És a "kliens":
define("ERR_TRACE", true); define("ERR_TRACE_HOST", "127.0.0.1"); define("ERR_TRACE_PORT", 10002); class BasicErrorHandler { [...] public static function trace($message) { if (ERR_TRACE) { $service_port = ERR_TRACE_PORT; $address = ERR_TRACE_HOST; $socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP); if ($socket === false) { self::$socket = false; trigger_error("socket_create() failed: reason: " . socket_strerror(socket_last_error()), E_USER_WARNING); } else { $result = socket_connect($socket, $address, $service_port); if ($result === false) { $socket = false; trigger_error("socket_connect() failed: reason: " . socket_strerror(socket_last_error()), E_USER_WARNING); } } if ($socket && (strstr($_SERVER['REQUEST_URI'], ".jpg") === false) && (strstr($_SERVER['REQUEST_URI'], ".gif") === false) && (strstr($_SERVER['REQUEST_URI'], ".png") === false)) { $header = date("Y-m-d H:i:s") . " " . session_id() . " "; $indents = strlen($header); $ind = ">"; for ($i = 0; $i < $indents; $i++) { $ind .= " "; } $message = $header . $_SERVER['REQUEST_URI'] . " " . $_SERVER['REMOTE_ADDR'] . str_replace("\n", "\n" . $ind, "\n" . $message) . "\n"; socket_write($socket, $message, strlen($message)); socket_write($socket, "quit\n", strlen("quit\n")); } if ($socket) { socket_close($socket); } } } [..] }
Ez lenne az a kódrészlet, ami segítségünkre van abban, hogy igazán egyszerűen küldjünk üzeneteket konzolunkra programunkból futás közben, ezzel könnyebbé téve a háttérben zajló történések figyelemmel kísérését.
beleszóltak