Невозможно сохранить сгенерированное PHP изображение вне скрипта;"результат слишком велик" - PullRequest
2 голосов
/ 13 апреля 2011

Предупреждение: file_get_contents (effect.php? File = test.gif & bs = & отрицательный = 1) [function.file-get-contents]: не удалось открыть поток: слишком большой результат в C: \ Users \ [user] \ Documents \ NetBeansProjects \ [site] \ handler \ img_replace.php в строке 19

Я получаю эту ошибку при попытке получить доступ к изображению, созданному из сценария PHP.Я часами гуглял ошибки «не удалось открыть поток» и «привести к слишком большим» ошибкам.

Это код для 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();
}

И это соответствующий код для 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 работает, когда целевой файл является обычным файлом изображения, но я бы не хотел записывать файлы на диск, которые будут прочитаны один раз, а затем удалены (плюс я, вероятно, получил бы ту же ошибку, если бы я попытался сделать это где-нибудь, кроме effect.php).Также не имеет значения, насколько велико сгенерированное изображение, так как я даже попробовал его с тестовым изображением 8x8 пикселей и все еще получил ошибку.

Я, очевидно, пытался использовать другие методы, кроме file_get_contents, включая пример № 2на этой странице: http://www.php.net/manual/en/function.fread.php

Я также проверил свой файл php.ini, и ограничение памяти составляет 128 МБ.

Есть идеи?

Редактировать: мне удалось заставить сценарии выполнять, по сути, то, что я хочу, и, вероятно, это лучше, поскольку теперь он не просматривает таблицу, ища одно и то же изображение дважды.Тем не менее, мне все равно пришлось выполнить промежуточный шаг записи на диск, и я до сих пор не решил ошибку «Результат слишком велик».Мне также не нравится, как effect.php ведет себя совершенно по-разному в зависимости от значения get.

Вот новый 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();

А вот код, добавленный вEffect.php:

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");
    }

1 Ответ

0 голосов
/ 16 апреля 2011

После использования моего псевдо-решения, опубликованного выше, в течение нескольких дней на моем локальном хосте Windows, я загрузил сценарии на sci-сервер моего uni для тестирования в онлайн-среде и не смог заставить их записывать файлы на диск, несмотря на настройки perimissions на tmp до 777. Вместо того чтобы пытаться обойти то, что, скорее всего, является преднамеренным ограничением, я вернулся к своей идее выходного буфера.

Решение оказалось обманчиво простым.

        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");
        }

Конечно, я все еще в растерянности относительно того, как хранить сгенерированные необработанные данные, созданные внешним скриптом, но, по крайней мере, теперь я достиг своей цели никогда не записывать файлы на диск.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...