14 de abril de 2015

Apuntes PDO PHP

PDO proporciona una capa de abstracción de acceso a datos, lo que significa que, independientemente de la base de datos que se esté utilizando, se usan las mismas funciones para realizar consultas y obtener datos. Para cada base de datos existe un manejador (driver) específico, que debe estar habilitado en el archivo de configuración de PHP (el archivo php.ini). Los manejadores se administran mediante extensiones de PHP, las cuales tienen nombres finalizando con dll en Windows y con so en Unix.
extension=php_pdo.dll
extension=php_pdo_firebird.dll
extension=php_pdo_informix.dll
extension=php_pdo_mssql.dll
extension=php_pdo_mysql.dll
extension=php_pdo_oci.dll
extension=php_pdo_oci8.dll
extension=php_pdo_odbc.dll
extension=php_pdo_pgsql.dll
extension=php_pdo_sqlite.dll
Ejemplo conexiones PDO
<?php
try {
 // Conexión a MS SQL Server 
  $cnn = new PDO("mssql:host=$host;dbname=$dbname, $user, $pass");
  
  // Conexión a Sybase
  $cnn = new PDO("sybase:host=$host;dbname=$dbname, $user, $pass");
 
  // Conexion a MySQL 
  $DBH = new PDO("mysql:host=$host;dbname=$dbname", $user, $pass);
 
  // Conexion a SQLite
  $DBH = new PDO("sqlite:my/database/path/database.db");
}
catch(PDOException $e) {
    echo $e->getMessage();
}
?>
Conexion PDO-MySQL
<?php
try{
        $this->db = new PDO(DB_MOTOR.':host='.DB_HOST.';dbname='.DB_NAME, DB_USER, DB_PASS);
        $this->db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
        $this->db->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
        $this->db->setAttribute(PDO::ATTR_PERSISTENT,true);
        $this->db->setAttribute(PDO::MYSQL_ATTR_INIT_COMMAND, "SET NAMES 'utf8'");
   
   }catch(PDOException $e){
         echo 'Ha surgido un error y no se puede conectar a la base de datos' .E_USER_ERROR. PHP_EOL;
         echo "";
         echo "Detalle: ".$e->getMessage();
         exit;
      }
?>
Ejemplo Excepciones PDO
$cnn->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_SILENT );
$cnn->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_WARNING );
$cnn->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION );
es mas util la opcion ERRMODE_EXCEPTION, aqui el ejemplo
try {
  $cnn = new PDO("mysql:host=$host;dbname=$dbname", $user, $pass);
  $cnn->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION );
 
  $cnn->prepare('DELECT name FROM people');
}
catch(PDOException $e) {
    echo "Error en la consulta";
    file_put_contents('PDOErrors.txt', $e->getMessage(), FILE_APPEND);
}
Ejemplo de sentencia SELECT
$sql= "SELECT filmID, filmName, filmDescription, filmImage, filmPrice, filmReview FROM movies WHERE filmID = :filmID"; 
$stmt = $pdo->prepare($sql);
$stmt->bindParam(':filmID', $filmID, PDO::PARAM_INT); 
$stmt->execute();
$obj = $stmt->fetchObject();
echo $obj->filmName;
Ejemplo de Unnamed Placeholders
Es necesario mantener el orden al momento de especificar los valores de la sentencia
<?php
 ini_set('display_errors', '0');
 include_once('connect.php');
 include_once('error_handling.php');

 $team = 'Yamaha';
 $status = 'Factory';

 $sqlQuery = "SELECT * from riders where team = ? AND status = ?";

 $statement = $dbh->prepare($sqlQuery);

 $statement->bindValue('1', $team, PDO::PARAM_STR); 
 $statement->bindValue('2', $status, PDO::PARAM_STR); 

 try{
  $statement->execute();
 }
 catch(PDOException $error){
  echo errorHandling($error);
 }
 while($row = $statement->fetch(PDO::FETCH_ASSOC)) {
  echo $row['name'] . " rides a " . $row['team'] . " " . $row['status'] . " MotoGP bike!
";
 }
?>
Ejemplo de Named Placeholders
No es necesario estar pendiente del orden de los parámetros pero si de especificar adecuadamente el par clave=>valor.
<?php
 ini_set('display_errors', '0');
 include_once('connect.php');
 include_once('error_handling.php');

 $team = 'Yamaha';
 $status = 'Factory';

 $sqlQuery = "SELECT * from riders where team = :team AND status = :status";

 $statement = $dbh->prepare($sqlQuery);

 $statement->bindParam(':team', $team, PDO::PARAM_STR);
 $statement->bindParam(':status', $status, PDO::PARAM_STR);

 try{
  $statement->execute();
 }
 catch(PDOException $error){
  echo errorHandling($error);
 }
 while($row = $statement->fetch(PDO::FETCH_ASSOC)) {
  echo $row['name'] . " rides a " . $row['team'] . " " . $row['status'] . " MotoGP bike!
";
 }
?>
Ejemplo Sentencia INSERT
<?php
$nom = 'Jose';
$ape = 'Hernandez';
 
try
{
  $con = new PDO('mysql:host=localhost;dbname=personal', 'user', 'pass');
  $con->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
 
  $stmt = $con->prepare('INSERT INTO personal (nombre, apellidos) VALUES (:nombre, :apellidos)');
  $rows = $stmt->execute( array( ':nombre'   => $nom,
                                    ':apellidos' => $ape));
 
  if( $rows == 1 )
    echo 'Inserción correcta';
}
catch(PDOException $e)
{
  echo 'Error: ' . $e->getMessage();
}
?>
Ejemplo Sentencia UPDATE
<?php
$nom = 'Jose';
$ape = 'Hernandez';
 
try
{
  $con = new PDO('mysql:host=localhost;dbname=personal', 'user', 'pass');
  $con->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
 
  $stmt = $con->prepare('UPDATE personal SET apellidos = :apellidos WHERE nombre = :nombre');
  $rows = $stmt->execute( array( ':nombre'   => $nom,
                                    ':apellidos' => $ape));
  if( $rows > 0 )
    echo 'Actualización correcta';
}
catch(PDOException $e)
{
  echo 'Error: ' . $e->getMessage();
}
?>
Ejemplo Sentencia DELETE
<?php
$ape = 'Hernandez';
 
try
{
  $con = new PDO('mysql:host=localhost;dbname=personal', 'user', 'pass');
  $con->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
 
  $stmt = $con->prepare('DELETE FROM personal WHERE apellidos = :apellidos');
  $rows = $stmt->execute( array( ':apellidos' => $ape));
 
  if( $rows > 0 )
    echo 'Borrado correcto';
}
catch(PDOException $e)
{
  echo 'Error: ' . $e->getMessage();
}
?>
Mapeo de Objetos
PDO nos permite realizar consultas y mapear los resultados en objetos de nuestro modelo. Para ello primero tenemos que crearnos una clase con nuestro modelo de datos.
<?php
// la clase puede estar en una
// ubicación o folder especifico 

class Usuario{
  private $nombre;
  private $apellidos;
 
  public function nombreApellidos()
  {
    return $this->nombre . ' ' . $this->apellidos;
  }
}
?>
como ejemplo se utilizara una sentencia SELECT, Hay que tener en cuenta que para que funcione correctamente, el nombre de los atributos en nuestra clase tienen que ser iguales que los que tienen las columnas en nuestra tabla de la base de datos. Con esto claro vamos a realizar la consulta.
<?php
try
{
  $con = new PDO('mysql:host=localhost;dbname=personal', 'user', 'pass');
  $con->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
 
 $stmt= $con->prepare('SELECT nombre, apellidos FROM personal');
  $stmt->execute();
 
  $stmt->setFetchMode(PDO::FETCH_CLASS, 'Usuario');
 
  while($usuario = $stmt->fetch())
    echo $usuario->nombreApellidos() . '
';
 
}
catch(PDOException $e)
{
  echo 'Error: ' . $e->getMessage();
}
?>
Ejemplo INSERT con Object Mapping
<?php
class person {
    public $name;
    public $addr;
    public $city;
 
    function __construct($n,$a,$c) {
        $this->name = $n;
        $this->addr = $a;
        $this->city = $c;
    }
    # etc ...
}
 
$cathy = new person('Cathy','9 Dark and Twisty','Cardiff');
 
$STH = $DBH->("INSERT INTO folks (name, addr, city) value (:name, :addr, :city)");
$STH->execute((array)$cathy);
?>
FETCHMODE en consultas SELECT Utilizando query() y PDO::FETCH_NUM
<?php
$sql = 'SELECT name, colour, calories FROM fruit';
try {
  $stmt = $dbh->query($sql);
  $result = $stmt->setFetchMode(PDO::FETCH_NUM);
  while ($row = $stmt->fetch()) {
    print $row[0] . "\t" . $row[1] . "\t" . $row[2] . "\n";
  }
}
catch (PDOException $e) {
  print $e->getMessage();
}
?>
Utilizando query() y PDO::FETCH_ASSOC
<?php
$stmt = $dbh->prepare("SELECT mykey, myvalue FROM mytable");
$stmt->setFetchMode(PDO::FETCH_ASSOC);
$arrValues = $stmt->fetchAll();
foreach ($arrValues as $row){
    print $row["mykey"]." -> ".$row["myvalue"]."
\n";
}
?>
Utilizando query() y PDO::FETCH_OBJ
<?php
$STH = $DBH->query('SELECT name, addr, city from folks'); 

$STH->setFetchMode(PDO::FETCH_OBJ);
 
while($row = $STH->fetch()) {
    echo $row->name . "\n";
    echo $row->addr . "\n";
    echo $row->city . "\n";
}
?>
Utilizando Unnamed Placeholders, execute() y PDO::FETCH_ASSOC
<?php
try {
    $conn = new PDO("mysql:host=$host;dbname=$dbname", $username, $password);
 
    $sql = 'SELECT lastname, firstname, jobtitle 
            FROM employees
            WHERE lastname LIKE ?';
 
    $q = $conn->prepare($sql);
    $q->execute(array('%son'));
    $q->setFetchMode(PDO::FETCH_ASSOC);
 
    while ($r = $q->fetch()) {
        echo sprintf('%s 
', $r['lastname']);
    }
} catch (PDOException $pe) {
    die("Could not connect to the database $dbname :" . $pe->getMessage());
}
?>
Utilizando Named Placeholders, execute() y PDO::FETCH_ASSOC
<?php
try {
    $conn = new PDO("mysql:host=$host;dbname=$dbname", $username, $password);
 
    $sql = 'SELECT lastname, firstname, jobtitle 
            FROM employees
            WHERE lastname  LIKE :lname OR
                  firstname LIKE :fname';
 
    $q = $conn->prepare($sql);
    $q->execute(array(':fname' => 'Le%',
                      ':lname' => '%son'));
    $q->setFetchMode(PDO::FETCH_ASSOC);
 
    while ($r = $q->fetch()) {
        echo sprintf('%s 
', $r['lastname']);
    }
} catch (PDOException $pe) {
    die("Could not connect to the database $dbname :" . $pe->getMessage());
}
?>
Transacciones en PDO
Debido a que no todas las bases de datos soportan transacciones, PHP corre en el modo de auto-commit que ejecuta cada instrucción individual en forma implícita. Si se desea usar transacciones, y no se desea utilizar el modo de auto-commit, es necesario invocar el método PDO::beginTransaction()al inicio de la transacción. Si el manejador de la base de datos no permite el uso de transacciones se producirá una excepción (PDOException). Cuando se acabe de especificar la transacción se pueden utilizar los métodos PDO::Commit para aplicar dichas instrucciones, o bien, PDO::rollBack para abortar dicha transacción.

<?php
try {
  $stmt = $dbh->prepare("INSERT INTO countries (name, area, population, density)
                                VALUES (:name, :area, :population, :density)");
  $stmt->bindParam(':name', $name);
  $stmt->bindParam(':area', $area);
  $stmt->bindParam(':population', $population);
  $stmt->bindParam(':density', $density);

  $dbh->beginTransaction();
  $name = 'Nicaragua'; $area = 129494; $population = 602800; $density = 46.55;
  $stmt->execute();
  $name = 'Panama'; $area = 78200; $population = 3652000; $density = 46.70;
  $stmt->execute();
  $dbh->commit();

} catch (Exception $e) {
  $dbh->rollBack();
  echo "Failed: " . $e->getMessage();
}
?>
o bien este ejemplo en que se utiliza un array para especificar los valores de la consulta
<?php
try {
  $stmt = $dbh->prepare("INSERT INTO countries (name, area, population, density)
                                VALUES (?, ?, ?, ?)");

  $dbh->beginTransaction();
  $stmt->execute(array('Nicaragua', 129494, 602800, 46.55));
  $stmt->execute(array('Panama', 78200, 3652000, 46.70));
  $dbh->commit();

} catch (Exception $e) {
  $dbh->rollBack();
  echo "Failed: " . $e->getMessage();
}
?>

Related Posts:

  • Metodos __get() y __set() PHPEste es un ejemplo de los métodos mágicos __set() y __get() en una clase con sus respectivas validaciones utilizando el método property_exists <?php class Objeto { private $id; private $nombre; private $ema… Read More
  • Buscador PHP Jquery AJAX JSONPara ejemplificar el uso de las tecnologias PHP-Jquery-AJAX-JSON se muestra la codificación de un buscador realizado en PHP que utiliza Jquery con su metodo $.ajax para hacer peticiones asincrónicas sobre una base de datos M… Read More
  • Resaltar sintaxis PHP en navegadoresA veces debes mostrar tu código php en el navegador de tu red interna para que otras personas puedan revisarlo y crear un complemento a codificar un modulo que implemente tu función, que herede de tu clase, que utilice tu int… Read More
  • Buscador PHP utilizando MySQLiAntes de empezar hago la acotación que este es un ejemplo básico pero que aun se utiliza, lo mejor seria utilizar Jquery para utilizar AJAX y recibir los mensajes vía JSON, también utilizar Jquery Validate para el campo oblig… Read More
  • Autocarga de clases __autoload() PHPCuando se escriben aplicaciones orientadas a objetos en PHP los archivos con las clases generalmente van dentro de una carpeta especifica, de esto saca ventaja la función __autoload para crear instancias de esas clases, __aut… Read More