5.2. Conectividad orientada a objetos con bases de datos

Actualmente Php ha declarado obsoleta su API clásica de conexión MySQL para proyectos que usen versiones de Php superiores a la 5.5.0. No obstante existen otras dos APIs de integración, llamadas MySQLi y PDO_MySQL. Se muestra aquí las características de codificación de estas API.

MySQLi Object-oriented

<!doctype html>
<html lang='es'>
<head>
  <meta charset='utf-8'>
  <meta name='viewport' content='width=device-width, initial-scale=1'>
  <meta http-equiv='x-ua-compatible' content='ie=edge'>
  <title>Conectividad</title>
  <link href='https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css' rel='stylesheet'>
</head>
<body>
<div class='container'>
<?php
  $ruta      = 'localhost';
  $login     = 'tuLogin';
  $key       = 'tuPassword';
  $db        = 'tuBD';
  
  // Creamos la conexión
  $conexion  = new mysqli( $ruta, $login, $key, $db);
  // Checamos la conexión
  if ($conexion->connect_error) {
    die("Fallo de conexión: " . $conexion->connect_error);
  }
  $sql = 'SELECT * FROM f1 ORDER BY year DESC';
  // Ejecutamos la sentencia sql
  $registros = $conexion->query($sql);
  // Cerramos la conexión
  $conexion->close();

  if ( $registros->num_rows > 0) {
      
    // output data of each row
     $html = '<table class="table table-bordered table-condensed table-condensed">';
     $html .= '<caption class="text-center">Campeones de Formula 1</caption>';
	 $html.= '<thead><tr><th>Año</th>';
	 $html.= '<th class="text-center">Campeón</th>';
	 $html.= '<th class="text-center">Escudería</th>';
	 $html.= '</tr></thead>';
	 $html.= '<tbody>';


    while($registro = $registros->fetch_assoc()) {
      $html .= '<td>'. $registro['year'].'</td>';
      $html .= '<td>'. $registro['campeon'].'</td>';
      $html .= '<td>'. $registro['escuderia'].'</td></tr>';
    }
    $html.= '</tbody>';
    $html .= '</table>';
    echo $html;	
  } else {
    $html= 'Sin Registros';
  }
?>
</div>
</body>
</html>

PDO (PHP Data Objects)

Al usar PDO damos solución a las debilidades de API de MySQL. Un par de ventajas que se obtienen con PDO es que el proceso de escapado de los parámetros es sumamente sencillo y sin la necesidad de estar atentos a utilizar en todos los casos funciones para este cometido como mysql_real_escape_string(). Otra ventaja es que PDO es una API flexible y nos permite trabajar con cualquier tipo de base de datos y no estar restringidos a utilizar MySql.

<?php
  $conexion = new PDO('mysql:host=localhost;dbname=nombreBaseDatos', 'user', 'pass');
  $conexion->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
?>

Los posibles valores que se le podría asignar a ATTR_ERRMODE son:


Nuestro código de conexión luce así.

<?php
  try {
    $conexion = new PDO('mysql:host=localhost;dbname=nombreBaseDatos', 'user', 'pass');
    $conexion->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
  } catch(PDOException $e) {
    echo 'Error conectando con la base de datos: ' . $e->getMessage();
  }
?>

Seleccionar datos con PDO

<!doctype html>
<html lan='es'>
<head>
  <meta charset='utf-8'>
  <meta name='viewport' content='width=device-width, initial-scale=1'>
  <meta http-equiv='x-ua-compatible' content='ie=edge'>
  <title>Conectividad PDO</title>
  <link href='https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css' rel='stylesheet'>
</head>
<body>
<div class='container'>
<?php
  function cabeza() {
    $html = '<table class="table table-bordered table-condensed table-condensed">';
    $html.= '<caption class="text-center">Campeones de Formula 1</caption>';
    $html.= '<thead><tr><th>Año</th>';
    $html.= '<th class="text-center">Campeón</th>';
    $html.= '<th class="text-center">Escudería</th>';
    $html.= '</tr></thead>';
    $html.= '<tbody>';
	return $html;
  }

  try {
    include('server.php');
	// Conexión
    $conexion = new PDO("mysql:host=localhost;dbname=$db", $login, $key);
    $conexion->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
	// Ejecutamos la consulta
    $registros = $conexion->query('SELECT * FROM f1 ORDER BY year DESC');
	// Cerramos la conexión
	$conexion = null;
	// Recorremos el conjunto de resultados
    foreach($registros as $registro) {
      $html .= '<td>'. $registro['year'].'</td>';
      $html .= '<td>'. $registro['campeon'].'</td>';
      $html .= '<td>'. $registro['escuderia'].'</td></tr>';
    }
    $html.= '</tbody>';
    $html .= '</table>';
    echo cabeza().$html;	
  } catch(PDOException $e) {
      echo  'Error conectando con la base de datos: ' . $e->getMessage();
  }
?>
</div>
</body>
</html>

Consulta Ajax PDO MySQl

<!DOCTYPE html>
<html lang='es'>
<head>
  <meta charset='utf-8'>
  <meta name='viewport' content='width=device-width, initial-scale=1'>
  <meta http-equiv='x-ua-compatible' content='ie=edge'>
  <title>Paises por continente</title>
  <meta name='Author' content='M.C. Jose Evaristo Pacheco Velasco' /> 
  <meta name='date' content='Marzo 29, 2016'/>
  <link href='https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css' rel='stylesheet'>
  <style>
    .banderas {
		border: 0;
		width: 70px;
	}
  </style>
</head>
<body>
  <div class='container'>  
    <form class='form-horizontal' id='forma' name='forma' method='post'>
    <fieldset>
      <legend>Selecciona el continente</legend>
      
      <div class='form-group'>
        <label class='control-label col-sm-2' for='continente'>Continente</label>
        <div class='col-sm-2'>
          <select name='continente' id='continente'>
            <option value='1'  selected>África</option>
            <option value='2'>América</option>
            <option value='3'>Asia</option>
	        <option value='4'>Europa</option>
	        <option value='5'>Oceanía</option>
	        <option value='6'>Todos los países</option>
          </select>
        </div>
      </div>

    </fieldset>
    </form>
    <div class='row'>     
      <div class='col-sm-offset-2 col-sm-8' id='message'></div>
    </div>    
  </div>
<!--  Script jQuery -->
</body>
</html>
<script src='http://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js'></script>
<script>
$(document).ready(function() { 
  var  idContinente = $('#continente').val();  
  var url  = '0520paises.php?continente='+idContinente;
  $('#message').load( url );
  $('#continente').change(function(event){
	var idContinente = $('#continente').val();
    var url  = '0520paises.php?continente='+idContinente;
    $('#message').load( url );
  });
});
</script>
<?php

  function sinAcentos($cadena) {
	$cadena = utf8_decode($cadena);  
    $no_permitidas = array ('á','é','í','ó','ú','Á','É','Í','Ó','Ú','ñ','À','Ã','Ì','Ò','Ù','Ù',
	                        'à ','è','ì','ò','ù','ç','Ç','â','ê','î','ô','û','Â','Ê','ÃŽ','Ô',
                            'Û','ü','ö','Ö','ï','ä','«','Ò','Ï','Ä','Ë');
    $permitidas = array ('a','e','i','o','u','A','E','I','O','U','n','N','A','E','I','O','U','a','e','i',
	                     'o','u','c','C','a','e','i','o','u','A','E','I','O','U','u','o','O','i','a','e',
                         'U','I','A','E');
    $texto = str_replace($no_permitidas, $permitidas, $cadena);
    return $texto;
  }

  function cabeza($nombreContinente) {
    $html = '<table class="table table-bordered table-condensed table-hover">';
	$html.= '<caption class="text-center">'.$nombreContinente.'</caption>';
    $html.= '<thead><tr>';
	$html.= '<th>Nombre</th>';
	$html.= '<th>Capital</th>';
	$html.= '<th>Superficie<br>Km<sup>2</sup></th>';
	$html.= '<th>Población</th>';
	$html.= '<th>Densidad<br>Hab/Km<sup>2</sup></th>';
	$html.= '<th>Bandera</th>';
	$html.= '</tr></thead>';
	$html.= '<tbody>';	
	return $html;  
  };

  function pie() {
	$html.= '</tbody>';
    $html.= '</table>';
	return $html;  
  };

  function totales( $nombreContinente, $n, $superficie, $poblacion, $densidad ) {
    $html = '<br>';
    $html.= '<table class="table table-bordered table-condensed table-hover">';
    $html.= '<caption class="text-center">Totales</caption>';
    $html.= '<thead><tr>';
    $html.= '<th>Continente</th>';
    $html.= '<th>Países</th>';
    $html.= '<th>Superficie<br>Km<sup>2</sup></th>';
    $html.= '<th>Población<br>Habitantes</th>';
    $html.= '<th>Densidad<br>Hab/Km<sup>2</sup></th>';
    $html.= '</tr></thead>';
    $html.= '<tbody>';
    $html.= '<tr><td>'. $nombreContinente.'</td>';
    $html.= '<td class="text-right">'.$n.'</td>';
    $html.= '<td class="text-right">'. number_format($superficie).' </td>';
    $html.= '<td class="text-right">'. number_format($poblacion).'</td>';
    $html.= '<td class="text-right">'. number_format($densidad,2,'.',',').'</td></tr>';
    $html.= '</tbody></table><br>';
    return $html;
  }

  function consultas( $continente ) {
    switch ($continente) {
      case 1: $nombreContinente = "África"; break;
      case 2: $nombreContinente = "América";  break;
      case 3: $nombreContinente = "Asia";  break;
      case 4: $nombreContinente = "Europa";  break;
      case 5: $nombreContinente = "Oceanía";  break;
      case 6: $nombreContinente = "Los países del Mundo";
    }
    if($continente == 6) {
      // Totales del continente o del mundo
       $sql = 'SELECT * FROM pais ORDER BY densidad DESC, nombre';
    } else {
       $sql = 'SELECT * FROM pais ';
       $sql.= 'WHERE idContinente = :idContinente ';
       $sql.= 'ORDER BY densidad DESC, nombre';
    }
    return array($sql, $nombreContinente);	  
  }// Consultas	 

  if( $_SERVER['REQUEST_METHOD'] == 'GET') {  
     include_once('server.php');
     try {
       $dsn = "mysql:host=localhost;dbname=$db";
       $conexion = new PDO($dsn, $login, $key, array(PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES utf8"));  
       $conexion->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
       $conexion->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
       $continente = $_REQUEST['continente'];
       list($sql, $nombreContinente) = consultas( $continente );
       if($continente == 6 ) {
         $stmt = $conexion->prepare( $sql );
         $stmt->execute();
       } else if($continente >= 1 AND $continente <= 5  ){
          $idContinente = $continente;
          $stmt = $conexion->prepare( $sql );
          $stmt->bindParam(':idContinente', $idContinente, PDO::PARAM_INT);
          $stmt->execute();
       } else exit('Datos no validos');
       $n = $stmt->rowCount();
       $html = '';
       //Totales
       $superficie = $poblacion = $densidad =0;
       while ($registro = $stmt->fetch(PDO::FETCH_ASSOC)) {	   
         $html.=  '<tr>';
         $html.= '<td><b>'. $registro['nombre'].'</b></td>';
         $html.= '<td>'. $registro['capital'].'</td>';
         $html.= '<td class="text-right">'. number_format($registro['superficie']).'</td>';
         $html.= '<td class="text-right">'. number_format($registro['poblacion']).'</td>';
         $html.= '<td class="text-right">'. number_format($registro['densidad'],2,'.',',').'</td>';
         $html.= '<td class="text-center">';
         $html.= '<img alt="" class="banderas center-block" src="../banderas/';
         $html.= sinAcentos($registro['nombre']).'.jpg" ></td></tr>';
         $superficie+= $registro['superficie'];
         $poblacion+=  $registro['poblacion'];
         $densidad+=  $registro['densidad']; 
       }
       echo cabeza($continente).$html.pie();
       echo totales($nombreContinente, $n, $superficie, $poblacion, $densidad);
    } catch(PDOException $e) {
        echo 'Error: ' . $e->getMessage();
    } 
  }
?>