简体   繁体   中英

Accessing response (output) headers in ZF2

Trying to output an image from a protected area using ZF2. In my action function I output the image data with a call to:

readfile($path);

In the browser this output is recognized as text and displayed starting with jpeg markers 'ÿØÿà...bla bla bla'. I'm assuming this is because Zend returned a 'text' content type in the HTTP header.

So then I tried to change the content type header with php command

header('Content-type: image/jpeg');

When I do this I get the following error:

Warning: Cannot modify header information - headers already sent by (output started at /Zend/module/Application/src/Application/Controller/ImagesController.php:84)

I looked extensively and found lots of documentation like this that seems to say I can do something like:

$this->getResponse()->setHeader('Content-Type', 'image/jpeg');

When I do that I get the message:

Fatal error: Call to undefined method Zend\Http\PhpEnvironment\Response::setHeader() in /Zend/module/Application/src/Application/Controller/ImagesController.php on line 39

Looking through the response object structure I don't see any link between Zend\\Http\\Headers and the Zend\\Http\\Response object or the Zend\\Http\\PhpEnvironment\\Response object so it is not surprising that php can't find the call to setHeader().

My question is how do I change the output header to make the borwser expect image data?

Here is my code in response to the first answer. It doesn't use a view since it is just outputting binary data:

    class ImagesController extends AbstractActionController {
    public function getfileAction() {
        $path = '/data/images/theImage.jpg';
        header('Content-type: image/png');
        //$this->getResponse()->setHeader('Content-Type:', 'image/jpeg');
        readfile($path);
        exit; }}

In response to Saeven's reply here is my exact implementation of your solution:

namespace Application\Controller;
use Zend\Mvc\Controller\AbstractActionController;
use Zend\Session\Container;
use Zend\View\Model\ViewModel;
use Zend\Http\Response;
use Zend\Http\Headers as Headers;

class ImagesController extends AbstractActionController {
    public function getfileAction() {
        $table = $this->getEvent()->getRouteMatch()->getParam('table');
        $fileName = $this->getEvent()->getRouteMatch()->getParam('filename');
        $path = '/datasm/apps/php/data/'.$table.'/'.$fileName;
        $imageData = file_get_contents($path);
        $response = $this->getResponse();
        $response->setContent($imageData);
        $response->getHeaders()->addHeaderLine('Content-Type', 'image/png');
        return $response;
    }
}

Here is a screen cap of my project showing that I don't have a corresponding view file for the getfileAction() 没有用于getFileAction的视图文件

Here is a screen cap of how I am testing using the browser and what is coming back from zend.

在浏览器上输出

regarding the version of zend I am using 2.2.5.

UPDATED:

$response
    ->getHeaders()
    ->addHeaderLine('Content-Transfer-Encoding', 'binary')
    ->addHeaderLine('Content-Type', 'image/png')
    ->addHeaderLine('Content-Length', mb_strlen($imageContent));

Original Answer :

this is what i used for a xml file :

$response = new \Zend\Http\Response();
$response->getHeaders()->addHeaderLine('Content-Type', 'text/xml; charset=utf-8');
$response->setContent($xml);
return $response;

Use the response, definitely. Can the call to header(), and use:

$response = $this->getResponse();
$response->setContent($imagedata);
$response
    ->getHeaders()
    ->addHeaderLine('Content-Type', 'image/png');
return $response;

Also, return the response to skip RENDER and FINISH dispatch events.

I think you should use a ImageModel (similiar to ViewModel) and ImageStrategy .

For example, from your controller,

$image =  new ImageModel();
$image->setFileName('my_file_name.png');
return $image;

You should create ImageStrategy (Custom View Strategy) and ImageModel (just extend ViewModel) by yourself.

I have sent a pull request to WebinoPhpThumb with the addition of ImageStrategy and ImageModel . You can view here

Update

I have created a module, HtImgModule which might help you. Read the docs here .

Make sure that the line:

header('Content-type: image/jpg');

is before any output. So make sure it is before the readfile($path); and make sure that you don't have any white space or invisible characters before your opening <?php tags.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM