PDO (PHP Data Objects) es la forma recomendada de conectarse a bases de datos en PHP. Ofrece una interfaz consistente para distintos motores (MySQL/MariaDB, PostgreSQL, SQLite, etc.), soporte de prepared statements y manejo de errores robusto.
| Motor | Ejemplo DSN | Notas |
|---|---|---|
| MySQL / MariaDB | mysql:host=localhost;dbname=miapp;charset=utf8mb4 |
Usar utf8mb4 para soportar todos los caracteres (emojis, etc.). |
| PostgreSQL | pgsql:host=localhost;port=5432;dbname=miapp |
El charset se configura con SET NAMES o al crear la BD. |
| SQLite | sqlite:/ruta/absoluta/miapp.sqlite |
BD basada en archivo. Asegurar permisos de escritura/lectura. |
<?php
declare(strict_types=1);
$dsn = 'mysql:host=localhost;dbname=miapp;charset=utf8mb4';
$user = 'usuario_app';
$pass = 'secreto';
try {
$pdo = new PDO($dsn, $user, $pass, [
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, // Excepciones en errores
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC, // fetch como array asociativo
PDO::ATTR_EMULATE_PREPARES => false, // prepared reales
]);
echo "✅ Conectado a MySQL/MariaDB";
} catch (PDOException $e) {
// No exponer credenciales ni DSN en producción
echo "❌ Error de conexión: " . $e->getMessage();
}
?>
<?php
$dsn = 'pgsql:host=localhost;port=5432;dbname=miapp';
$user = 'usuario_app';
$pass = 'secreto';
try {
$pdo = new PDO($dsn, $user, $pass, [
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
]);
// Charset (opcional): $pdo->exec("SET NAMES 'UTF8'");
echo "✅ Conectado a PostgreSQL";
} catch (PDOException $e) {
echo "❌ Error de conexión: " . $e->getMessage();
}
?>
<?php
$dsn = 'sqlite:' . __DIR__ . '/data/miapp.sqlite';
try {
$pdo = new PDO($dsn, null, null, [
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
]);
echo "✅ Conectado a SQLite";
} catch (PDOException $e) {
echo "❌ Error de conexión: " . $e->getMessage();
}
?>
Ejemplo de SELECT con prepared statement (seguro contra inyección SQL):
<?php
// Suponiendo $pdo conectado
$stmt = $pdo->prepare('SELECT id, nombre, email FROM usuarios WHERE id = :id');
$stmt->execute([':id' => 1]);
$usuario = $stmt->fetch();
if ($usuario) {
echo "Usuario: " . $usuario['nombre'] . " (" . $usuario['email'] . ")";
} else {
echo "No se encontró el usuario";
}
?>
Siempre usá try/catch y PDO::ERRMODE_EXCEPTION para capturar errores correctamente.
<?php
try {
$pdo->beginTransaction();
$stmt = $pdo->prepare('INSERT INTO usuarios (nombre, email) VALUES (:n, :e)');
$stmt->execute([':n' => 'Pablo', ':e' => 'pablo@mail.com']);
$pdo->commit();
echo "✅ Insert ok";
} catch (Throwable $ex) {
$pdo->rollBack();
// Log real: error_log($ex->getMessage());
echo "❌ Ocurrió un error. Intente de nuevo.";
}
?>
root para la app).| Problema | Causa probable | Solución |
|---|---|---|
could not find driver |
Extensión PDO del motor no habilitada | Activar pdo_mysql / pdo_pgsql / pdo_sqlite en php.ini y reiniciar el servidor |
| Caracteres raros | Charset no configurado | Usar charset=utf8mb4 (MySQL) o SET NAMES 'UTF8' (PostgreSQL) |
| Permisos denegados | Usuario/rol sin permisos para la DB | Otorgar permisos mínimos requeridos (SELECT/INSERT/UPDATE/DELETE) |
| Timeout / No conecta | Host/puerto incorrectos o servicio caído | Verificar DNS/puerto, firewall y que MySQL/PG esté iniciado |