2013-07-01 50 views
8

我想知道如何從控制器沒有任何模板返回圖像。 我想在通訊中使用它進行像素跟蹤。從控制器返回圖像symfony2

我開始使用此代碼

$image = "1px.png"; 
    $file = readfile("/path/to/my/image/1px.png"); 
    $headers = array(
     'Content-Type'  => 'image/png', 
     'Content-Disposition' => 'inline; filename="'.$file.'"'); 
    return new Response($image, 200, $headers); 

但在導航我有斷開的鏈接(未找到文件...)

+0

剛剛看到的消息,但是這將有助於。 [用symfony下載文件](http://www.inanzzz.com/index.php/post/cko4/downloading-a-file-with-symfony) – BentCoder

回答

9

現在你返回文件名作爲響應體和寫入文件 - Content-Disposition的文件名屬性的內容。

return new Response($image, 200, $headers); 

應該是:

return new Response($file, 200, $headers); 

......還有......

'Content-Disposition' => 'inline; filename="'.$file.'"'); 

應該是...

'Content-Disposition' => 'inline; filename="'.$image.'"'); 

吧?

進一步看看this question

+0

完美!解決方案是另一個話題。在你的情況下,我有一個500錯誤代碼。感謝您的鏈接 –

1

此外,我不得不改變:

$file = readfile("/path/to/my/image/1px.png"); 

這樣:

$file = file_get_contents("/path/to/my/image/1px.png"); 

好像ReadFile的是呼應內容讀這本書是迫使頭輸出早,否定強制的Content-Type頭。

16

按照Symfony的文檔時serving files你可以使用一個BinaryFileResponse

use Symfony\Component\HttpFoundation\BinaryFileResponse; 
$file = 'path/to/file.txt'; 
$response = new BinaryFileResponse($file); 
// you can modify headers here, before returning 
return $response; 

這BinaryFileResponse自動處理某些HTTP請求頭,並免去您使用readfile()或其他文件的功能。

+0

這不適用於動態創建的圖像數據。 – RichieHH

0

file_get_contents是一個壞主意。通過file_get_contents讀取大量圖像會殺死我的小服務器。我不得不尋找另一種解決方案,這對我來說現在完美並且非常快速。

關鍵是使用readfile($ sFileName)而不是file_get_contents。 Symfony Stream Response可以接收一個回調函數,它將在發送($ oResponse-> send())時執行。所以這是一個使用readfile()的好地方。

作爲一個小好處,我寫下了一種緩存方式。

use Symfony\Component\HttpFoundation\Request; 
use Symfony\Component\HttpFoundation\Response; 
use Symfony\Component\HttpFoundation\StreamedResponse; 

class ImageController 
{ 

    public function indexAction(Request $oRequest, Response $oResponse) 
    { 
     // Get the filename from the request 
     // e.g. $oRequest->get("imagename") 
     $sFileName = "/images_directory/demoimage.jpg"; 
     if(! is_file($sFileName)){ 
      $oResponse->setStatusCode(404); 

      return $oResponse; 
     } 

     // Caching... 
     $sLastModified = filemtime($sFileName); 
     $sEtag = md5_file($sFileName); 

     $sFileSize = filesize($sFileName); 
     $aInfo = getimagesize($sFileName); 

     if(in_array($sEtag, $oRequest->getETags()) || $oRequest->headers->get('If-Modified-Since') === gmdate("D, d M Y H:i:s", $sLastModified)." GMT"){ 
      $oResponse->headers->set("Content-Type", $aInfo['mime']); 
      $oResponse->headers->set("Last-Modified", gmdate("D, d M Y H:i:s", $sLastModified)." GMT"); 
      $oResponse->setETag($sEtag); 
      $oResponse->setPublic(); 
      $oResponse->setStatusCode(304); 

      return $oResponse; 
     } 

     $oStreamResponse = new StreamedResponse(); 
     $oStreamResponse->headers->set("Content-Type", $aInfo['mime']); 
     $oStreamResponse->headers->set("Content-Length", $sFileSize); 
     $oStreamResponse->headers->set("ETag", $sEtag); 
     $oStreamResponse->headers->set("Last-Modified", gmdate("D, d M Y H:i:s", $sLastModified)." GMT"); 

     $oStreamResponse->setCallback(function() use ($sFileName) { 
      readfile($sFileName); 
     }); 

     return $oStreamResponse; 
    } 
} 
2

這對我來說很好。

$filepath = "/path/to/my/image/chart.png"; 
$filename = "chart.png"; 

$response = new Response(); 
$disposition = $response->headers->makeDisposition(ResponseHeaderBag::DISPOSITION_INLINE, $filename); 
$response->headers->set('Content-Disposition', $disposition); 
$response->headers->set('Content-Type', 'image/png'); 
$response->setContent(file_get_contents($filepath)); 

return $response; 
0

快速anwser

use Symfony\Bundle\FrameworkBundle\Controller\Controller; 
use Symfony\Component\HttpFoundation\Response; 
use Symfony\Component\HttpFoundation\ResponseHeaderBag; 

class AnotherController extends Controller { 

    public function imagesAction($img = 'my_image.jpg'){ 

    $filepath = '/path/to/images/'.$img; 

     if(file_exists($filepath)){ 
     $response = new Response(); 
     $disposition = $response->headers->makeDisposition(ResponseHeaderBag::DISPOSITION_INLINE, $img); 
     $response->headers->set('Content-Disposition', $disposition); 
     $response->headers->set('Content-Type', 'image/jpeg'); 
     $response->setContent(file_get_contents($filepath)); 
     return $response; 
     } 
     else{ 
     return $this->redirect($this->generateUrl('my_url_to_site_index')); 
     } 
    } 
}