【问题标题】:Symfony2: How to display/download a BLOB fieldSymfony2:如何显示/下载 BLOB 字段
【发布时间】:2013-03-04 17:05:18
【问题描述】:

对于我的客户,我必须为一些不同的文件使用 blob 存储。

所以我创建了一个独立的包,其中 Blob 类扩展了 Doctrine\DBAL\Types\Type。 并在捆绑类中具有引导功能。

效果很好,我可以在数据库中写入 Blob 数据。

但我无法下载任何文件:/

我有:

public function downloadAction($id) {
    $em = $this->getDoctrine()->getManager();

    /* @var $entity Document */
    $entity = $em->getRepository('Lille3SapBundle:Document')->find($id);

    if (!$entity) {
        throw $this->createNotFoundException('Unable to find Document entity.');
    }

    $file = $entity->getFichier();

    $response = new \Symfony\Component\HttpFoundation\Response($file, 200, array(
        'Content-Type' => 'application/octet-stream',
        'Content-Length' => sizeof($file),
        'Content-Disposition' => 'attachment; filename="'.$entity->getNomDocument().'"',
    ));

    return $response;
}

我有一个例外: 响应内容必须是实现 __toString() 的字符串或对象,给定的“资源”。

事实上,$file 值不是预期的 BLOB,而是类似于 Resource id #123

-> 我检查了 blob 数据字段的值,它们在数据库中都可以

那么我怎样才能在控制器中强制使用 blob 行而不是 Resource id #111

【问题讨论】:

  • 你能告诉我们getFichier方法的内容吗? resource 是在该调用中生成的吗?如果不是,将资源 handle 存储在数据库中有点奇怪...

标签: symfony blob


【解决方案1】:

您仍然可以按照最初的计划将 BLOB 字段用于 DB 中的字段。

createAction中照常存储数据(没有base64_encode()):

$stream = fopen($entity->getFichier(),'rb');
$entity->setFichier(stream_get_contents($stream));

downloadAction 中使用:

$file = $entity->getFichier();
$response = new \Symfony\Component\HttpFoundation\Response(stream_get_contents($file), 
    200, 
    array(
        'Content-Type' => 'application/octet-stream',
        'Content-Length' => sizeof($file),
        'Content-Disposition' => 'attachment; filename="'.$entity->getNomDocument().'"',
    ));

return $response;

说明:

BLOB 字段被视为没有 __toString() 实现的 resource 变量。

gettype($file) -> "resource"
get_resource_type($file) -> "stream"

stream_get_contents($file) 创造了奇迹:从资源变量中获取 STRING 内容。

【讨论】:

  • 如果您直接从 Doctrine 实体的属性获取流,请不要忘记致电 rewind($entity->getFichier());
  • @Rafal Gradziel 它工作了 90%。但我无法下载该文件。在响应中,我将文件内容作为控制台中的输出。任何帮助! !
  • 我正在尝试应用它,但最终出现 PHP 错误:Message: fopen() expects parameter 1 to be a valid path, resource given
  • 仅供参考,我遇到了 sizeof() 总是返回 1 的问题,因此文件被严重截断。我必须做strlen($file) 而不是sizeof($file)
【解决方案2】:

好的,我有一个(非常难看的)解决方案:

首先:我将 Document 实体的文件属性的数据类型 blob 更改为 text

其次:在 createAction 中我更改了 setFichier 调用:

$stream = fopen($entity->getFichier(),'rb');
$entity->setFichier(base64_encode(stream_get_contents($stream)));

第三:在downloadAction中,我对文本base64文本域进行解码:

$file = $entity->getFichier();              
$response = new \Symfony\Component\HttpFoundation\Response(base64_decode($file), 200, array(
        'Content-Type' => 'application/octet-stream',
        'Content-Length' => sizeof($file),
        'Content-Disposition' => 'attachment; filename="'.$entity->getNomDocument().'"',
));

return $response;

现在我可以以 blob 方式保存和下载文件...

【讨论】:

  • 我建议删除对某些文件有问题的“Content-Length”字段
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-05-31
  • 2012-05-21
  • 2012-02-04
  • 2011-02-06
  • 1970-01-01
  • 1970-01-01
  • 2012-04-03
相关资源
最近更新 更多