Установка заголовка для содержимого изображения в CakePHP - PullRequest
0 голосов
/ 26 августа 2011

Я пишу действие в контроллере, где в определенном случае я хочу напрямую выводить необработанные данные изображения и установить соответствующий тип содержимого заголовка.Однако я думаю, что заголовок уже был установлен ранее CakePHP (я устанавливаю render как false).

Есть ли способ обойти это?Спасибо!

Ответы [ 3 ]

1 голос
/ 26 августа 2011

Это не $this->render(false), это $this->autoRender=false; Заголовок не отправляется в действии контроллера, если вы что-то не выводите.

1 голос
/ 26 августа 2011

Как уже было сказано, CakePHP не отправляет заголовки, когда render равно false. Однако помните, что любой код, выполняющий echo, будет отправлять заголовки (кроме случаев, когда вы используете буферизацию вывода). Это включает в себя сообщения от PHP (предупреждения и т. Д.).

Отправка файла может быть выполнена несколькими способами, но есть два основных способа:

Отправьте файл, используя обычный PHP

function send_file_using_plain_php($filename) {
    // Avoids hard to understand error-messages
    if (!file_exists($filename)) {
        throw RuntimeException("File $filename not found");
    }

    $fileinfo = new finfo(FILEINFO_MIME);
    $mime_type = $fileinfo->file($filename); 
    // The function above also returns the charset, if you don't want that:
    $mime_type = reset(explode(";", $mime_type));
    // gets last element of an array

    header("Content-Type: $mime_type");
    header("Content-Length: ".filesize($filename));
    readfile($filename);
}

Используйте X-Sendfile и пусть веб-сервер обслуживает файл

// This was only tested with nginx

function send_file_using_x_sendfile($filename) {
    // Avoids hard to understand error-messages
    if (!file_exists($filename)) {
        throw RuntimeException("File $filename not found");
    }

    $fileinfo = new finfo(FILEINFO_MIME);
    $mime_type = $fileinfo->file($filename); 
    // The function above also returns the charset, if you don't want that:
    $mime_type = reset(explode(";", $mime_type));
    // gets last element of an array

    header("Content-Type: $mime_type");
    // The slash makes it absolute (to the document root of your server)
    // For apache and lighttp use:
    header("X-Sendfile: /$filename");
    // or for nginx: header("X-Accel-Redirect: /$filename");

}

Первая функция занимает один PHP-процесс / поток во время отправки данных и не поддерживает Range-Requests или другие расширенные HTTP-функции. Поэтому его следует использовать только с небольшими файлами или на очень маленьких сайтах.

Используя X-Sendfile, вы получаете все это, но вам нужно знать, какой веб-сервер работает, и, возможно, даже нужно изменить конфигурацию. Особенно при использовании lighttp или nginx это действительно окупается с точки зрения производительности, поскольку эти веб-серверы чрезвычайно хороши в обслуживании статических файлов с диска.

Обе функции поддерживают файлы, отсутствующие в корневом каталоге документов веб-сервера. В nginx есть так называемые «внутренние местоположения» (http://wiki.nginx.org/HttpCoreModule#internal). Они могут использоваться с X-Accel-Redirect -Header. Возможно даже регулирование скорости, взгляните на http://wiki.nginx.org/XSendfile.

Если вы используете apache, есть mod_xsendfile, который реализует функцию, необходимую для второй функции.

0 голосов
/ 26 августа 2011

Если render равен false, торт не будет отправлять заголовок.

Здесь вы можете положиться на обычный php.

PNG:

header('Content-Type: image/gif');
readfile('path/to/myimage.gif');

JPEG:

header('Content-Type: image/jpeg');
readfile('path/to/myimage.jpg');

PNG:

header('Content-Type: image/png');
readfile('path/to/myimage.png');
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...