CakeFest 2024: The Official CakePHP Conference

PDO::pgsqlLOBOpen

(PHP 5 >= 5.1.2, PHP 7, PHP 8, PECL pdo_pgsql >= 1.0.2)

PDO::pgsqlLOBOpenAbrir un flujo de un objeto grande existente

Descripción

public PDO::pgsqlLOBOpen(string $oid, string $mode = "rb"): resource

PDO::pgsqlLOBOpen() abre un flujo para acceder a los datos a los que hace referencia oid. Si mode es r, el flujo será abierto para lectura; si mode es w, el flujo será abierto para escritura. Se pueden utilizar todas las funciones de sistema de ficheros usuales, tales como fread(), fwrite() y fgets() para manipular el contenido del flujo.

Nota: Esta función, y todas las manipulaciones del objeto grande, debe ser invocada y realizada dentro de una transacción.

Parámetros

oid

Un identificador de objeto grande.

mode

Si el modo es r, se abre el flujo para lectura. Si el modo es w, se abre el flujo para escritura.

Valores devueltos

Devuelve un recurso de flujo en caso de éxito o false en caso de error.

Ejemplos

Ejemplo #1 Un ejemplo de PDO::pgsqlLOBOpen()

Siguiendo el ejemplo de PDO::pgsqlLOBCreate(), este trozo de código recupera el objeto grande de la base de datos y lo envía al navegador.

<?php
$bd
= new PDO('pgsql:dbname=test host=localhost', $usuario, $contraseña);
$bd->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$bd->beginTransaction();
$sentencia = $bd->prepare("select oid from BLOBS where ident = ?");
$sentencia->execute(array($some_id));
$sentencia->bindColumn('oid', $oid, PDO::PARAM_STR);
$sentencia->fetch(PDO::FETCH_BOUND);
$flujo = $bd->pgsqlLOBOpen($oid, 'r');
header("Content-type: application/octet-stream");
fpassthru($flujo);
?>

Ver también

add a note

User Contributed Notes 3 notes

up
1
binaryexp at gmail
15 years ago
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.
up
0
knl at bitflop dot com
15 years ago
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.
up
0
knl at bitflop dot com
15 years ago
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.
To Top