Ich möchte wissen, wie ich ein Bild vom Controller ohne Vorlage zurückgeben kann. Ich möchte es für das Pixel-Tracking in einem Newsletter verwenden.
Ich beginne mit diesem Code
$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);
Aber auf dem Navigator habe ich einen defekten Link (Datei nicht gefunden ...)
Im Moment geben Sie den Dateinamen als Antworttext zurück und schreiben den Dateiinhalt in die Eigenschaft filename von Content-Disposition.
return new Response($image, 200, $headers);
sollte sein:
return new Response($file, 200, $headers);
... und ...
'Content-Disposition' => 'inline; filename="'.$file.'"');
sollte sein ...
'Content-Disposition' => 'inline; filename="'.$image.'"');
recht?
Weitere werfen Sie einen Blick auf diese Frage .
Laut Symfony Docs können Sie beim Bereitstellen von DateienBinaryFileResponse Folgendes verwenden:
use Symfony\Component\HttpFoundation\BinaryFileResponse;
$file = 'path/to/file.txt';
$response = new BinaryFileResponse($file);
// you can modify headers here, before returning
return $response;
Diese BinaryFileResponse verarbeitet automatisch einige HTTP-Anforderungsheader und erspart Ihnen die Verwendung von readfile()
oder anderen Dateifunktionen.
Das funktioniert gut für mich.
$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;
file_get_contents ist eine schlechte Idee . Das Lesen einer großen Liste von Bildern über file_get_contents hat meinen kleinen Server getötet. Ich musste eine andere Lösung finden und das funktioniert jetzt perfekt und sehr schnell für mich.
Der Schlüssel ist, readfile ($ sFileName) anstelle von file_get_contents zu verwenden. Die Symfony Stream Response kann eine Rückruffunktion übernehmen, die beim Senden ausgeführt wird ($ oResponse-> send ()). Dies ist also ein guter Ort, um readfile () zu verwenden.
Als kleinen Vorteil habe ich eine Art von Caching aufgeschrieben.
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;
}
}
Auch musste ich ändern:
$file = readfile("/path/to/my/image/1px.png");
dazu:
$file = file_get_contents("/path/to/my/image/1px.png");
Wie es aussah, gab readfile den Inhalt wieder, während es Header zwang, früh auszugeben und den erzwungenen Content-Type-Header zu negieren.
Schnelle Antwort
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_pixel_tracking.png'){
$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/png');
$response->setContent(file_get_contents($filepath));
return $response;
}
else{
return $this->redirect($this->generateUrl('my_url_to_site_index'));
}
}
}