Ask your Symfony questions! Pay money and get answers fast! (more info)

Displaying an Image (Blob) Symfony

  • SOLVED

Hi Guys,
i'm trying to display a BLOB from the Database. Everything works fine, but i want to avoid echo-ing Data in the Action-Class.

So here is my Code in the Action:

public function executeShowImage(sfWebRequest $request){
$foto= Doctrine::getTable('fotos')->findOneBy('fid',$request->getParameter('id'));
if(count($foto)>0){
$response=$this->getResponse();
$response->setContent('image');
echo $foto->getInhalt();
}else{
return false;
}
}


In my Template I call this function:

<img src="<? echo "fotos/ShowImage?id=".$foto->getId(); ?>" />


This works and all images are displayed. But i dislike my Action-Code because of the Output-function (echo $foto->getInhalt());

I tried allready something like this:

public function executeShowImage(sfWebRequest $request){
$foto= Doctrine::getTable('fotos')->findOneBy('stud_id',$request->getParameter('id'));
if(count($foto)>0){
$response=$this->getResponse();
$response->setContent('image');
$response->setContent($foto->getInhalt());
return sfView::NONE;
}
}


or delegating the output to another template by using this code:

public function executeShowImage(sfWebRequest $request){
$foto= Doctrine::getTable('fotos')->findOneBy('stud_id',$request->getParameter('id'));
if(count($foto)>0){
$response=$this->getResponse();
$response->setContent('image');
$this->foto=$foto->getInhalt()
$this->setTemplate('image');
}
}

<strong>and in the Imagetemplate</strong>
echo $foto;



but nothing brings me any further.
Have you any idea to avoid the output in the action and delegate it to the view or something which makes more sense?

Answers (4)

2010-06-14

José Antonio answers:

Hello Martin Baudrechsel:

I supouse that the "inhalt" property of your "fotos" table are the BLOB field....

try to put this code in your action:

public function executeShowImage(sfWebRequest $request){
$foto= Doctrine::getTable('fotos')->findOneBy('stud_id',$request->getParameter('id'));
if(count($foto)>0){
$response=$this->getResponse();
$response->setContent('image');
<strong>$this->foto= stream_get_contents($foto->getInhalt());</strong>
$this->setTemplate('image');
}
}

<strong>and in the imagetemplate</strong>

echo $foto;


Regards


Martin Baudrechsel comments:

Didn't work.
I tried about the url and i receive a warning:

Warning: stream_get_contents() expects parameter 1 to be resource, string given in /Applications/XAMPP/xamppfiles/htdocs/bachelor/apps/frontend/modules/fotos/actions/actions.class.php on line 67


But you are right: getInhalt() represents my Blob-field


José Antonio comments:

Hello Martin Baudrechsel:

If the "renderText()" function sugested by Wojciech Sznapka don't work you should try save the image content into a image and after that show it with an img xhtml tag. Meabe you can do this:

public function executeShowImage(sfWebRequest $request){
$foto= Doctrine::getTable('fotos')->findOneBy('stud_id',$request->getParameter('id'));
if(count($foto)>0){
<strong> $this->foto = sfConfig::get('sf_upload_dir').DIRECTORY_SEPARATOR.$foto->getStudId().'.'.$foto->getExtention();
$stream = fopen($this->foto,'wb');
fwrite($stream, $foto->getInhalt());
fclose($stream);</strong>
$this->setTemplate('image');
}
}


and in the imagetemplate

<img src="<strong><?php echo $foto;?></strong>" alt="image" />


José Antonio comments:

I put <strong>$foto->getExtention()</strong> for promp you to writte a extention for the file... take care whit it.

2010-06-14

Yura Rodchyn answers:

I think it would be theft to put this work on the cache server, write a module to nginx or lighty.
Render images from a database that does not symfony work.

Or if you want symfony use standart setContent action method.
Soething like this:


<?php

class myActions extends sfActions
{
public function renderRawImage($data, $mimeType = 'image/png')
{
$this->getResponse()->setContentType($mimeType);
$this->getResponse()->setContent($data);
return sfView::NONE;
}
}


class articlesActions extends myActions
{
public function executeShowImage(sfWebRequest $request)
{
$foto = Doctrine::getTable('fotos')->findOneBy('stud_id',$request->getParameter('id'));

if(count($foto) > 0){
$this->renderRawImage($foto->getInhalt());
return sfView::NONE;
}
}

}

?>


Martin Baudrechsel comments:

yeah I got it the way you said. I tried that already as you can see in my 2nd example:

$response->setContent($foto->getInhalt());
return sfView::NONE;


I don't know why, but no it works this way :D

2010-06-14

Wojciech Sznapka answers:

try this:


public function executeShowImage(sfWebRequest $request)
{
$foto = Doctrine::getTable('fotos')->findOneBy('stud_id',$request->getParameter('id'));
if ($foto){
$this->getResponse()->setContentType('image/jpeg');
return $this->renderText($foto->getInhalt());
}
}


Martin Baudrechsel comments:

Didn't work... trying over url gets me the binary Data as text.

2010-06-14

Bill Hunt answers:

There's a nice tutorial on how this used to be done with the Propel FileStorage plugin, it's probably a good place to start:

[[LINK href="http://trac.symfony-project.org/wiki/DatabaseFileStorageSystem"]]http://trac.symfony-project.org/wiki/DatabaseFileStorageSystem[[/LINK]]

That being said, I should express concern over storing an image in the DB in the first place. I'm sure you know what you're doing to be posting here, but generally there are more problems than answers in storing files in the DB rather than the filesystem. You might consider refactoring to avoid the issue altogether.