【问题标题】:Accessing response (output) headers in ZF2在 ZF2 中访问响应(输出)标头
【发布时间】:2015-01-09 16:48:37
【问题描述】:

尝试使用 ZF2 从受保护区域输出图像。在我的动作函数中,我通过调用来输出图像数据:

readfile($path);

在浏览器中,此输出被识别为文本并以 jpeg 标记“ÿØÿà...bla bla bla”开始显示。我假设这是因为 Zend 在 HTTP 标头中返回了“文本”内容类型。

然后我尝试使用 php 命令更改内容类型标头

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

当我这样做时,我收到以下错误:

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

我进行了广泛的查看,发现了很多像 this 这样的文档,似乎说我可以做这样的事情:

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

当我这样做时,我会收到消息:

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

查看响应对象结构,我看不到 Zend\Http\Headers 和 Zend\Http\Response 对象或 Zend\Http\PhpEnvironment\Response 对象之间的任何链接,所以 php 不能找到对 setHeader() 的调用。

我的问题是如何更改输出标题以使浏览器期望图像数据?

这是我响应第一个答案的代码。它不使用视图,因为它只是输出二进制数据:

    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; }}

作为对 Saeven 的回复,这里是我对您的解决方案的确切实施:

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;
    }
}

这是我的项目的屏幕截图,显示我没有 getfileAction() 的相应视图文件

这是我如何使用浏览器进行测试以及从 zend 返回的内容的屏幕截图。

关于 zend 的版本,我使用的是 2.2.5。

【问题讨论】:

  • 附注,在控制器中你可以使用 $this->params('table') 或 $this->params()->fromRoute('table')

标签: php zend-framework2


【解决方案1】:

更新:

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

原答案:

这是我用于 xml 文件的内容:

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

【讨论】:

  • 谢谢。这确实更改了返回的标题,这解决了我原来的问题,但仍然没有更改我的数据以显示为图像。我还为 content-length 添加了一个标头,因为它将该值设置为 1。当我使用 filesize($path) 设置长度时,它返回所有图像数据,但作为字符串。换句话说,它没有返回二进制数据,而是我的二进制数据转换为字符串数据。所以现在看来​​我在使用 $imageData = file_get_contents($path) 读取图像并使用 $response->setContent($imageData) 设置它的部分遇到了问题。
  • 试试这个:$response ->getHeaders() ->addHeaderLine('Content-Transfer-Encoding', 'binary') ->addHeaderLine('Content-Type', 'image/png') ->addHeaderLine('Content-Length', mb_strlen($imageContent));
【解决方案2】:

一定要使用响应。能否调用header(),并使用:

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

另外,返回响应以跳过 RENDER 和 FINISH 调度事件。

【讨论】:

  • 我试过这个但它没有改变我验证的标题仍然是 Content-Type: text/html; charset=UTF-8
  • 您是否返回了响应而不是依赖默认的 ViewModel?我已经像面包和黄油一样使用了这种策略。你用的是什么版本的 ZF2?
  • >面包和黄油。是的,应该很容易同意。我在上面添加了很多细节,应该可以回答你的问题。 Zend 框架版本是 2.2.5
【解决方案3】:

我认为你应该使用ImageModel(类似于ViewModel)和ImageStrategy

例如,从您的控制器中,

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

你应该自己创建ImageStrategy(自定义视图策略)和ImageModel(只是扩展ViewModel)。

我已经向WebinoPhpThumb 发送了一个拉取请求,并添加了ImageStrategyImageModel。可以查看here

更新

我创建了一个模块,HtImgModule,它可能会对您有所帮助。阅读文档here

【讨论】:

【解决方案4】:

确保该行:

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

在任何输出之前。因此,请确保它位于 readfile($path); 之前,并确保在打开 <?php 标记之前没有任何空格或不可见字符。

【讨论】:

  • 感谢您的回复。我在上面添加了我的控制器代码,以向您展示到底发生了什么。它仍然返回调用未定义方法错误。
  • @smDeveloper 这肯定与在调用header('Content-type: image/png'); 之前发送的一些输出有关。我不认为 Zend 在调用您的操作之前会发送任何输出,因此在文件开头的 <?php 之前必须有一些空格。它可能在ImagesController 文件或您的前端控制器中。它不太可能在其他地方。
  • 在使用像 zend 这样的框架时,像这样更改标题并不是一个好主意,它提供了正确的方式来做这件事
猜你喜欢
  • 2013-02-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多