2013-03-04 35 views
10

對於我的客戶端,我必須爲一些不同的文件使用blob存儲。Symfony2:如何顯示/下載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( ),給出了「資源」。

其實$文件值不是預期的BLOB但像資源ID#東西123

- >我檢查BLOB數據字段的值,和他們確定在數據庫

那麼,怎樣才能迫使我在控制器中有BLOB列而不是資源ID#111

+0

你能告訴我們'getFichier'方法的內容嗎?在該呼叫中是否產生了「資源」?如果沒有,將資源**句柄**存儲在您的數據庫中會有點奇怪... – 2013-03-04 17:12:06

回答

1

好吧,我有一個(非常uggly)解決方案:

首先:我將文檔實體的文件屬性的數據類型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的方式...

+0

我建議刪除'Content-Length'字段,這對某些文件有問題 – saillantist 2013-03-05 10:47:50

21

您仍然可以使用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($文件)使得魔術在這裏:得到STRING從資源變量的內容。

+2

不要忘記調用'rewind($ entity - > getFichier());',如果你直接從Doctrine實體的屬性獲取流。 – Dejv 2016-04-22 13:01:39

+0

@Rafal Gradziel它工作了90%。但我無法下載該文件。在響應中,我將獲取文件內容作爲控制檯中的輸出。任何幫助! ! – 2016-10-05 15:54:26