GET und POST Requests absetzen mit PHP und fsockopen

Das Web entwickelt sich weiter - und je mehr es das tut umso wichtiger wird das gegenseitige, automatische Austauschen von Inhalten. Zumeist erfolgt das über APIs, je nachdem wie komplex dieses sind gibts dafür sehr viele unterschiedliche Herangehensweisen. Eines haben die Meisten aber gemeinsam: sie müssen entweder über einen GET oder POST abgesetzt werden.



Wer das im Hintergrund seiner Webanwendung machen will, natürlich voll automatisch, ist mit fsockopen gut bedient. Ich liefere hier zwei einfache Beispiele wie man mit fsockopen innerhalb eines PHP-Skriptes sowohl einen GET als auch einen POST absetzt.

Zuerst der GET Aufruf:

<?php
	$host = 'www.webstylez.net';
	$path = '/GET-und-POST-Requests-absetzen-mit-PHP-und-fsockopen/';
	$fp = fsockopen($host, 80, $errno, $errstr, 30);
	if (!$fp) {
		$buffer .= "$errstr ($errno)<br />\n";
	} else {
		$out = "GET ".$path." HTTP/1.1\r\n";
		$out .= "Host: ".$host."\r\n";
		$out .= "Connection: Close\r\n\r\n";
		fwrite($fp, $out);
	
		while (!feof($fp)) {
			$buffer .= fgets($fp, 128);
		}
		fclose($fp);
	}
	echo $buffer;
?>

Der Umgang mit fsockopen ist ein wenig sperrig: Man kann nicht einfach einen Link reinpappen und den aufmachen lassen, fsockopen arbeitet nämlich nicht wie man es aus dem Browser gewohnt ist mit einem Protokoll, sondern über Ports.

Deswegen geben wir bei Host die Domain OHNE http:// an, das HTTP-Protokoll interessiert fsockopen nämlich nicht. Stattdessen sagen wir in der funktion als zweiter Parameter 80, was der Standard-Port des HTTP-Protokolls ist. Das ist ein häufiger Fehler den ich selber immer wieder mache! Man muss mit fsockopen die domain aus der URL heruastrennen und als host angeben, und den rest dann unten im GET Aufruf!

Unseren Aufruf pappen wir in einen filestream und mit einer while können wir dann verfolgen was von unserem Ruf zurückschallt. Wie man sieht kommt dieser Artikel über den Aufruf herein und hat zu Beginn HTTP-Header Zeilen. Diese würden wir mit einem normalen HTTP-Aufruf nicht sehen, weil sie ja vom Browser interpretiert werden, in den neueren APIs ist es aber immer wichtiger eben diese Header-Zeilen zu sehen. Wordpress und Movable Type wickeln so die Trackpacks und Pingbacks ab.

Der POST braucht etwas mehr, denn wir wollen ja Daten mitschicken:

<?php
	$host = 'www.webstylez.net';
	$path = '/GET-und-POST-Requests-absetzen-mit-PHP-und-fsockopen/';
	$data = 'message='.urlencode('Ich werde gepostet');
	$fp = fsockopen($host, 80, $errno, $errstr, 30);
	if (!$fp) {
		$buffer .= "$errstr ($errno)<br />\n";
	} else {
		$out = "POST ".$path." HTTP/1.1\r\n";
		$out .= "Host: ".$host."\r\n";
		$out .= "Content-Type: application/x-www-form-urlencoded; charset=utf-8\r\n";
		$out .= "Content-Length: ".strlen($data)."\r\n";
		$out .= "Connection: Close\r\n\r\n";
		$out .= $data;
		fwrite($fp, $out);
 
		while (!feof($fp)) {
			$buffer .= fgets($fp, 128);
		}
		fclose($fp);
	}
?>

Was hat sich geändert? Abgesehen davon, dass wir natürlich statt GET einen POSt in den Filestream schreiben, geben wir als content-type ein Formular an, damit signalisieren wir dem Empfänger, das wir eine REST-Struktur á la ?name=wert&name2=wert2 verwenden. Dann verlangt ein richtig formatierter POST die Angabe der Content-Length, also die ANzahl der Zeichen die wie Posten wollen, und danach werden ganz einfach unsere POST-Daten in der bekannten REST-Schreibweise angegeben.