1.3. API nativa en PostgreSQL

1.3. API nativa en PostgreSQL Dataprix 29 Octubre, 2009 - 16:09

Para trabajar con la API nativa de PostgreSQL en PHP, deberemos haber compilado el intérprete con soporte para este SGBD, o bien disponer ya del binario de PHP precompilado con el soporte incorporado.

En el caso de tenerlo que compilar, únicamente debemos indicar como opción --with-pgsql. Posteriormente, o en el caso de que ya dispongamos del binario, podemos validar que el soporte para PostgreSQL está incluido correctamente en el intérprete con la ejecución del siguiente comando:

$ php -i | grep PostgreSQL
PostgreSQL
PostgreSQL Support => enabled
PostgreSQL(libpq) Version => 7.4.6
$

A partir de aquí, PHP proporciona unos parámetros de configuración que nos permitirán controlar algunos aspectos del funcionamiento de las conexiones con el SGBD, y las propias funciones de trabajo con la base de datos.

En cuanto a los parámetros, deberán situarse en el fichero php.ini o bien configurarse para nuestra aplicación en concreto desde el servidor web. Destacan los siguientes:

•    pgsql.allow_persistent: indica si vamos a permitir el uso de conexiones persistentes. Los valores son true o false.

•    pgsql.max_persistent:  número  máximo  de  conexiones  persistentes permitidas por proceso.

•    pgsql.max_links: número máximo de conexiones permitidas por proceso, incluyendo las persistentes.

Este parámetro disminuye
ligeramente el rendimiento
del sistema.

•    pgsql.auto_reset_persistent: detecta automáticamente conexiones persistentes cerradas y las elimina.

Por lo que respecta a la utilización de la API para la conexión y consulta de bases de datos, reproduciremos el anterior ejemplo:

1 <?php
2 // Conectando y eligiendo la base de datos con que vamos a trabajar
3 $link = pg_connect("host=host_pgsql port=5432 dbname=mi_database user=user_pgsql password=pass_pgsql");
4 $stat = pg_connection_status($link);
5 if ($stat === 0) {
6    echo `Conexión establecida´;
7 } else {
8   die `No puedo conectarme´;
9 }
10
11 // Realizando una consulta SQL
12 $query = `SELECT * FROM mi_tabla´;
13 $result = pg_query($link,$query) or die(`Consulta errónea: ´ . pg_last_error());
14
15 // Mostramos los resultados en HTML
16 echo "<table>\n";
17 while ($line = pg_fetch_array($result, PGSQL_ASSOC)) {
18   echo "\t<tr>\n";
19   foreach ($line as $col_value) {
20   echo "\t\t<td>;$col_value</td>\n";
21   }
22 echo "\t</tr>\n";
23 }
24 echo "</table>\n";
25
26 // Liberamos el resultset
27 pg_free_result($result);
28
29 // Cerramos la conexión
30 pg_close($link);
31 ?&gt;

 

Recordad
La mayoría de los errores
en este aspecto se originan por una mala configuración de los permisos de los usuarios en el SGBD. Una forma de probarlo que suele ofrecer más informa- ción es intentar la conexión con el cliente de la base de datos desde la línea de comandos, es- pecificando el mismo usuario, base de datos y contraseña que estamos utilizando en el script.

En las diez primeras líneas, establecemos la conexión y comprobamos que se ha realizado correctamente.

A diferencia de MySQL, la selección de la base de datos se hace en el momento de la conexión. En cambio, la comprobación de la conexión es un poco más complicada.

Para   establecer   una   conexión   persistente,   debemos   utilizar   la   función pg_pconnect() con los mismos parámetros.

A continuación, se utiliza la función pg_query() para lanzar la consulta a la base de datos.

Para comprobar errores, la API de PostgreSQL distingue entre un error de conexión, y errores sobre los recursos devueltos. En el primer caso, deberemos usar pg_connection_status(), mientras que en el segundo podemos optar por pg_last_error() o bien pg_result_error($recurso) para obtener el mensaje de error que pueda haber devuelto un recurso en concreto.

 

La función pg_query() puede devolver los siguientes resultados:

Utilidad de la sentencia de conexión
Aquí se aplican los mismos consejos que dábamos en el apartado anterior, y las mismas consideraciones en cuanto al parámetro $link y su opcionalidad si únicamente tenemos una conexión establecida con
el mismo usuario y contraseña.

•    FALSE si ha habido un error.

•    Una referencia a una estructura si la sentencia ha tenido éxito.

La función pg_affected_rows($recurso) nos permite conocer el número de filas que se han visto afectadas por sentencias de actualización, borrado o inserción. Esta función deberá recibir como parámetro el recurso devuelto por la función pg_query().

La función pg_num_rows($recurso) nos permite conocer el número de filas devuelto por sentencias de consulta.

Una vez obtenido el recurso a partir de los resultados de la consulta, PHP proporciona multitud de formas de iterar sobre sus resultados o de acceder a uno de ellos directamente. Comentamos las más destacadas:

•    $fila = pg_fetch_array($recurso, <tipo_de_array>)

Esta función va iterando sobre el recurso, devolviendo una fila cada vez, hasta que no quedan más filas y devuelve FALSE. La forma del array devuelto, dependerá del parámetro <tipo_de_array> que puede tomar estos valores:

•    PG_NUM: devuelve un array con índices numéricos para los campos. Es decir, en $fila[0] tendremos el primer campo del SELECT, en $fila[1],
el segundo, etc.

•    PG_ASSOC: devuelve un array asociativo donde los índices son los nombres de campo o alias que hayamos indicado en la sentencia SQL.

•    PG_BOTH: devuelve un array con los dos métodos de acceso.

 

Recuperando el ejemplo inicial, entre las líneas 11 y 24:

 

11 // Realizando una consulta SQL
12 $query = `SELECT * FROM mi_tabla´;
13 $result = pg_query($query,$link) or die(`Consulta errónea: ´ . pg_last_error());
14// Mostramos los resultados en HTML
15 echo `<table>\n´;
16 while ($line = pg_fetch_array($result, PGSQL_BOTH)) {
17   echo "\t<tr>\n";
18   for($i=0;$i&lt;sizeof($line);$i++) {
19   echo "\t\t<td>$line[$i]</td>\n";
20   }
21   echo "<td>Nombre: $line[`nombre´]</td>";
22   echo "\t</tr>\n";
23 }
24 echo "</table>\n";

•    $objeto = pg_fetch_object($recurso)

Esta función va iterando sobre los resultados, devolviendo un objeto cada vez, de forma que el acceso a los datos de cada campo se realiza por medio de las propiedades del objeto. Al igual que en el array asociativo, hay que vigilar con los nombres de los campos en consulta, evitando que devuelva campos con el mismo nombre fruto de combinaciones de varias tablas, ya que sólo podremos acceder al último de ellos.

Volvemos sobre el ejemplo inicial

11 // Realizando una consulta SQL
12 $query = `SELECT nombre,apellidos FROM mi_tabla´;
13 $result = pg_query($query,$link) or die(`Consulta errónea: ´ . pg_last_error());
14 // Mostramos los resultados en HTML
15 echo `<table>\n´;
16 while ($object = pg_fetch_array($result, PGSQL_BOTH)) {
17   echo "\t<tr>\n";
18   echo "<td>Nombre: " . $object-&gt;nombre . "</td>";
19   echo "<td>Apellidos: " . $object-&gt;apellidos . "</td>";
20   echo "\t</tr>\n";
21 }
22 echo "</table>\n";

Podemos pasar a la función pg_fetch_object() un segundo parámetro para indicar la fila concreta que queremos obtener:

$resultado = pg_fetch_all($recurso)

 

Esta función devuelve toda la hoja de datos correspondiente a $recurso; es decir, una array con todas las filas y columnas que forman el resultado de la consulta.

•    $exito = pg_result_seek($recurso,$fila)

Esta función permite mover el puntero dentro de la hoja de resultados representada por $recurso hasta la fila que deseemos. Deben tomarse las mismas consideraciones que en la función mysql_data_seek().

En cuanto a la liberación de recursos y la desconexión de la base de datos, es totalmente aplicable lo explicado para MySQL, incluyendo los aspectos relacionados con las conexiones persistentes.

Al igual que en MySQL, PHP también proporciona funciones específicas para trabajar con algunos aspectos particulares de PostgreSQL. Al tener éste más funcionalidad que se aleja de lo estándar debido a su soporte a objetos, estas funciones cobrarán más importancia.  A continuación  comentamos las más destacadas:

•    pg_field_name, pg_field_num, pg_field_size, pg_field_type: estas funciones  proporcionan información sobre los campos  que  integran una consulta. Sus nombres son suficientemente explícitos acerca de su cometido.

•    pg_last_oid: esta función nos devuelve el OID obtenido por la inserción de una tupla si el recurso que recibe como parámetro es el correspondiente a una sentencia INSERT. En caso contrario devuelve FALSE.

•    pg_lo_create,    pg_lo_open,    pg_lo_export,    pg_lo_import, pg_lo_read, pg_lo_write: estas funciones (entre otras) facilitan el trabajo con objetos grandes (LOB) en PostgreSQL.

&lt;?php
$database = pg_connect("dbname=jacarta");
pg_query($database, "begin");
$oid = pg_lo_create($database);
echo "$oid\n";
$handle = pg_lo_open($database, $oid, "w");
echo "$handle\n";
pg_lo_write($handle, "large object data");
pg_lo_close($handle);
pg_query($database, "commit");
?&gt;

Las funciones pg_lo_import y pg_lo_export pueden tomar ficheros como parámetros, facilitando la inserción de objetos binarios en la base de datos.