Symfony2: как отобразить/загрузить поле BLOB
Для моего клиента я должен использовать хранилище 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, а не идентификатор ресурса # 111
Ответы
Ответ 1
Вы все еще можете использовать поле 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 поля рассматриваются как переменная ресурса, которые не имеют реализации __toString().
gettype($file) -> "resource"
get_resource_type($file) -> "stream"
stream_get_contents ($ file) создает магию: получает содержимое STRING из переменной ресурса.
Ответ 2
Хорошо, у меня есть (очень uggly) решение:
Во-первых: я изменил тип данных blob на текст для атрибута файла объекта Document.
Во-вторых: в createAction я изменил вызов setFichier:
$stream = fopen($entity->getFichier(),'rb');
$entity->setFichier(base64_encode(stream_get_contents($stream)));
В-третьих: в файле downloadAction я декодирую текстовое поле text 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...