Übersicht » Einführung OOP
Das Script auf dieser Seite setzt eine Socket-Erweiterung von PHP voraus, um eine hardwarenahe
Schnittstelle zum Aufbau einer Socket-Verbindung zwischen Client und Server zu nutzen, wobei diese Erweiterung auf BSD Sockets
aufbaut. Das Kürzel BSD steht in diesem Zusammenhang für Berkeley Software Distribution. Um das Script nutzen zu können, muss
der Socket-Support ermöglicht sein. Kontrollieren Sie vor einem ersten Test, ob in der PHP Info ein Eintrag wie "Sockets
Support enabled" existiert. Falls nicht, suchen Sie in der php.ini (falls Zugriff auf die php.ini besteht) nach
dem Eintrag extension=php_sockets.dll und kommentieren diesen durch die Entfernung des vorangestellten Semikolons ein. Weitere
Hinweise siehe [1].
Für den Fall, dass sich ein "Sockets Support" nicht ermöglichen lassen sollte, sei auf das Beispiel "cURL
Klasse" verwiesen, welches ebenfalls eine Ausgabe wie dieses Listing liefert. Einziger Unterschied, Port und IP-Adresse
werden nicht mit eingeblendet.
Nach dem ersten Aufruf des Scripts im Browser sowie der Eingabe und Übermittlung einer URL mit Hilfe des Formulars, enthält
die Ausgabe die vom Server erhaltene Response mit dem HTTP-Header (Message Header) und dem Message Body. Somit das, was
auch ein einfacher Bot sehen würde, wenn er eine Webseite besucht.
Vorbemerkung: Bei der Beschreibung wird der Begriff Funktionen statt Methoden (wie
bei OOP üblich) verwendet, da es sich um Funktionen handelt, die von PHP und anderen Sprachen zur Verfügung gestellt und
in diesen Sprachen als Funktionen beschrieben werden.
Weiterhin wurde nur eine Klasse für die eigentliche TPC/IP Socket Verbindung definiert, die Auswertung der vom Formular
übermittelten Daten erfolgt hingegen im prozeduralen Stil. Auf eine durchgängig objektorientierte Programmierung wurde zu
Gunsten der Einfachheit in diesem Beispiel verzichtet. Dass es auch anders geht, beweisen die Beispiele unter den Menüpunkten
"Formular Klasse" und "cURL Klasse".
Einzelheiten: Im ersten Teil der Klasse werden die erforderlichen Angaben für den Request gesetzt. Daran
anschließend wird mit der Funktion getservbyname der passende Port für den angegebenen Dienst (www) und für das
angegebene Protokoll (TPC) gesucht, sowie mit der Funktion gethostbyname die entsprechende IPv4-Adresse ausgelöst. Mit
socket_create wird der Endpunkt (Socket) für die Kommunikation erzeugt, wobei folgende Parameter gesetzt werden:
AF_INET für auf IPv4 beruhende Internet-Protokolle
SOCK_STREAM Socket-Typ für das TCP-Protokoll
SOL_TCP Konstante für das TCP-Protokoll
Im weiteren Verlauf wird mit socket_connect eine Verbindung zur angegebenen Adresse und zum ermittelten
Port aufgebaut und mit socket_write die Request-Daten geschrieben. Die if-Statements mit socket_strerror dienen lediglich der
Anzeige des Verlaufs bzw. der Ermittlung von Socket-Fehlern. In einer Schleife (while) werden die übermittelten Daten
mit der Funktion socket_read gelesen, wobei die Anzahl der höchstens zu lesenden Bytes zwar anzugeben ist, nur bei den Tests
kleine Werte von PHP scheinbar nicht beachtet wurden, eine fehlen Angabe hingegen schon. Mit socket_close wird zum Abschluss der
Klasse die Socket-Verbindung geschlossen.
Für die Ausgabe ist es neben der Erstellung eines Objektes erforderlich, die übermittelten Werte den öffentlichen Variablen
der Klasse zuzuweisen. Beides, weiterhin die eigentliche Ausgabe, erfolgt mit den letzten Code-Zeilen.
Code-Listing/Script zum Aufbau einer TCP/IP Socket Verbindung:
<?php error_reporting(E_ALL); $domain = "www.example.com"; $seite = "/"; $seitef = ""; /*-- Überprüfung der vom Formular übermittelten URL ---------------------------*/ if (isset($_GET["abrufen"]) and !empty($_GET["abrufen"])) { $abrufen = trim($_GET["abrufen"]); $hrefpos = stripos($abrufen, "http://"); $abrufen = preg_replace("/[^a-zA-Z0-9.:?&\/=_-]/", "", $abrufen); if ($hrefpos === false) { $abrufen = "http://".$abrufen; } $geparst = parse_url($abrufen); if (isset($geparst["host"]) and !empty($geparst["host"])) { $domain = $geparst["host"]; } if (isset($geparst["path"]) and !empty($geparst["path"])) { $seite = $geparst["path"]; $seitef = $seite; if (isset($geparst["query"]) and !empty($geparst["query"])) { $seite .= "?".$geparst["query"]; } } } ?> <!DOCTYPE html> <html> <head> <title>Abruf wie durch Bot</title> </head> <body> <div style="text-align:center"> <h1>Abruf wie durch Bot</h1> <?php echo htmlentities($domain.$seitef, ENT_QUOTES)."<br>\n"; ?> <form action="<?php echo basename($_SERVER["PHP_SELF"]); ?>" method="get"> <input type="text" name="abrufen" size="60" maxlength="80"><br> <input type="reset" value=" Reset "> <input type="submit" value=" Senden "> </form> </div> <?php /*-- Klasse zum Aufbau einer TCP/IP Socket Verbindung -------------------------*/ class WieBot { public $domain = ""; public $seite = ""; public function getVerbindung() { $request = "GET ".$this->seite." HTTP/1.1\r\n"; $request .= "Host: ".$this->domain."\r\n"; $request .= "User-Agent: Mozilla/5.0 (compatible; Demo Botklasse 0.1)\r\n"; $request .= "Connection: Close\r\n\r\n"; $dienstp = getservbyname("www", "tcp"); $adresse = gethostbyname($this->domain); $socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP); $gebeaus = ""; if ($socket != false) { $sockett = "TCP/IP Socket (Endpunkt) wurde erzeugt: OK.<br>\n"; } else { $sockett = "TCP/IP Socket (Endpunkt) wurde nicht erzeugt: Grund: ". socket_strerror($socket)."<br>\n"; } $verbindg = socket_connect($socket, $adresse, $dienstp); if ($verbindg != false) { $verbindgt = "Eine Verbindung zu ".$adresse." ". "über Port ".$dienstp." wurde aufgebaut: OK.<br>\n"; } else { $verbindgt = "Der Verbindungsaufbau schlug fehl. ". "Grund: ".$verbindg." ".socket_strerror($verbindg)."<br>\n"; } $gesendet = socket_write($socket, $request, strlen($request)); if ($gesendet !== false) { $gesendett = "Ein HTTP GET Request wurde gesendet: OK.<br>\n"; } else { $gesendett = "Es wurde kein Request gesendet!<br>\n"; } while ($ausgabe = socket_read($socket, 1000)) { $gebeaus .= htmlentities($ausgabe, ENT_QUOTES); } socket_close($socket); $endeges = "Der Socket (Endpunkt) wurde geschlossen: OK.<br>\n\n"; return "<span style=\"color:#862000\">".$sockett.$verbindgt.$gesendett."</span>\n<hr>\n". "<pre>".$gebeaus."</pre>\n<hr>\n<span style=\"color:#862000\">".$endeges."</span>\n"; } } /*------------------------------------------------------------------------------- Erzeugen und Instanziieren des Objektes WieBot, Zuweisung der Variablen-Werte von $domain und $seite, Ausgabe des Rückgabewertes der Funktion getVerbindung. -------------------------------------------------------------------------------- */ $wiebot = new WieBot(); $wiebot->domain = $domain; $wiebot->seite = $seite; echo $wiebot->getVerbindung(); ?> </body> </html>
Hinweis zu 1: Bei einem Test wurde der Fehler-Code 406 ausgegeben. Als Grund stellte sich heraus, dass der Server, auf dem das Script abgelegt wurde, kein http:// im QueryString erlaubte. Bei Eingabe der URL ohne http:// ins Formular erfolgte der Abruf wie erwartet ohne Probleme.
Einstieg in PHP
Übersicht
Diverse Themen