我想从Symfony的服务加载我自己的敏感文件.我对Symfony文档中的所有内容感到困惑.默认情况下,我只能访问放在我的/web
文件夹中的文件.
但如果我是对的,这个文件夹是公开的.所以我想将我的文件移动到/src/AppBundle/Resources/myfile.txt
以下是我读过的几个链接,但没有找到任何明确的内容.
http://symfony.com/doc/current/components/config/resources.html
http://symfony.com/doc/current/components/finder.html
http://symfony.com/doc/current/cookbook/configuration/override_dir_structure.html
Symfony2:访问Web外部文件夹中的文件
我应该使用__DIR__
声明吗?
如果可能,我有2个目标要实现:
访问具有项目相对路径的文件(例如AppBundle或'www'文件夹)
访问文件/random/place/on/my/server
而不暴露整个路径.
最后一件事要补充; 没有办法在web文件夹中复制我的文件,有超过10Gb的文件可供访问,所以没有缓存,没有复制,只是一个简单的访问.
您可以使用以下代码在Symfony中提供文件:
$response = new BinaryFileResponse($filepath); // Set headers $response->headers->set('Cache-Control', 'private'); $response->headers->set('Content-Type', $file->getMimeType()); $response->headers->set('Content-Disposition', $response->headers->makeDisposition( ResponseHeaderBag::DISPOSITION_ATTACHMENT, $file->getName() )); return $response;
确保你还有:
use Symfony\Component\HttpFoundation\ResponseHeaderBag; use Symfony\Component\HttpFoundation\BinaryFileResponse;
如何获取$file
在您链接的Finder组件的文档中进行了解释.当您将代码放在AppBundle中的控制器中时,您可以使用:
$filepath = __DIR__ . '/../Resources/myfile.txt';
或者,您可以使用相对于应用程序根目录的路径:
$rootDir = $this->get('kernel')->getRootDir(); $filepath = $rootDir. '/src/AppBundle/Resources/myfile.txt';
$filepath
也可以是绝对路径,但要确保网络服务器可以从该路径读取.只要您使用webservers docroot(可能是
)之外的路径,就可以使用PHP中的选民和其他自定义逻辑来控制对文件的访问.
获取$ file对象:
为了构建你的文件对象,你可以使用Finder组件,但这实际上只不过是一个围绕SPL文件处理的包装器.因此你也可以使用:
$file = new \SplFileInfo($filepath);
为什么选择BinaryFileResponse?
发送大文件时,PHP可能会将整个文件读入内存,然后再将其作为响应发送给客户端.这可能会导致PHP内存不足.使用BinaryFileResponse
通过逐块读取文件并将这些块流式传输到客户端来避免这种情况.因此,永远不要使用Response
对象发送大文件.
使用X-Sendfile:
虽然使用上面的代码可以防止PHP耗尽内存,但在发送文件时仍然会使PHP忙碌.如果您有一个繁忙的Web服务器,您可能希望尽可能多地保留PHP进程来呈现网页,而不是流式文件.
Luckely,而不是这个:
Request ----> Webserver ----> PHP-FPM ----> File Response <--- Webserver <---- PHP-FPM <---- File
你可以这样做:
Request ----> Webserver ----> PHP-FPM Response <--- Webserver <---- PHP-FPM ^ | | | | V File
这是通过使用X-Sendfile完成的.
这是邪恶的,我该怎么用呢?
获取X-Sendfile
工作需要两个简单的步骤:
在响应中添加一个标题,告诉您的Web服务器它应该为文件服务.
配置您的Web服务器以读取该标头并实际服务该文件.
标题的名称以及Web服务器的配置方式取决于您使用的Web服务器的类型:
在Apache中,您需要一个特殊的模块
Nginx的信息
请注意,Nginx将其称为X-Accel.传递给Nginx的标题X-Accel-Redirect
是唯一的区别.