问题描述
我有一个动态生成的QR码PNG。我可以通过访问www.example.com/events/qrgen
来访问它,这将使其正确显示在浏览器中。
// this action displays a QR code in the browser
public function qrgen() {
$this->layout = false;
$this->response->type('image/png');
}
// this action SHOULD make the png download
public function download_qrgen() {
$qrUrl = Router::url(['controller'=>'events','action'=>'qrgen']);
$this->response->file($qrUrl,['download'=>true,'name'=>'qr']);
return $this->response;
}
// in the "qrgen" view
QRcode::png('example value',null,"M",4,4);
但是当我访问www.example.com/events/download_qrgen
时,出现错误“找不到该页面”,并将CakeResponse->file(string,array)
的值显示为:/var/www/example.com//events/qrgen
。
如果我尝试在Webroot中尝试下载文件,它将正确下载该文件。但是我似乎无法下载这样的动态生成的png。
解决方法
CakeResponse::file()
需要传递给它的文件系统路径,而不是URL,它不会发出任何HTTP请求来获取数据。
您必须自己获取数据,然后将其缓冲在一个临时文件中,该文件的路径可以在文件系统中传递给CakeResponse::file()
:
public function download_qrgen() {
$this->layout = false;
$qrcodeData = $this->_getViewObject()->render('qrgen');
$temp = tmpfile();
fwrite($temp,$qrcodeData);
$filePath = stream_get_meta_data($temp)['uri'];
$this->response->file($filePath,['download' => true,'name' => 'qr.png']);
return $this->response;
}
或者您自己准备包含数据和标头的响应:
public function download_qrgen() {
$this->layout = false;
$qrcodeData = $this->_getViewObject()->render('qrgen');
$this->response->type('image/png');
$this->response->download('qr.png');
$this->response->length(strlen($qrcodeData));
$this->response->header('Content-Transfer-Encoding','binary');
$this->response->body($qrcodeData);
return $this->response;
}
另请参见