For my client I have to use blob storage for some various files.
对于我的客户端,我必须使用blob存储来处理各种文件。
So I have created a independent bundle with a Blob class extends Doctrine\DBAL\Types\Type. and with a boot function in the bundle class.
所以我创建了一个独立的bundle,其中一个Blob类扩展了Doctrine \ DBAL \ Types \ Type。并在bundle类中使用引导函数。
That works pretty fine I can write in the database Blob datas.
这很好,我可以写在数据库Blob数据中。
But I can't download any document after :/
但我无法下载任何文件后:/
I have got:
我有:
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;
}
and I have got an Exception: The Response content must be a string or object implementing __toString(), "resource" given.
我有一个例外:响应内容必须是一个字符串或对象,实现__toString(),给定“资源”。
in fact, the $file values is not the expected BLOB but something like Resource id #123
实际上,$ file值不是预期的BLOB,而是类似于资源ID#123
-> I have check blob data fields values, and they are ok in the database
- >我检查了blob数据字段值,它们在数据库中没问题
So how can I force in the controller to have the blob row and not a Resource id #111
那么我如何强制控制器中的blob行而不是资源ID#111
2 个解决方案
#1
21
You can still use BLOB field for your field in DB as you initially planned.
您仍然可以按照最初计划在数据库中为您的字段使用BLOB字段。
In createAction store data as usual (with no base64_encode()):
在createAction中像往常一样存储数据(没有base64_encode()):
$stream = fopen($entity->getFichier(),'rb');
$entity->setFichier(stream_get_contents($stream));
and in downloadAction just use:
并在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;
Explanation:
说明:
BLOB fields are treated as resource variable which have no __toString() implementation.
BLOB字段被视为没有__toString()实现的资源变量。
gettype($file) -> "resource"
get_resource_type($file) -> "stream"
stream_get_contents($file) makes the magic here: gets STRING content from resource variable.
stream_get_contents($ file)在这里发挥作用:从资源变量中获取STRING内容。
#2
1
Okay, I have got a (very uggly) solution:
好的,我有一个(非常好的)解决方案:
Firstly: I changed the data type blob to text for the file attribute of Document entity.
首先:我将数据类型blob更改为文本实体的文件属性的文本。
Secondly: in createAction I've changed the setFichier call:
其次:在createAction中我改变了setFichier调用:
$stream = fopen($entity->getFichier(),'rb');
$entity->setFichier(base64_encode(stream_get_contents($stream)));
Thirdly: in downloadAction, I decode the text base64 text field:
第三:在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;
And now I can persist and download files as blob way...
现在我可以坚持下载文件作为blob方式...
#1
21
You can still use BLOB field for your field in DB as you initially planned.
您仍然可以按照最初计划在数据库中为您的字段使用BLOB字段。
In createAction store data as usual (with no base64_encode()):
在createAction中像往常一样存储数据(没有base64_encode()):
$stream = fopen($entity->getFichier(),'rb');
$entity->setFichier(stream_get_contents($stream));
and in downloadAction just use:
并在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;
Explanation:
说明:
BLOB fields are treated as resource variable which have no __toString() implementation.
BLOB字段被视为没有__toString()实现的资源变量。
gettype($file) -> "resource"
get_resource_type($file) -> "stream"
stream_get_contents($file) makes the magic here: gets STRING content from resource variable.
stream_get_contents($ file)在这里发挥作用:从资源变量中获取STRING内容。
#2
1
Okay, I have got a (very uggly) solution:
好的,我有一个(非常好的)解决方案:
Firstly: I changed the data type blob to text for the file attribute of Document entity.
首先:我将数据类型blob更改为文本实体的文件属性的文本。
Secondly: in createAction I've changed the setFichier call:
其次:在createAction中我改变了setFichier调用:
$stream = fopen($entity->getFichier(),'rb');
$entity->setFichier(base64_encode(stream_get_contents($stream)));
Thirdly: in downloadAction, I decode the text base64 text field:
第三:在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;
And now I can persist and download files as blob way...
现在我可以坚持下载文件作为blob方式...