我想从Symfony的服务加载我自己的敏感文件.我对Symfony文档中的所有内容感到困惑.默认情况下,我只能访问放在我的/web文件夹中的文件.
但如果我是对的,这个文件夹是公开的.所以我想将我的文件移动到/src/AppBundle/Resources/myfile.txt
以下是我读过的几个链接,但没有找到任何明确的内容.
我应该使用__DIR__声明吗?
如果可能,我有2个目标要实现:
/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;
Run Code Online (Sandbox Code Playgroud)
确保你还有:
use Symfony\Component\HttpFoundation\ResponseHeaderBag;
use Symfony\Component\HttpFoundation\BinaryFileResponse;
Run Code Online (Sandbox Code Playgroud)
如何获取$file在您链接的Finder组件的文档中进行了解释.当您将代码放在AppBundle中的控制器中时,您可以使用:
$filepath = __DIR__ . '/../Resources/myfile.txt';
Run Code Online (Sandbox Code Playgroud)
或者,您可以使用相对于应用程序根目录的路径:
$rootDir = $this->get('kernel')->getRootDir();
$filepath = $rootDir. '/src/AppBundle/Resources/myfile.txt';
Run Code Online (Sandbox Code Playgroud)
$filepath也可以是绝对路径,但要确保网络服务器可以从该路径读取.只要您使用webservers docroot(可能是<your app root>/web)之外的路径,就可以使用PHP中的选民和其他自定义逻辑来控制对文件的访问.
获取$ file对象:
为了构建你的文件对象,你可以使用Finder组件,但这实际上只不过是一个围绕SPL文件处理的包装器.因此你也可以使用:
$file = new \SplFileInfo($filepath);
Run Code Online (Sandbox Code Playgroud)
为什么选择BinaryFileResponse?
发送大文件时,PHP可能会将整个文件读入内存,然后再将其作为响应发送给客户端.这可能会导致PHP内存不足.使用BinaryFileResponse通过逐块读取文件并将这些块流式传输到客户端来避免这种情况.因此,永远不要使用Response对象发送大文件.
使用X-Sendfile:
虽然使用上面的代码可以防止PHP耗尽内存,但在发送文件时仍然会使PHP忙碌.如果您有一个繁忙的Web服务器,您可能希望尽可能多地保留PHP进程来呈现网页,而不是流式文件.
Luckely,而不是这个:
Request ----> Webserver ----> PHP-FPM ----> File
Response <--- Webserver <---- PHP-FPM <---- File
Run Code Online (Sandbox Code Playgroud)
你可以这样做:
Request ----> Webserver ----> PHP-FPM
Response <--- Webserver <---- PHP-FPM
^ |
| |
| V
File
Run Code Online (Sandbox Code Playgroud)
这是通过使用X-Sendfile完成的.
这是邪恶的,我该怎么用呢?
获取X-Sendfile工作需要两个简单的步骤:
标题的名称以及Web服务器的配置方式取决于您使用的Web服务器的类型:
请注意,Nginx将其称为X-Accel.传递给Nginx的标题X-Accel-Redirect是唯一的区别.