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!

Weitere Posts:

Dieser Beitrag wurde unter php, Quicktips, webdev veröffentlicht. Setze ein Lesezeichen auf den Permalink.

Eine Antwort auf Streams

  1. df sagt:

    Cool, hab die Streams definitiv unterschätzt. Danke!

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.