imagepng und Content-Length
bearbeitet von
Lieber pl,
> ~~~php
> imagepng($im);
> imagedestroy($im);
> header("Content-Type: image/png");
> ~~~
wenn man den Output-Buffer aktiv nutzt, dann kann man `header()`-Aufrufe egal wo machen, aber ob man unbedingt diese Infrastruktur nutzen will, ist eine Frage des Standpunktes. Anfangs habe ich das auch benutzt, aber mittlerweile schreibe ich meine PHP-Scripte so, dass sie das nicht mehr benötigen.
> Wie in PHP so üblich, landet die Binary im Out Buffer und um die Ausgabe samt HTTP-Header kümmert sich PHP.
Das kann man so machen, muss man aber nicht. Will man die Daten zuerst in anderer Weise handhaben, kann man sie auch in eine Datei schreiben lassen. Dazu ist der zweite Parameter bei `imagepng($res, $to)`, der dann ungleich `null`sein muss.
> Leider fehlt der Header Content-Length, wie bringe ich PHP dazu einen Solchen anzuhängen?
Wenn Du mit dem Output-Buffer hantierst, dann würde ich das so tun:
~~~ php
ob_start();
// stand schon etwas im Puffer?
$buffer_data = ob_get_clean();
// hier findet die Erzeugung Deines Bildes statt...
// Bilddaten in den Puffer schreiben
imagedestroy($im);
// Bilddaten aus dem Puffer holen
$img_data = ob_get_contents();
// Bild senden
header('Content-Type: image/png');
header('Content-Length: '.strlen($img_data));
// Puffer senden und Script hart beenden
ob_end_flush();
exit;
~~~
Wenn Dein Script vernünftig aufgebaut ist, kannst Du Dir den Teil mit `ob_end_flush()` und `exit` sparen. Auch wäre es eine Idee, eine [temporäre Datei](https://www.php.net/manual/en/function.tmpfile.php) anzulegen, in die Du die Bilddaten schreiben lässt, um sie am Ende mit [`readfile()`](https://www.php.net/manual/en/function.readfile.php) an den Browser ausgeben zu lassen. Damit wäre die ganze Puffer-Hantiererei nicht nötig und Dein Script könnte im Anschluss weiterlaufen, um z.B. noch diverse andere Dinge (z.B. logging) zu leisten:
~~~ php
function send_png_image ($im) {
// temporäre Datei erzeugen
$tmp = tmpfile();
$path = stream_get_meta_data($tmp)['uri'];
// Bilddaten in temporäre Datei schreiben
imagepng($im, $tmp);
// Bild senden
header('Content-Type: image/png');
header('Content-Length: '.filesize($path));
readfile($path);
}
~~~
Liebe Grüße
Felix Riesterer