16

对于我的客户,我必须对一些不同的文件使用 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

4

2 回答 2

28

您仍然可以按照最初的计划将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() 实现的资源变量。

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

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

于 2013-05-10T09:29:23.897 回答
1

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

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

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

于 2013-03-05T10:03:57.407 回答