Есть ли способ заставить контроллер Codeigniter вернуть изображение?

Мне было интересно, есть ли у контроллера способ вместо возврата строки или представления возвращать изображение (будь то JPG, PNG и т. д.). Например, вместо того, чтобы заканчиваться $this->load->view('folder/special_view.php), я бы хотел сделать что-то вроде $this->load->image('images/gorilla.png') , и пусть мой пользователь перейдет к этому контроллеру, он увидит изображение, как если бы он перешел к обычному .png или jpeg. Могу ли я установить заголовки, чтобы он ожидал другого MIME? Пример кода этого был бы фантастическим.

Мне потребовалась бы целая вечность, чтобы объяснить, зачем мне это нужно, но это включает в себя добавление готовой CMS в codeigniter и необходимость в определенных вещах, чтобы быть правдой. Большое спасибо!


person Ethan    schedule 15.12.2009    source источник


Ответы (7)


конечно можешь, используй это вместо $this->load->view()

$filename="/path/to/file.jpg"; //<-- specify the image  file
if(file_exists($filename)){ 
  $mime = mime_content_type($filename); //<-- detect file type
  header('Content-Length: '.filesize($filename)); //<-- sends filesize header
  header("Content-Type: $mime"); //<-- send mime-type header
  header('Content-Disposition: inline; filename="'.$filename.'";'); //<-- sends filename header
  readfile($filename); //<--reads and outputs the file onto the output buffer
  exit(); // or die()
}
person ekhaled    schedule 15.12.2009
comment
Я работаю над текущей версией Codeigniter. этот код у меня не работает - person Ammar Hayder Khan; 29.05.2014
comment
Я предполагаю, что команда exit не имеет смысла, так как die завершает скрипт, и они все равно выполняют ту же работу. Кстати, спасибо за код. - person Márton Tamás; 21.12.2017

Это не предназначено для превосходства, но предложение pǝlɐɥʞ представляет собой чистую реализацию PHP, которую нельзя использовать повторно. Вы хотели использовать синтаксис $this->load->image('images/gorilla.png'), так что вот как вы можете это сделать.

Создайте /application/libraries/MY_Loader.php

<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');

/**
 * Loader Class
 *
 * Loads views and files
 *
 * @package     CodeIgniter
 * @subpackage  Libraries
 * @author      Phil Sturgeon
 * @category    Loader
 * @link        http://codeigniter.com/user_guide/libraries/loader.html
 */
class MY_Loader extends CI_Loader {

    function image($file_path, $mime_type_or_return = 'image/png')
    {
        $this->helper('file');

        $image_content = read_file($file_path);

        // Image was not found
        if($image_content === FALSE)
        {
            show_error('Image "'.$file_path.'" could not be found.');
            return FALSE;
        }

        // Return the image or output it?
        if($mime_type_or_return === TRUE)
        {
            return $image_content;
        }

        header('Content-Length: '.strlen($image_content)); // sends filesize header
        header('Content-Type: '.$mime_type_or_return); // send mime-type header
        header('Content-Disposition: inline; filename="'.basename($file_path).'";'); // sends filename header
        exit($image_content); // reads and outputs the file onto the output buffer
    }

Есть несколько способов использовать это:

Основной формат вывода (по умолчанию — jpeg)

$this->load->image('/path/to/images/gorilla.png');

Отправить MIME-тип, чтобы использовать другие типы изображений

$this->load->image('/path/to/images/gorilla.jpg', 'image/jpeg');

Вернуть изображение

$image = $this->load->image('/path/to/images/gorilla.php', TRUE);

Так же, как $this->load->view, третий параметр, установленный в TRUE, означает, что он будет возвращаться вместо прямого вывода.

Надеюсь это поможет :-)

person Phil Sturgeon    schedule 16.12.2009
comment
Библиотека должна находиться в application/core/MY_Loader.php - person Gaurav Gupta; 16.04.2014
comment
@GauravGupta да, если вы используете 2.0 или более позднюю версию, она должна быть в core/, а не в libraries/. 2.0 не существовало в 2009. :) - person Phil Sturgeon; 16.04.2014

Более простой способ с автоматическим мим-типом.

$this->load->helper('file');

$image_path = '/path/to/image/file';

$this->output->set_content_type(get_mime_by_extension($image_path));
$this->output->set_output(file_get_contents($image_path));
person Shiva127    schedule 11.10.2012

О кодексе Фила:

Сегодня в CodeIgniter 2.0 есть одно изменение, которое необходимо сделать, чтобы оно заработало:

  • Библиотека должна находиться в /application/core/MY_Loader.php

Мне нравится замечать небольшую опечатку в объяснении библиотеки:

  • В шапке ошибка "Базовый вывод (по умолчанию jpeg)" потому что на самом деле по умолчанию .png

Другие решения проблемы:

Я сделал небольшой код, чтобы заставить его работать с основными библиотеками codeIgniter:

    $this->output->set_header("Content-Type: image/png");
    $this->load->file('../images/example.png');

Или с помощью библиотеки обработки изображений

    $config['image_library'] = "GD2";
    $config['source_image'] = "../images/example.png";
    $config['maintain_ratio'] = TRUE;
    $config['dynamic_output'] = TRUE;

    $this->load->library('image_lib', $config);
    $image = $this->image_lib->resize();

В обоих случаях вы получаете то же изображение, что и из источника, но на выходе.

Но мне больше понравилось расширение к основной библиотеке :-)

Большое спасибо, Фил.

person Eduardo Inza    schedule 10.02.2011
comment
Я никогда не замечал общий загрузчик файлов. Я просматривал код CodeIgniter... Спасибо, что указали на это.. Используя лучшее из codeigniter... :) - person ; 25.09.2011
comment
Ну, еще одна вещь, которую я отметил, заключалась в том, что внутренне функция загрузки вызывает функцию включения... согласно руководству по php, следует использовать включение, если оно используется для обработки... вместо этого следует использовать функцию чтения файла... поэтому мы можем использовать Функция readfile предоставляется в помощнике по работе с файлами! - person ; 25.09.2011

Этот метод работает, даже если для параметра $config['compress_output'] установлено значение TRUE.

$filename="/path/to/file.jpg"; //<-- specify the image  file
if(file_exists($filename)){ 
  header('Content-Length: '.filesize($filename])); //<-- sends filesize header
  header('Content-Type: image/jpg'); //<-- send mime-type header
  header('Content-Disposition: inline; filename="'.$filename.'";'); //<-- sends filename     header
  $jpg = file_get_contents($filename); 
  $this->output->set_output($jpg);
}
person JohnWright    schedule 07.02.2012

Если это соответствует вашему варианту использования, просто перенаправить на него просто отлично. Например, отслеживание с использованием изображений будет выглядеть так:

// Do your logic here

redirect($image_path); // Or PHP's header location function

Не нужно менять заголовки. Ваш вариант использования может не соответствовать этому, но кому-то это может пригодиться ^_^

person Ryan Thompson    schedule 13.03.2012

я бы сделал

$computedImage = 'path/to/the/image.ext';
$this->load->helper('file');
$this->output->set_content_type(get_mime_by_extension($computedImage))->set_output(file_get_contents($computedImage));

Если это поможет. Ваше здоровье!

person foxybagga    schedule 06.12.2012