2011-01-12 4 views
0

Ich habe eine Liste von Bildern als Blobs in meiner Datenbanktabelle.Bildergalerie mit Blob-Bildern in Symfony

Was ich tun möchte, ist die Bilder in listSuccess.php anzuzeigen, wie eine Galerie.

Könnte jemand einen Code zur Verfügung stellen, der mir helfen oder mich starten würde?

Grüße

Antwort

2

Zunächst einmal, wenn Sie Daten in DB speichern nicht in der einen Tabelle speichern. Hier mein Beispiel:

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/Aktionen/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'] 
    );   
    } 
} 

DateiForm.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); 
    } 
} 
1

In der Liste Aktion, eine Sammlung der entsprechenden Bildobjekte erhalten. Generieren Sie in der Vorlage für jede Variable ein -Tag, das auf eine andere Aktion verweist, die das Image selbst aus der Datenbank abruft und anschließend nach dem Festlegen der entsprechenden http-Header ausgibt.

Gibt es einen bestimmten Grund, warum Sie die Bilder in der Datenbank speichern? Es wäre effizienter, sie irgendwo außerhalb der Webroot auf der Festplatte zu speichern, so dass Sie immer noch Zugriffssteuerung haben können.

Update

Ein einfaches Beispiel folgt. Ich habe es hier eingegeben und kann daher Fehler enthalten.

//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; 
} 
+0

Denken Sie daran, den richtigen Content-Type-HTTP-Header in Ihrem Image-Handler auszugeben. Verwenden Sie auch die Routing-Funktion von Symfony, um URLs auf .jpg oder was auch immer zu setzen, und versuchen Sie, den Header Last-modified zu erhalten, damit der Browser intelligent zwischenspeichert und unnötiges Nachladen verhindert. – Nathan

+0

Und ja, Blobs sind doof dafür; Dateisysteme eignen sich hervorragend zum Speichern von Bildern. – Nathan

+0

Könnten Sie mir ein einfaches Beispiel für Code geben, den ich verwenden könnte? Mit freundlichen Grüßen – terrid25

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