Drupal 8 - 通过路由模块将文件发送到浏览器

时间:2016-03-09 18:10:44

标签: file module controller routes drupal-8

我有一个模块,在这个模块中,.routing.yml中应该有一个新路由:

path: '/file_exporter/{filename}'
defaults:
  _controller: '\Drupal\file_exporter\Controller\ExportController::file_export'

在ExportController中,发生了一些魔术,根据用户和其他情况创建了一个文件,这很好用,我把这个文件放在模块内的临时文件夹中。

但是我怎么能用drupal将它发送到浏览器?

目标ist,我在另一个站点上有一个链接到/fileexporter/file_123.xyz,点击此链接可以让浏览器直接下载新生成的file_123.xyz

是否有可以扩展的类,或者我可以在Drupal 8中使用的函数通过路由和控制器直接将文件发送到浏览器?

1 个答案:

答案 0 :(得分:0)

诀窍在于使用BinaryFileResponse

这是一个处理设置HTTP标头和内容类型并返回BinaryFileResponse的示例函数:

<?php
// $uri: the file you want to send, as a URI (e.g. private://somefile.txt)
// $ofilename: the output filename, this will be displayed in the browser.
// $contenttype: the mime content type for the browser
// $delete_after_send: delete the file once it's been sent to the browser

function mymodule_transfer_file($uri, $ofilename, $contenttype = NULL, $delete_after_send = FALSE) {

  $mime = \Drupal::service('file.mime_type.guesser')->guess($uri);

  $headers = array(
    'Content-Type' => $mime . '; name="' . Unicode::mimeHeaderEncode(basename($uri)) . '"',
    'Content-Length' => filesize($uri),
    'Content-Disposition' => 'attachment; filename="' . Unicode::mimeHeaderEncode($ofilename) . '"',
    'Cache-Control' => 'private',
  );

  if (isset($contenttype)) {
    $headers['Content-Type'] = $contenttype;
  }

  if ($delete_after_send) {
    // Delete after end of script.
    drupal_register_shutdown_function('file_unmanaged_delete', $uri);
  }

  $uri_obj = new Uri($uri);
  return new BinaryFileResponse($uri, 200, $headers, $uri_obj->getScheme() !== 'private');
}