我正在使用带有extbase和流体的Typo3。我有一个名为downloadAction()
的动作控制器。调用该操作后,系统会尝试呈现下载模板(但我只是想开始下载)。
public function downloadAction($id) {
// create file
// send header
// dump file
// exit
}
如何转储创建的download-File
并发送下载标头而不是正常的渲染过程?什么是最好的方式?
由于
答案 0 :(得分:10)
几个月前我在一个项目中做到了这一点,这很简单。
/**
* @param string $fileName
* @return void
*/
public function downloadAction($fileName) {
$file = $this->settings['uploadFolder'] . 'uploadedPhotos/' . $fileName;
if(is_file($file)) {
$fileLen = filesize($file);
$ext = strtolower(substr(strrchr($fileName, '.'), 1));
switch($ext) {
case 'txt':
$cType = 'text/plain';
break;
case 'pdf':
$cType = 'application/pdf';
break;
case 'exe':
$cType = 'application/octet-stream';
break;
case 'zip':
$cType = 'application/zip';
break;
case 'doc':
$cType = 'application/msword';
break;
case 'xls':
$cType = 'application/vnd.ms-excel';
break;
case 'ppt':
$cType = 'application/vnd.ms-powerpoint';
break;
case 'gif':
$cType = 'image/gif';
break;
case 'png':
$cType = 'image/png';
break;
case 'jpeg':
case 'jpg':
$cType = 'image/jpg';
break;
case 'mp3':
$cType = 'audio/mpeg';
break;
case 'wav':
$cType = 'audio/x-wav';
break;
case 'mpeg':
case 'mpg':
case 'mpe':
$cType = 'video/mpeg';
break;
case 'mov':
$cType = 'video/quicktime';
break;
case 'avi':
$cType = 'video/x-msvideo';
break;
//forbidden filetypes
case 'inc':
case 'conf':
case 'sql':
case 'cgi':
case 'htaccess':
case 'php':
case 'php3':
case 'php4':
case 'php5':
exit;
default:
$cType = 'application/force-download';
break;
}
$headers = array(
'Pragma' => 'public',
'Expires' => 0,
'Cache-Control' => 'must-revalidate, post-check=0, pre-check=0',
'Content-Description' => 'File Transfer',
'Content-Type' => $cType,
'Content-Disposition' => 'attachment; filename="'. $fileName .'"',
'Content-Transfer-Encoding' => 'binary',
'Content-Length' => $fileLen
);
foreach($headers as $header => $data)
$this->response->setHeader($header, $data);
$this->response->sendHeaders();
@readfile($file);
}
exit;
}
答案 1 :(得分:4)
您可以为下载请求定义特殊的PageType:
download = PAGE
download {
typeNum = 1249058993
10 < tt_content.list.20.efempty_pi1
config {
disableAllHeaderCode = 1
xhtml_cleaning = 0
admPanel = 0
additionalHeaders = Content-type:application/octet-stream
}
}
}
“efempty”必须替换为您的分机名称。
您现在可以像这样触发下载:
<f:link.action pageType="1249058993" action="download" controller="ControllerName">Download</f:link.action>
答案 2 :(得分:1)
<强>更新强>: 这实际上不适用于激活压缩,因为Content-Length仍然代表未压缩的大小。 eID可以用作解决方法,事实上甚至有一个官方要求:
eID =&#34; dumpFile&#34;请参阅typo3 / sysext / core / Resource / PHP / FileDumpEID.php
然而,此次通话不会强行下载,而是“#&#34; dump&#34;它。我已经为@ Forge制作了一张票来解决这个问题(已经被接受并且针对LTS 7):https://forge.typo3.org/issues/67111
旧答案: 至于现在,最简单的方法是:
# ASCII "download" in Numbers (4-15-23-14-12-15-1-4) - See http://rumkin.com/tools/cipher/numbers.php
plugin.tx_extensionname.view.formatToPageTypeMapping.download = 4152314121514
tx_extensionname_download = PAGE
tx_extensionname_download {
typeNum < plugin.tx_extensionname.view.formatToPageTypeMapping.download
config {
disableAllHeaderCode = 1
xhtml_cleaning = 0
admPanel = 0
debug = 0
no_cache = 1
}
10 = USER
10 {
userFunc = TYPO3\CMS\Extbase\Core\Bootstrap->run
extensionName = ExtensionName
pluginName = PluginName
vendorName = VENDOR
controller = ControllerName
action = download
view < plugin.tx_extensionname.view
persistence < plugin.tx_extensionname.persistence
settings < plugin.tx_extensionname.settings
}
}
/**
* Download
*
* @param \VENDOR\ExtensionName\Domain\Model\Model $model
* @return void
* @ignorevalidation $model
*/
public function downloadAction($model) {
if ($model->getFile()) {
$model->getFile()->getOriginalResource()->getOriginalFile()->getStorage()->dumpFileContents(
$model->getFile()->getOriginalResource(),
$asDownload = TRUE,
$alternativeFilename = $model->getFile()->getOriginalResource()->getName()
);
exit;
}
$this->throwStatus(
$statusCode = 404,
$statusMessage = 'Not Found'
);
}
<f:link.action controller="ControllerName" pluginName="PluginName" action="download" arguments="{model: '{model.uid}'}" format="download" title="{model.file.originalResource.title}">Download</f:link.action>
与其他提到的答案相比的好处如下:
附注:iPhone忽略Content-Disposition标题(始终内联)
关于&#34;退出&#34;关注我没有测试它,但如果您使用自己的PHPView(StandaloneView?),它可能会有页面类型。
答案 3 :(得分:0)
如何转储创建的download-File并发送下载头而不是正常的渲染过程?
只要headers haven't already been sent,就没有什么可以阻止您发送标题,发送内容并实际调用exit
,但您可能希望check for output buffering和{{3在这之前。您可能还想clear any open buffers。