This is what worked for me. If you have the oid, then all you need to do is:
<?php
$pdo = new PDO($dsn, $user, $pass);
$pdo->beginTransaction();
$data = $pdo->pgsqlLOBOpen($oid, 'r');
header("Content-Type: $mime");
// any other headers...
fpassthru($data); // echo stream_get_contents($data); also works
?>
The beginTransaction() is required, if you want to $pdo->commit() (it's not required) then do it after the fpassthru.
On a side note, those using Zend Framework can call getConnection() on the standard PDO database object which will get them the $pdo object as above. Then just remember to disableLayout() and setNoRender() as necessary.
PDO::pgsqlLOBOpen
(PHP 5 >= 5.1.2, PECL pdo_pgsql >= 1.0.2)
PDO::pgsqlLOBOpen — Ouvre un flux existant de large objet
Description
$oid
[, string $mode = "rb"
] )
PDO::pgsqlLOBOpen() ouvre un flux pour accéder aux
données référencées par oid. Si
mode est r, le flux est ouvert en
lecture, si mode est w, alors le
flux sera ouvert en écriture. Vous pouvez utilisez toutes les fonctions
usuelles de système de fichiers, comme fread(),
fwrite() et fgets() pour manipuler le
contenu du flux.
Note: Cette fonction, ainsi que toutes les manipulations sur l'objet large, doit être appelée et exécutée à l'intérieur d'une transaction.
Liste de paramètres
-
oid -
Un identifiant d'objet large
-
mode -
Si le mode est r, ouverture du flux en lecture. Si le mode est w, ouverture du flux en écriture.
Valeurs de retour
Retourne une ressource de flux en cas de succès ou FALSE si une erreur survient.
Exemples
Exemple #1 Exemple avec PDO::pgsqlLOBOpen()
Suivant l'exemple de PDO::pgsqlLOBCreate(), cet partie de code récupère l'objet large de la base de données et l'affiche au navigateur.
<?php
$db = new PDO('pgsql:dbname=test host=localhost', $user, $pass);
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$db->beginTransaction();
$stmt = $db->prepare("select oid from BLOBS where ident = ?");
$stmt->execute(array($some_id));
$stmt->bindColumn('oid', $lob, PDO::PARAM_LOB);
$stmt->fetch(PDO::FETCH_BOUND);
fpassthru($lob);
?>
Voir aussi
- PDO::pgsqlLOBCreate() - Crée un nouvel objet large
- PDO::pgsqlLOBUnlink() - Supprime un objet large
- pg_lo_open() - Ouvre un objet de grande taille PostgreSQL
Also remember that fread() will only parse the first 8192 bytes from the stream. Use..
<?php
$data = stream_get_contents($stream);
?>
.. if you have a larger output to parse.
The above example is missing some data. After spending several hours trying to get it to work in vain, Jeff Davis from the PostgreSQL channel on IRC (freenode) figured out what was missing.
The below example will work, but you have to insert the MIME type and file size of the large object that you are storing, so you can use that data for extraction.
<?php
$db = new PDO('pgsql:dbname=test host=localhost', $user, $pass);
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$db->beginTransaction();
$stmt = $db->prepare("SELECT oid, blob_type, filesize FROM BLOBS WHERE ident = ?");
$stmt->execute(array($some_id));
$stmt->bindColumn('oid', $lob, PDO::PARAM_LOB);
$stmt->bindColumn('blob_type', $blob_type, PDO::PARAM_STR);
$stmt->bindColumn('filesize', $filesize, PDO::PARAM_STR);
$stmt->fetch(PDO::FETCH_BOUND);
$stream = $pdo->pgsqlLOBOpen($lob, 'r');
$data = fread($stream, $filesize);
header("Content-type: $blob_type");
echo $data;
?>
Also fpassthru() will just give this result: Warning: fpassthru(): supplied argument is not a valid stream resource in ...
Use echo or print instead.
