有没有办法让Codeigniter控制器返回一张图片?

11

我想知道是否有一种方法,可以让控制器返回图像(无论是JPG、PNG等),而不是字符串或视图。例如,我想通过$this->load->image('images/gorilla.png')这样的方式结束,而不是使用$this->load->view('folder/special_view.php'),这样如果我的用户访问该控制器,他们将看到一个像普通.png或.jpeg一样的图像。我能否设置头文件以期望不同的MIME?如果有示例代码,那就太好了。

我需要这个功能的原因很长,但它涉及将预先制作的CMS引入codeigniter,并使其需要满足某些条件。非常感谢!

7个回答

27

你肯定可以,使用这个来代替 $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()
}

我正在使用Codeigniter的当前版本。这段代码对我来说无效。 - Ammar Hayder Khan
3
我猜exit命令没有用处,因为die命令终止脚本,它们都能完成同样的工作。顺便感谢您提供的代码。 - Márton Tamás

12

我并不想进行攀比,但是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-type 以使用其他图像类型

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

返回图片

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

就像 $this->load->view 一样,将第三个参数设置为 TRUE 意味着它将返回而不是直接输出。

希望这可以帮助你 :-)


该库必须位于application/core/MY_Loader.php中。 - Gaurav Gupta
@GauravGupta 是的,如果您正在使用2.0或更高版本,则需要将其放在core/而不是libraries/中。 2009年不存在2.0。 :) - Phil Sturgeon

11

使用自动 MIME 类型更容易的方式。

$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));

1
如果符合您的使用情况,直接重定向到它就可以了。例如,使用图像进行跟踪就像这样:
// Do your logic here

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

无需更改标题。您的用例可能不适用于此,但其他人可能会发现这很有用 ^_^


1

关于Phil的代码:

在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();

两种情况下,您从源获取的图像与输出中获取的图像相同。

但对我来说,我更喜欢核心库的扩展 :-)

非常感谢您,Phil。


我从未注意到通用文件加载器。我正在查看CodeIgniter的代码...感谢您指出这一点...使用Codeigniter的最佳功能... :) - user370029
我注意到的另一件事是,在内部,load函数调用了include函数...根据php手册,如果用于处理,应该使用include...而应该使用readfile函数...因此,我们可以使用File helper中提供的readfile函数! - user370029

1

即使您将$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);
}

1

我会做一个

$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));

如果这有帮助的话。干杯!

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接