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!
Cool, hab die Streams definitiv unterschätzt. Danke!