2 Stimmen

PHP-generiertes Bild kann nicht außerhalb des Skripts gespeichert werden; "Ergebnis zu groß".

Warning: file_get_contents(effect.php?file=test.gif&bs=&negative=1) [function.file-get-contents]: failed to open stream: Ergebnis zu groß in C:\Users\ [user] \Documents\NetBeansProjects\ [Seite] \handler\img_replace.php in Zeile 19

Ich erhalte diesen Fehler, wenn ich versuche, auf ein Bild zuzugreifen, das von einem PHP-Skript generiert wurde. Ich habe die Fehler "failed to open stream" und "result too large" seit Stunden gegoogelt und bin ratlos.

Dies ist der Code für img_replace.php:

try
{
    $file = $_POST['file'];
    $ref_get = $_POST['ref_get'];

    $image = R::findOne(IMAGES_TABLE, "filename='$file'");
    $image->data = file_get_contents("effect.php?" . htmlspecialchars_decode($ref_get));

    R::store($image);
}
catch (Exception $ex)
{
    echo $ex->getMessage();
}

Und dies ist der entsprechende Code für effect.php:

try
{
    $image = R::findOne(IMAGES_TABLE, "filename='$file'");

    $mimetype = $image->mimetype;
    $filename = $image->filename;
    $data = $image->data;

    header("content-type: $mimetype");
    header("content-disposition: filename=$filename");

    $src_img = imagecreatefromstring($data);

    //manipulate the image

    echo imagepng($out_img);

}
catch (Exception $ex)
{
    $message_ref = $ex->getMessage();
    echo $ex->getMessage();
}

file_get_contents funktioniert, wenn die Zieldatei eine normale Bilddatei ist, aber ich würde lieber keine Dateien auf die Festplatte schreiben, um sie einmal zu lesen und dann zu löschen (außerdem würde ich wahrscheinlich die gleiche Fehlermeldung bekommen, wenn ich versuchen würde, es irgendwo anders als in effect.php zu machen). Es spielt auch keine Rolle, wie groß das erzeugte Bild ist, da ich es sogar mit einem 8x8 Pixel großen Testbild versucht habe und immer noch den Fehler bekam.

Ich habe natürlich versucht, mit anderen Methoden als file_get_contents, einschließlich Beispiel # 2 auf dieser Seite: http://www.php.net/manual/en/function.fread.php

Ich habe auch meine php.ini-Datei überprüft und das Speicherlimit beträgt 128 MB.

Irgendwelche Ideen?


Edit: Ich konnte die Skripte dazu bringen, im Wesentlichen das zu tun, was ich will, und es ist wahrscheinlich besser, da es jetzt nicht mehr zweimal in der Tabelle nach demselben Bild sucht. Allerdings muss ich immer noch den Zwischenschritt des Schreibens auf die Festplatte machen, und ich habe den Fehler "Ergebnis zu groß" immer noch nicht gelöst. Mir gefällt auch nicht, dass effect.php sich je nach get-Wert völlig unterschiedlich verhält.

Hier ist die neue img_replace.php:

<?php
require_once "../include/session.php";
require_once "../include/vars.php";

$ref_get = $_POST['ref_get'];

header("location: effect.php?" . htmlspecialchars_decode($ref_get) . "&apply=1");
exit();

Und hier ist der Code, der der Datei effects.php hinzugefügt wurde:

if($apply && $ref_base == "index.php?p=ucp")
    {
        $filename = "../tmp/temp.png";
        imagepng($out_img,$filename);
        $handle = fopen($filename, "rb");
        $image->data = fread($handle, filesize($filename));
        fclose($handle);
        unlink($filename);

        R::store($image);

        header("location: ../index.php?p=ucp&act=gallery");
        exit();
    }
    else
    {
        header("content-type: $mimetype");
        header("content-disposition: filename=$filename");
    }

0voto

abielefeldt Punkte 21

Nachdem ich meine oben gepostete pesudo-Lösung ein paar Tage lang auf meinem Windows-Localhost verwendet hatte, lud ich die Skripte zum Testen in einer Online-Umgebung auf den Informatikserver meiner Uni hoch und konnte sie nicht dazu bringen, Dateien auf die Festplatte zu schreiben, obwohl ich die Zugriffsrechte auf tmp auf 777 gesetzt hatte. Anstatt zu versuchen, diese höchstwahrscheinlich absichtliche Einschränkung zu umgehen, griff ich auf meine Idee mit dem Ausgabepuffer zurück.

Die Lösung erwies sich als trügerisch einfach.

        ob_start();            
        if($fmt == "jpeg")
        {
            $imagefunc($out_img,null,$quality);
        }
        else
        {
            $imagefunc($out_img);
        }
        $image->data = ob_get_contents();
        ob_end_clean();

        $filesize_bytes = strlen($image->data);
        $filesize_kb = (int)($filesize_bytes / 1024.0 + 0.5);

        if($filesize_kb <= $max_filesize && $filesize_bytes > 0)
        {
            $gallery = R::findOne(GALLERIES_TABLE, "filename='$file'");
            $image->filename = stripExt($image->filename) . ".$fmt";
            $gallery->filename = stripExt($gallery->filename) . ".$fmt";
            $image->mimetype = "image/$fmt";
            R::store($image);
            R::store($gallery);
            $message_ref = "Effects applied successfully. New filesize: " . $filesize_kb . "KB";
        }
        else if($filesize_bytes == 0)
        {
            throw new Exception("Error: Unable to create temp image");
        }
        else
        {
            throw new Exception("New file too large (" . $filesize_kb . "KB); replacement canceled");
        }

Zugegeben, ich weiß immer noch nicht, wie ich die von einem externen Skript erzeugten Rohdaten speichern soll, aber zumindest habe ich jetzt mein Ziel erreicht, niemals Dateien auf die Festplatte schreiben zu müssen.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X