Streams

Kleine Zusammenstellung, was man mit PHP-Streams für feine Sachen anstellen kann. Streams werden total zu unrecht noch sehr stiefmütterlich behandelt, deswegen hier mal ein paar „Schmankerl“.

Temoräre Dateien mit Streams

$fp = fopen("php://temp/maxmemory:" . (2 * 1024 * 1024), 'r+'); fputs($fp, "hello\n"); rewind($fp); echo stream_get_contents($fp); 

Hier wird 2 MB im Speicher reserviert. Sollte der zu speichernde Inhalt größer als diese 2 MB werden (was im übrigen auch der Default-Wert ist, wenn man /maxmemory: weglassen würde), wird eine temporäre Datei in sys_get_temp_dir angelegt. Damit sind coole Sachen möglich, bspw. mittels fputcsv in eine Variable schreiben – siehe hier. Alternativ existiert auch noch php://temp, was direkt in eine temporäre Datei schreibt.

Normaler Output mit Filtern

$fp = fopen('php://output', 'w'); stream_filter_append($fp, 'convert.base64-encode'); fwrite($fp, "Base 64 encoded!"); 

Direkter Zugriff auf den Output-Stream, ähnlich wie mit echo und print. Befriedigt in der hier gezeigten Form zugegeben eher akademische Bedürfnisse. Die zur Verfügung stehenden Filter können benutzt werden.

Streams filtern

readfile("php://filter/read=string.toupper|string.rot13/resource=https://d-mueller.de"); 

Stream (in diesem Fall diese Webseite) einlesen und mit den Filtern rot13 und strtoupper bearbeiten.

Alternativ geht das auch mit Dateien und schreibend:

file_put_contents("php://filter/write=string.rot13/resource=samplefile.htm", "<o>Bold and rotated!</o>"); 

CURL Ersatz

ini_set('user_agent', "Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/537.1 (KHTML, like Gecko) Chrome/21.0.1180.89 Safari/537.1 phpyeah!"); $fp = fopen('http://local/streams/bar.php', 'r'); 

User-Agent setzen leicht gemacht. Aber da geht noch mehr:

$options = array('http' => array (     'content' => 'foo=bar&baz=1234', 	'method'  => 'POST',     'timeout' => 3, 	'header' => "Content-Type: application/x-www-form-urlencoded\r\nCookie: test=xy\r\n" ));  $context = stream_context_create($options); echo file_get_contents("http://local/streams/bar.php", 0, $context); 

Ist ohnehin sehr schön, dass file_get_contents mit dem Stream-Kontext klarkommt. Lässt sich auch vorzüglich testen, indem wir in der bar.php-Datei einfach folgendes unterbringen:

print_r($_COOKIE); print_r($_POST); 

Data-Stream

$str = "Das ist ein Test"; $decoded = file_get_contents("data://text/plain;base64," . base64_encode($str)); var_dump($str === $decoded); //bool(true) 

Meta-Informationen

$soundstream = fopen("Barcardi Feeling - The Orginal Song Of Bacardi Rum.mp3", "r"); $meta = stream_get_meta_data($soundstream); print_r($meta); /* Array (     [wrapper_type] => plainfile     [stream_type] => STDIO     [mode] => r     [unread_bytes] => 0     [seekable] => 1     [uri] => Barcardi Feeling - The Orginal Song Of Bacardi Rum.mp3     [timed_out] =>      [blocked] => 1     [eof] =>  ) */ 

Ist auch bei URLs recht gesprächig.

Zip-Dateien lesen

$fp = fopen('zip://' . dirname(__FILE__) . '/file.zip#content.txt', 'r'); echo fread($fp, 1024); fclose($fp); 

Liest die Datei „content.txt“ aus dem Archiv „file.zip“.

FTP-Handling

$creds = array ( 	"host" => 'ftp.d-mueller.de', 	"user" => 'nutzername', 	"password" => 'daspasswort' );  $stream = stream_context_create(array('ftp' => array('overwrite' => true))); $filename = "testfile.txt";  $uri = sprintf('ftp://%s:%s@%s/%s', $creds['user'], $creds['password'], $creds['host'], $filename); file_put_contents($uri, "write me!", 0, $stream); 

Entliehen von ebene7, wo der Schnippsel ursprünglich geposted wurde.

Funktioniert selbstredend auch lesend:

$creds = array ( 	"host" => 'ftp.d-mueller.de', 	"user" => 'nutzername', 	"password" => 'daspasswort' );  $stream = stream_context_create(array('ftp' => array('overwrite' => true))); $filename = "robots.txt";  $uri = sprintf('ftp://%s:%s@%s/%s', $creds['user'], $creds['password'], $creds['host'], $filename); echo file_get_contents($uri, 0, $stream); 

…und noch viel mehr!

Darüberhinaus gibt es – entsprechend kompiliertes PHP vorausgesetzt – noch Streams für das Handling von Audiodateien (ogg-Files) oder direkten SSH-Zugriff. Streams sollte man immer auf der Rechnung haben!