可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
I was wondering if there was a way for a controller to, instead of returning a string, or a view, return an image (be it JPG, PNG etc). For example, instead of ending with a $this->load->view('folder/special_view.php), I'd like to do something like $this->load->image('images/gorilla.png'), and have it so if my user were to go to that controller they would see an image as if they'd gone to a normal .png or jpeg. Can I set the headers so it expects a different MIME? Example code of this would be fantastic.
It would take forever for me to explain why I need this, but it involves bringing a premade CMS into codeigniter, and having it need certian things to be true. Thank you so much!
回答1:
sure you can, use this instead of $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
die(); //<--cleanup
exit; //and exit
}
回答2:
This is not intended as One-upmanship, but pǝlɐɥʞ's suggestion is a pure PHP implementation that is not all that re-usable. You wanted to use the syntax $this->load->image('images/gorilla.png') so here is how you can.
Create /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
}
There are a few ways you can use this:
Basic output (default is jpeg)
$this->load->image('/path/to/images/gorilla.png');
Send mime-type to use other image types
$this->load->image('/path/to/images/gorilla.jpg', 'image/jpeg');
Return the image
$image = $this->load->image('/path/to/images/gorilla.php', TRUE);
Just like $this->load->view, the 3rd parameter being set to TRUE means it will return instead of directly outputting.
Hope this helps :-)
回答3:
An easier way with automatic mime-type.
$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));
回答4:
About the Phil's code:
In CodeIgniter 2.0, today, there are a one change that have to be made in order to make it work:
- The library has to be in /application/core/MY_Loader.php
I like to remark a small typo about the library's explanation:
- There is a mistake in the header "Basic output (default is jpeg)" because in fact the default is .png
Another solutions to the problem are:
I've made a small code to make it work with the core codeIgniter libraries:
$this->output->set_header("Content-Type: image/png");
$this->load->file('../images/example.png');
Or using the Image Manipulation Library
$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();
In both cases you get the same image you get from the source but in the output.
But for me, I liked more the extension to the core library :-)
Thank you very much Phil.
回答5:
If it fits your use case, simply redirecting to it is just fine. For example, tracking using images would be like:
// Do your logic here
redirect($image_path); // Or PHP's header location function
No need to change headers. Your use case may not fit this, but someone might find this useful ^_^
回答6:
I would do a
$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));
If this helps. Cheers!
回答7:
This method works even if you have $config['compress_output'] set to 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);
}