Symfony2:如何显示/下载BLOB字段

时间:2013-03-04 17:05:18

标签: symfony blob

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

所以我创建了一个带有Blob类的独立包,扩展了Doctrine \ DBAL \ Types \ Type。 并且在bundle类中使用引导函数。

我可以在数据库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;
}

我有一个例外: Response内容必须是实现__toString(),“resource”的字符串或对象。

实际上, $ file 值不是预期的BLOB,而是像资源ID#123

- >我检查了blob数据字段值,它们在数据库中没问题

那么如何强制控制器中的blob行而不是资源ID#111

2 个答案:

答案 0 :(得分:24)

您仍然可以按照最初的计划在数据库中使用 BLOB 字段。

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 字段被视为 resource 变量,它没有__toString()实现。

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

stream_get_contents($ file)让这里变得神奇:从资源变量中获取 STRING 内容。

答案 1 :(得分:1)

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

首先:我将数据类型 blob 更改为文本以获取Document实体的文件属性。

其次:在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方式下载文件......