使用 Symfony3 和 Flysystem 提供文件下载
Serving files for download with Symfony3 and Flysystem
简介
我正在使用:
- Windows 10 专业版
- XAMPP 与 PHP v7.0.9
- Symfony v3.1.6
- Doctrine v2.5.4
- StofDoctrineExtensionsBundle [1] 为了
管理树结构。
- OneupUploaderBundle [2] 用于上传文件
- OneupFlysystemBundle [3] 用于文件系统抽象
正在设置
我确实设置了树结构(代表目录和文件)并使用 OneupUploaderBundle
和 Flysystem
端点上传文件。
文件上传组织为上传到项目根文件夹中存在的名为data
的文件夹。上传工作正常,甚至不同上传工作的自定义子目录路径(例如 data/project_001/test1.txt
和 data/project_002/test2.txt
)!
问题
我需要提供用户之前上传的文件。
目前
我遇到错误(控制器以 1 结尾)
The file "Project_9999/2_Divi/bbb.pdf" does not exist
500 Internal Server Error - FileNotFoundException
和错误(控制器以 2 结尾)
Catchable Fatal Error: Object of class League\Flysystem\File could not be converted to string
500 Internal Server Error - ContextErrorException
请注意 $exists
return true
- 所以文件肯定存在!
代码
config.yml
的相关部分
oneup_uploader:
mappings:
gallery:
storage:
type: flysystem
filesystem: oneup_flysystem.gallery_filesystem
frontend: blueimp
enable_progress: true
namer: app.upload_unique_namer
allowed_mimetypes: [ image/png, image/jpg, image/jpeg, image/gif ]
max_size: 10485760s
oneup_flysystem:
adapters:
my_adapter:
local:
directory: "%kernel.root_dir%/../data"
filesystems:
gallery:
adapter: my_adapter
控制器动作
<?php
public function projectDownloadFileAction($file_id, Request $request)
{
$em = $this->getDoctrine()->getManager();
$repo = $em->getRepository('AppBundle:FileTree');
$ultra = $this->get('app.ultra_helpers');
$selected_file = $repo->getFileTreeNodeByIdArray($file_id);
$item_name = $selected_file[0]['item_name'];
$item_extension = $selected_file[0]['item_extension'];
$activeProject = $this->get('session')->get('active_project');
$activeProjectSelectedNodePath = $this->get('session')->get('active_project_selected_node_path');
$item_file_name = $item_name .'.'. $item_extension;
$complete_file_path = $activeProject['secret_path'] . $activeProjectSelectedNodePath .'/'. $item_file_name;
dump($complete_file_path);
ENDING -1-
ENDING -2-
}
结局 1
$downloadable_file = new \SplFileInfo($complete_file_path);
dump($downloadable_file);
$response = new BinaryFileResponse($downloadable_file);
// Set headers
$response->headers->set('Cache-Control', 'private');
$response->headers->set('Content-Type', mime_content_type($downloadable_file));
$response->headers->set('Content-Disposition', $response->headers->makeDisposition(
ResponseHeaderBag::DISPOSITION_ATTACHMENT,
$downloadable_file->getFilename()
));
return $response;
结局 2
$filesystem = $this->get('oneup_flysystem.gallery_filesystem');
$exists = $filesystem->has($complete_file_path);
if (!$exists)
{
throw $this->createNotFoundException();
}
dump($exists);
$downloadable_file = $filesystem->get($complete_file_path);
dump($downloadable_file);
$response = new BinaryFileResponse($complete_file_path);
$response->trustXSendfileTypeHeader();
$response->setContentDisposition(ResponseHeaderBag::DISPOSITION_ATTACHMENT);
return $response;
更新 1
我试图提供 Ending 1
变量 `$complete_file_path 的绝对路径,但只有错误。例如:
File not found at path: C:\DEV\tree_and_upload\data\Project_9999_Viens\test1.txt
500 Internal Server Error - FileNotFoundException
File not found at path: C:/DEV/tree_and_upload/data/Project_9999/1_Viens/test1.txt
500 Internal Server Error - FileNotFoundException
但这没有任何区别 - 我遇到了访问错误。也许 Symfony 正在积极限制对项目根目录中 data
文件夹的访问...
问题
如何提供位于项目根文件夹中的 data
文件夹中的文件,并使用 Flysystem
文件系统抽象层和 Local
适配器?
结论
我错过了什么?
请指教
感谢您的时间和知识。
因为 Flysystem
和 local adapter
没有获取可下载文件路径的方法! It is suggested 在 public web
文件夹中移动或存储文件,并以与资产相同的方式检索路径。
我最终使用 StreamedResponse
[1] 而不是 BinaryFileResponse
。
use Symfony\Component\HttpFoundation\StreamedResponse;
$response = new StreamedResponse();
$response->setCallback(function () {
echo $downloadable_file_stream_contents;
flush();
});
$response->send();
How do you get $downloadable_file_stream_contents;
$fs = new Filesystem($localAdapter);
$downloadable_file_stream = $fs->readStream($public_path);
$downloadable_file_stream_contents = stream_get_contents($downloadable_file_stream);
简介
我正在使用:
- Windows 10 专业版
- XAMPP 与 PHP v7.0.9
- Symfony v3.1.6
- Doctrine v2.5.4
- StofDoctrineExtensionsBundle [1] 为了 管理树结构。
- OneupUploaderBundle [2] 用于上传文件
- OneupFlysystemBundle [3] 用于文件系统抽象
正在设置
我确实设置了树结构(代表目录和文件)并使用 OneupUploaderBundle
和 Flysystem
端点上传文件。
文件上传组织为上传到项目根文件夹中存在的名为data
的文件夹。上传工作正常,甚至不同上传工作的自定义子目录路径(例如 data/project_001/test1.txt
和 data/project_002/test2.txt
)!
问题
我需要提供用户之前上传的文件。
目前
我遇到错误(控制器以 1 结尾)
The file "Project_9999/2_Divi/bbb.pdf" does not exist 500 Internal Server Error - FileNotFoundException
和错误(控制器以 2 结尾)
Catchable Fatal Error: Object of class League\Flysystem\File could not be converted to string 500 Internal Server Error - ContextErrorException
请注意 $exists
return true
- 所以文件肯定存在!
代码
config.yml
的相关部分oneup_uploader:
mappings:
gallery:
storage:
type: flysystem
filesystem: oneup_flysystem.gallery_filesystem
frontend: blueimp
enable_progress: true
namer: app.upload_unique_namer
allowed_mimetypes: [ image/png, image/jpg, image/jpeg, image/gif ]
max_size: 10485760s
oneup_flysystem:
adapters:
my_adapter:
local:
directory: "%kernel.root_dir%/../data"
filesystems:
gallery:
adapter: my_adapter
控制器动作
<?php
public function projectDownloadFileAction($file_id, Request $request)
{
$em = $this->getDoctrine()->getManager();
$repo = $em->getRepository('AppBundle:FileTree');
$ultra = $this->get('app.ultra_helpers');
$selected_file = $repo->getFileTreeNodeByIdArray($file_id);
$item_name = $selected_file[0]['item_name'];
$item_extension = $selected_file[0]['item_extension'];
$activeProject = $this->get('session')->get('active_project');
$activeProjectSelectedNodePath = $this->get('session')->get('active_project_selected_node_path');
$item_file_name = $item_name .'.'. $item_extension;
$complete_file_path = $activeProject['secret_path'] . $activeProjectSelectedNodePath .'/'. $item_file_name;
dump($complete_file_path);
ENDING -1-
ENDING -2-
}
结局 1
$downloadable_file = new \SplFileInfo($complete_file_path);
dump($downloadable_file);
$response = new BinaryFileResponse($downloadable_file);
// Set headers
$response->headers->set('Cache-Control', 'private');
$response->headers->set('Content-Type', mime_content_type($downloadable_file));
$response->headers->set('Content-Disposition', $response->headers->makeDisposition(
ResponseHeaderBag::DISPOSITION_ATTACHMENT,
$downloadable_file->getFilename()
));
return $response;
结局 2
$filesystem = $this->get('oneup_flysystem.gallery_filesystem');
$exists = $filesystem->has($complete_file_path);
if (!$exists)
{
throw $this->createNotFoundException();
}
dump($exists);
$downloadable_file = $filesystem->get($complete_file_path);
dump($downloadable_file);
$response = new BinaryFileResponse($complete_file_path);
$response->trustXSendfileTypeHeader();
$response->setContentDisposition(ResponseHeaderBag::DISPOSITION_ATTACHMENT);
return $response;
更新 1
我试图提供 Ending 1
变量 `$complete_file_path 的绝对路径,但只有错误。例如:
File not found at path: C:\DEV\tree_and_upload\data\Project_9999_Viens\test1.txt 500 Internal Server Error - FileNotFoundException
File not found at path: C:/DEV/tree_and_upload/data/Project_9999/1_Viens/test1.txt 500 Internal Server Error - FileNotFoundException
但这没有任何区别 - 我遇到了访问错误。也许 Symfony 正在积极限制对项目根目录中 data
文件夹的访问...
问题
如何提供位于项目根文件夹中的 data
文件夹中的文件,并使用 Flysystem
文件系统抽象层和 Local
适配器?
结论
我错过了什么?
请指教
感谢您的时间和知识。
因为 Flysystem
和 local adapter
没有获取可下载文件路径的方法! It is suggested 在 public web
文件夹中移动或存储文件,并以与资产相同的方式检索路径。
我最终使用 StreamedResponse
[1] 而不是 BinaryFileResponse
。
use Symfony\Component\HttpFoundation\StreamedResponse;
$response = new StreamedResponse();
$response->setCallback(function () {
echo $downloadable_file_stream_contents;
flush();
});
$response->send();
How do you get $downloadable_file_stream_contents;
$fs = new Filesystem($localAdapter);
$downloadable_file_stream = $fs->readStream($public_path);
$downloadable_file_stream_contents = stream_get_contents($downloadable_file_stream);