Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
947 views
in Technique[技术] by (71.8m points)

symfony - Symfony2: How to display/download a BLOB field

For my client I have to use blob storage for some various files.

So I have created a independent bundle with a Blob class extends DoctrineDBALTypesType. and with a boot function in the bundle class.

That works pretty fine I can write in the database Blob datas.

But I can't download any document after :/

I have got:

public function downloadAction($id) {
    $em = $this->getDoctrine()->getManager();

    /* @var $entity Document */
    $entity = $em->getRepository('Lille3SapBundle:Document')->find($id);

    if (!$entity) {
        throw $this->createNotFoundException('Unable to find Document entity.');
    }

    $file = $entity->getFichier();

    $response = new SymfonyComponentHttpFoundationResponse($file, 200, array(
        'Content-Type' => 'application/octet-stream',
        'Content-Length' => sizeof($file),
        'Content-Disposition' => 'attachment; filename="'.$entity->getNomDocument().'"',
    ));

    return $response;
}

and I have got an Exception: The Response content must be a string or object implementing __toString(), "resource" given.

in fact, the $file values is not the expected BLOB but something like Resource id #123

-> I have check blob data fields values, and they are ok in the database

So how can I force in the controller to have the blob row and not a Resource id #111

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

You can still use BLOB field for your field in DB as you initially planned.

In createAction store data as usual (with no base64_encode()):

$stream = fopen($entity->getFichier(),'rb');
$entity->setFichier(stream_get_contents($stream));

and in downloadAction just use:

$file = $entity->getFichier();
$response = new SymfonyComponentHttpFoundationResponse(stream_get_contents($file), 
    200, 
    array(
        'Content-Type' => 'application/octet-stream',
        'Content-Length' => sizeof($file),
        'Content-Disposition' => 'attachment; filename="'.$entity->getNomDocument().'"',
    ));

return $response;

Explanation:

BLOB fields are treated as resource variable which have no __toString() implementation.

gettype($file) -> "resource"
get_resource_type($file) -> "stream"

stream_get_contents($file) makes the magic here: gets STRING content from resource variable.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...