开发者

image gallery using blob images in symfony

开发者 https://www.devze.com 2023-02-03 16:35 出处:网络
I have a list of images as blobs in my database table. What I\'d like to do is display the images in listSuccess.php, like a开发者_C百科 gallery.

I have a list of images as blobs in my database table.

What I'd like to do is display the images in listSuccess.php, like a开发者_C百科 gallery.

Could someone provide some code that would help or get me started?

Regards


First of all if you store data in DB do not store it in the one sigle table. Here my example:

schema.yml

File:
  connection: doctrine
  actAs: { Timestampable: ~ }
  columns:
    document_id: { type: integer(5), notnull: true}
    name: string(255)
    size: integer(11)
    mime: string(255)
  relations:
    Document:
      class: Document
      local: document_id
      foreign: id
      type: one
      onDelete: CASCADE
    FileData:
      local: id
      foreign: file_id
      type: one
      foreignType: one


FileData:
  connection: doctrine
  columns:
    file_id: { type: integer(6), notnull: true }
    binary_data: { type: LONGBLOB, notnull: true }
  relations:
    File: { onDelete: CASCADE, local: file_id, foreign: id, foreignType: one }

frontend/modules/file/actions/actions.class.php

<?php

class fileActions extends sfActions
{

  public function executeDownload(sfWebRequest $request)
  {
    $response = $this->getResponse();


    /** @var $file File */
    $file = $this->getRoute()->getObject();
    $this->forward404Unless($file->getDocument()->isApprovedAndShared($this->getUser()));
    $fsize = $file->getSize();

    $response->setContentType($file->getMime());
    $response->setHttpHeader('Content-Length',$fsize);
    $response->setHttpHeader('Content-Disposition','filename='.$file->getName());
    $response->setHttpHeader('Content-transfer-encoding','binary');

    $response->setContent($file->getFileData()->getBinaryData());

    return sfView::NONE;
  }

  public function executeAddFile(sfWebRequest $request)
  {
    $this->forward404Unless($request->isMethod(sfRequest::POST));

    /** @var $document Document */
    $document = $this->getRoute()->getObject();
    $this->forward404Unless( $document->getOffice()->getId() == $this->getUser()->getGuardUser()->getOfficeId(), $this->getContext()->getI18N()->__('textAccessForbidden'));

    $form = new FileForm();

    $files = $request->getFiles($form->getName());
    $file_name = $files['file']['name'];
    $file_already_exist = FileTable::getInstance()->getFile($document->getId(), $file_name);

    if ($file_already_exist) {
      $form = new FileForm($file_already_exist);
      $form->bind($request->getParameter($form->getName()), $request->getFiles($form->getName()));
//      $form->getObject()->setCreatedAt(date("Y-m-d H:i:s", time()));
      $form->getObject()->setUpdatedAt(date("Y-m-d H:i:s", time()));
    }
    else {
      $form = new FileForm();
      $form->bind($request->getParameter($form->getName()), $request->getFiles($form->getName()));
    }

    if ($form->isValid())
    {
      $form->getObject()->setDocumentId($document->getId());
      $file_result = $form->save();

      if ($file_already_exist)
        $this->getUser()->setFlash('notice', $this->getContext()->getI18N()->__("textFileReplacedOk", array('%s%'=>$file_result->getName())));
      else
        $this->getUser()->setFlash('notice', $this->getContext()->getI18N()->__("textFileUploadOk", array('%s%'=>$file_result->getName())));

      $this->redirect($this->generateUrl("document_edit",$document));
    }

    $this->getUser()->setFlash('error', $this->getContext()->getI18N()->__("textFileUploadError"));
    $this->forward("document","edit");

  }


  public function executeDelete(sfWebRequest $request)
  {
    /** @var $file File */
    $file = $this->getRoute()->getObject();

    $this->forward404Unless($request->getParameter('document_id') == $file->getDocumentId() , sprintf('The object doesn\'t belong to the document (file: %s).', $request->getParameter('id')));
    $this->forward404Unless($file = FileTable::getInstance()->find(array($file->getId() )), sprintf('Object file does not exist (%s).', $request->getParameter('id')));
    $file->delete();

    $this->getUser()->setFlash('notice', sprintf($this->getContext()->getI18N()->__("textFileDeletedOk"),$file->getName()));

    $this->redirect($this->generateUrl( "document_edit",DocumentTable::getInstance()->find(array($file->getDocumentId())) ));
  }

}

FileDataForm.class.php

class FileDataForm extends BaseFileDataForm
{
  public function configure()
  {
    unset(
      $this['file_id']
    );        
  }
}

FileForm.class.php

class FileForm extends BaseFileForm
{
  public function configure()
  {
    $this->disableCSRFProtection();
    $this->useFields(array());
    $this->widgetSchema['file'] = new sfWidgetFormInputFile(array());

    $this->setValidator('file', new sfValidatorFile(array(
     'max_size' => 1024*1024*sfConfig::get("app_max_file_size", 10) //MB
    )));


  }

  public function save($con = null)
  {

    /** @var $validated_file
     var_dump( $validated_file) */
    $validated_file = $this->getValue('file');

    /** @var $file File */
    $file = $this->getObject();
    $file->setMime($validated_file->getType());
    $file->setName($validated_file->getOriginalName());
    $file->setSize($validated_file->getSize());

    $fileData = new FileData();

    $fd = @fopen($validated_file->getTempName(), 'rb');

    $fileData->setBinaryData(fread($fd,$validated_file->getSize()));

    fclose($fd);

    $file->setFileData($fileData);
    unset($this['file']); //do not save Validated file: this is a trick :)

    return parent::save($con);
  }
}


In your list action, get a collection of the appropriate image objects. In the template, generate an <img> tag for each, pointing to another action, that fetches the image itself from the database, then outputs it after setting the appropriate http headers.

Any specific reason you're storing the images in the database? It'd be more efficient to store them on the disk, somewhere outside of the webroot, so you can still have access control.

update

A basic example follows. I just typed it here, so may contain errors.

//actions.class.php
public function executeIndex(sfWebRequest $request) {
  //get the images belonging to the current gallery
  $this->images = Doctrine_Core::getTable("Image")->retrieveByGalleryId($request->getParameter("id"));
}

//indexSuccess.php
<?php foreach ($images as $image): ?>
  <img src="<?php echo url_for("image_show", $image) ?>" alt="<?php echo $image->title ?>" />
<?php endforeach>

//actions.class.php again
public function executeShow(sfWebRequest $request) {
  $image = $this->getRoute()->getObject();
  $this->getResponse()->clearHttpHeaders();
  $this->getResponse()->setContentType($image->mime_type);
  $this->getResponse()->setHttpHeader('Content-Disposition', 'attachment; filename=' . $image->file_name);
  $this->getResponse()->setHttpHeader('Content-length', $image->file_size);
  readfile($image->file_name);
  return sfView::NONE;
}


$profile_picture = base64_encode(stream_get_contents($image->getContent()));
echo '<img src="data:image/jpeg;base64,'.$profile_picture.'" />';
0

精彩评论

暂无评论...
验证码 换一张
取 消