Consulta a través de la extensión del controlador PHP Data Objects

La extensión del controlador PHP Data Objects (PDO) viene con PHP por defecto, desde PHP 5.1.0.

Conectando

Usando la extensión del controlador PDO, podemos conectarnos a una base de datos MySQL desde PHP usando la clase PDO, de la siguiente manera:

<?php
$host = '127.0.0.1';
$dbname = 'sakila';
$username = 'root';
$password = 'mL08e!Tq';
$conn = new PDO(
"mysql:host=$host;dbname=$dbname",
$username,
$password
);

Esta simple expresión multilínea buscará MySQL en el host 127.0.0.1 e intentará conectarse a su base de datos sakila utilizando el nombre de usuario root y la contraseña mL08e!Tq.

Manejo de errores

Los errores de manejo alrededor de PDO se pueden hacer usando la clase especial PDOException, de la siguiente manera:

<?php
try {
$host = '127.0.0.1';
$dbname = 'sakila';
$username = 'root';
$password = 'mL08e!Tq';
$conn = new PDO(
"mysql:host=$host;dbname=$dbname",
$username,
$password,
[PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION]
);
} catch (PDOException $e) {
echo $e->getMessage(), PHP_EOL;
}

Hay tres modos de error diferentes:

  • ERRMODE_SILENT
  • ERRMODE_WARNING
  • ERRMODE_EXCEPTION

Aquí, estamos utilizando ERRMODE_EXCEPTION para utilizar los bloques try … catch.

Seleccionando

La consulta de registros con PDO es algo similar a la consulta de registros con mysqli.
Utilizamos declaraciones SQL sin procesar en ambos casos. La diferencia radica en la conveniencia de los métodos PHP y las sutiles diferencias que proporcionan. El siguiente ejemplo demuestra cómo podemos seleccionar registros de una tabla MySQL:

<?php
try {
$conn = new PDO(
"mysql:host=127.0.0.1;dbname=sakila", 'root', 'mL08e!Tq',
[PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION]
);
$result = $conn->query('SELECT * FROM customer LIMIT 5');
$customers = $result->fetchAll(PDO::FETCH_OBJ);
foreach ($customers as $customer) {
echo $customer->first_name, ' ', $customer->last_name, PHP_EOL;
}
} catch (PDOException $e) {
echo $e->getMessage(), PHP_EOL;
}

Esto da el siguiente resultado:

La instancia del objeto PDOStatement y $result tiene varios métodos diferentes de obtención de resultados:

  • fetch(): recupera la siguiente fila de un conjunto de resultados, permite ser llamada repetidamente y devuelve un valor según el estilo de búsqueda
  • fetchAll(): recupera todas las filas del conjunto de resultados como una matriz y devuelve un valor según el estilo de recuperación
  • fetchObject(): recupera la siguiente fila de un conjunto de resultados como un objeto y permite que se llame repetidamente
  • fetchColumn (): recupera una sola columna de la siguiente fila de un conjunto de resultados y permite que se llame repetidamente

La siguiente lista muestra los estilos de búsqueda de PDO disponibles:

  • PDO::FETCH_LAZY
  • PDO::FETCH_ASSOC
  • PDO::FETCH_NUM
  • PDO::FETCH_BOTH
  • PDO::FETCH_OBJ
  • PDO::FETCH_BOUND
  • PDO::FETCH_COLUMN
  • PDO::FETCH_CLASS
  • PDO::FETCH_INTO
  • PDO::FETCH_FUNC
  • PDO::FETCH_GROUP
  • PDO::FETCH_UNIQUE
  • PDO::FETCH_KEY_PAIR
  • PDO::FETCH_CLASSTYPE
  • PDO::FETCH_SERIALIZE
  • PDO::FETCH_PROPS_LATE
  • PDO::FETCH_NAMED

Si bien la mayoría de estos estilos de búsqueda son bastante explicativos, podemos
consultar http://php.net/manual/en/pdo.constants.php para más detalles.

El siguiente ejemplo demuestra un enfoque de selección más elaborado, uno con enlace de parámetros en la mezcla:

<?php
try {
$conn = new PDO(
"mysql:host=127.0.0.1;dbname=sakila", 'root', 'mL08e!Tq',
[PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION]
);
$statement = $conn->prepare('SELECT * FROM customer
WHERE customer_id > :customer_id AND store_id = :store_id AND email
LIKE :email');
$statement->execute([
':customer_id' => 100,
':store_id' => 2,
':email' => '%ANN%',
]);
$customers = $statement->fetchAll(PDO::FETCH_OBJ);
foreach ($customers as $customer) {
echo $customer->first_name, ' ', $customer->last_name, PHP_EOL;
}
} catch (PDOException $e) {
echo $e->getMessage(), PHP_EOL;
}

Esto da el siguiente resultado:

La diferencia más obvia entre el enlace con PDO y el enlace con mysqli es que PDO permite el enlace de parámetros con nombre. Esto hace que las consultas sean mucho más legibles.

Insertar

Al igual que la selección, la inserción implica el mismo conjunto de métodos PDO envueltos alrededor de la instrucción INSERT INTO SQL:

<?php
try {
$conn = new PDO(
"mysql:host=127.0.0.1;dbname=sakila", 'root', 'mL08e!Tq',
[PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION]
);
$statement = $conn->prepare('INSERT INTO address (
address,
district,
city_id,
postal_code,
phone,
location
) VALUES (
:address,
:district,
:city_id,
:postal_code,
:phone,
POINT(:longitude, :latitude)
);
');
$statement->execute([
':address' => 'The street',
':district' => 'The district',
':city_id' => '537',
':postal_code' => '31000',
':phone' => '888777666333',
':longitude' => 45.55111,
':latitude' => 18.69389
]);
} catch (PDOException $e) {
echo $e->getMessage(), PHP_EOL;
}

Actualización

Al igual que seleccionar e insertar, la actualización implica el mismo conjunto de métodos PDO envueltos alrededor de la instrucción UPDATE SQL:

<?php
try {
$conn = new PDO(
"mysql:host=127.0.0.1;dbname=sakila", 'root', 'mL08e!Tq',
[PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION]
);
$statement = $conn->prepare('UPDATE address SET phone = :phone WHERE
address_id = :address_id');
$statement->execute([
':phone' => '888777666555',
':address_id' => 600,
]);
} catch (PDOException $e) {
echo $e->getMessage(), PHP_EOL;
}

Borrando

Al igual que seleccionar, insertar y actualizar, la eliminación implica el mismo conjunto de métodos PDO envueltos alrededor de la declaración DELETE FROM SQL:

<?php
try {
$conn = new PDO(
"mysql:host=127.0.0.1;dbname=sakila", 'root', 'mL08e!Tq',
[PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION]
);
$statement = $conn->prepare('DELETE FROM payment WHERE payment_id =
:payment_id');
$statement->execute([
':payment_id' => 16046
]);
} catch (PDOException $e) {
echo $e->getMessage(), PHP_EOL;
}

Transacciones

Las transacciones con PDO no son muy diferentes de aquellas con MySQLi. Al utilizar los métodos beginTransaction (), commit () y rollback () de la instancia PDO, podemos controlar las características de transacción de MySQLi:

<?php
$conn = new PDO(
"mysql:host=127.0.0.1;dbname=sakila", 'root', 'mL08e!Tq',
[PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION]
);
try {
// Iniciar nueva transacción
$conn->beginTransaction();
// Crear nueva dirección
$result = $conn->query('INSERT INTO address (
address,
district,
city_id,
postal_code,
phone,
location
) VALUES (
"The street",
"The district",
537,
"27107",
"888777666555",
POINT(45.55111, 18.69389)
);
');
// Fetch newly created address id
$addressId = $conn->lastInsertId();
// Crear nuevo cliente
$statement = $conn->prepare('INSERT INTO customer (
store_id,
first_name,
last_name,
email,
address_id
) VALUES (
2,
"John",
"Doe",
"john-pdo@test.it",
:address_id
)
');
$statement->execute([':address_id' => $addressId]);
// Recuperar ID de cliente recién creado
$customerId = $conn->lastInsertId();
// Seleccione la información del cliente recién creada
$statement = $conn->prepare('SELECT * FROM customer WHERE customer_id =
:customer_id');
$statement->execute([':customer_id' => $customerId]);
$customer = $statement->fetchObject();
// Confirmar transacción
$conn->commit();
echo $customer->first_name, ' ', $customer->last_name, PHP_EOL;
} catch (PDOException $e) {
$conn->rollback();
echo $e->getMessage(), PHP_EOL;
}

Comparte