Para realizar la conexión trabajaremos con PHP Data Objects (PDO), lo que nos dará una abstracción de base de datos permitiendo que nuestro script pueda conectar con diferentes manejadores, en nuestro caso usaremos MySQL, bueno ahora si manos a la obra:
Lo primero que creamos es el archivo con la configuración:
config.ini
[MySql]
host = 'localhost'
dbname = 'db'
username = 'root'
password = ''
acá vamos a indicar los parámetros para instanciar el dns de PDO en este caso con MySQL
[CITA]esta pequeña cita es del manual donde nos indica que dns para instanciar PDO, como vemos los todos los parámetros los tenemos dentro de nuestro archivo config.ini.
$db = new PDO ( 'mysql:host=localhost;dbname=<SOMEDB>' , '<USERNAME>' , '<PASSWORD>' );
[/CITA]
ahora hacemos uso de la clase configReader para leer el archivo config.ini y así obtener los parámetros que necesitamos para el dns de nuestra clase
configReader.php
<?php
class ConfigReader
{
private $_config;
public function __construct($archivo)
{
if (!file_exists($archivo)) {
throw new Exception('No se encontro el archivo: '.$archivo);
}
$this->_config = parse_ini_file($archivo, true);
}
public function getConfig()
{
return $this->_config;
}
}
?>
ahora vamos a crear la clase que nos permitirá conectar con MySQL
mysql.php
<?php
final class MySQL extends PDO
{
private $_username;
private $_password;
private $_host;
private $_db;
public function __construct(ConfigReader $config)
{
$config_data = $config->getConfig();
$this->_username = $config_data['MySql']['username'];
$this->_password = $config_data['MySql']['password'];
$this->_host = $config_data['MySql']['host'];
$this->_db = $config_data['MySql']['dbname'];
$this->_dsn = 'mysql:host='.$this->_host.';dbname='.$this->_db;
parent::__construct($this->_dsn, $this->_username, $this->_password);
}
}
?>
si nos damos cuenta esta clase no es extendible ya que tiene la palabra final, ademas exiende directamente de PDO, lo que esta clase hace es la instancia para trabajar con MySQL en PDO, vemos el DNS que colocabamos al principio, los parametros los extraemos de la isntancia de la clase confiReader que pedimos como parametro en el constructor de nuestra clase MySQL.
Ahora vamos a trabajar el patron factory que nos permite instanciar objetos de un subtipo en este caso el subtipo sera MySQL
primero creamos la interface
DbFactory_Interface.php
<?php
interface DbFactory_Interface
{
public static function create($sIniFile);
}
?>
ahora la clase dbfactory que implementa la interface creada anteriormente
dbfactory.php
<?php
error_reporting ( E_ALL );
ini_set ( "display_errors" , 1 );
include("DbFactory_Interface.php");
include("registry.php");
include("ConfiReader.php");
include("db.php");
class DatabaseFactory implements DbFactory_Interface
{
public static function create($sIniFile)
{
$config = new ConfigReader($sIniFile);
$config_data = $config->getConfig();
$database_class = key($config_data);
include($database_class.'.php');
$db = new $database_class($config);
Registry::add($sIniFile, $db);
return $db;
}
}
?>
en este archivo incluimos todas nuestras clases que vamos a utilizar para que nuestra clase de conexion haga el trabajo. Si se fijan dentro de esta clase es utiliza el patron registry para poder realizar diferentes instancias de la clase, ya que la clase si necesitamos conectar con varios manejadores de base de datos podemos hacerlo solo creando el archivo .ini dandole los parametros del DNS de PDO para el manejador con el que deseemos conectar y el archivo con la clase que extiende de PDO donde indicamos con que manejador conectar en nuestro caso MySQL.php, aca le dejo el patron registry
<?php
class registry
{
static private $registry = array();
public function add($name, &$item)
{
if (!self::exists($name)) {
self::$registry[$name] = $item;
return true;
} else {
return false;
}
}
public function exists($name)
{
if (is_string($name)) {
return array_key_exists($name, self::$registry);
} else {
throw new Exception('Registry item\'s name must be a string');
}
}
public function &get($name)
{
if (self::exists($name)) {
$return = self::$registry[$name];
} else {
$return = NULL;
}
return $return;
}
}
?>
pues ahora solo nos falta crear la clase que se va a encargar de ejecutar las sentencias en este caso yo realize una clase para la ejecucion de consultas preparadas de manera que se evite la inyeccion sql ya que es importante el tema de la seguridad.
<?php
#######################################################
# Clace para conexion con db #
# #
# Creado por Carlos Belisario #
# #
# #
# Fecha: 20/11/2010 #
# #
#######################################################
class db
{
/*establese la conexion*/
protected $_conect;
/*trabaja los query*/
protected $_query;
/*resultados de las consultas*/
protected $_row;
protected $_result;
public function __construct()
{
$site_path = realpath(dirname(__FILE__)).DIRECTORY_SEPARATOR.'config.ini';
$this->_conect=DatabaseFactory::create($site_path);
}
/*trae todos los datos de las tablas indicadas en el array tabla*/
public function selectAll($table = array(),$condicion = array(),$relacion = array()){
$result = array();
try{
if(!array($table)){
die("Las Tablas deben de estar en formato arreglo");
}
if(count($table)>1){
foreach($table as $id=>$valor){
if($id==0){
$tablas = $valor." INNER JOIN ".next($table)." ON(".$relacion[$id].")";
}
else{
if($id!=1){
$tablas.= " INNER JOIN ".$valor." ON(".$relacion[$id-1].")";
}
}
}
}
else{
$tablas = $table[0];
}
if(empty($condicion))
{
$sql = "SELECT * FROM $tablas";
$this->_query = $this->_conect->prepare($sql);
$this->_query->execute();
}
else{
foreach($condicion as $key=>$value){
$parametros[] = "$key=?";
$condic[] = $value;
}
$condiciones = implode(" AND ",$parametros);
$sql = "SELECT * FROM $tablas WHERE $condiciones";
$this->_query = $this->_conect->prepare($sql);
$this->_query->execute($condic);
}
while($this->_row = $this->_query->fetch()){
$result[] = $this->_row;
}
return $result;
}
catch(PDOExeption $e){
echo $e->getMessaage();
}
}
/*ejecuta una sentencia de MySQL Preparada usando el formato de PDO*/
public function ejecutarSentencia($query,$parametro = NULL,$return = false)
{
$result=array();
try{
$this->_query = $this->_conect->prepare($query);
$this->_query->execute($parametro);
if($return==true){
while($this->_row = $this->_query->fetch()){
$result[] = $this->_row;
}
return $result;
}
}
catch(PDOExeption $e){
echo $e->getMessaage();
}
}
/*inserta registros en la base de datos*/
public function insert($table,$valores)
{
if(!is_array($valores)){
echo "Los datos deben de estar en formato de arreglo";
}
try{
foreach($valores as $id=>$valor){
$parametros[] = '?';
$campos[] = $id;
$value[] = $valor;
}
$val = implode(",",$parametros);
if(!empty($campos)){
$fields = implode(",",$campos);
$sql = "INSERT INTO $table ($fields) VALUES ($val)";
}
$insert=$this->_conect->prepare($sql);
$insert->execute($value);
}
catch(PDOExeption $e){
echo $e->getMessaage();
}
}
/*Actualiza registros de la base de datos*/
public function update($table,$valores,$condicion)
{
if(!is_array($valores)){
echo "Los datos deben de estar en formato de arreglo";
}
try{
foreach($valores as $id=>$valor){
$parametro[]="$id=?";
$values[]=$valor;
}
foreach($condicion as $key=>$value){
$de=explode(".",$value);
if(count($de)>1){
$parametro_condicion[]="$key=$value";
}
else{
$parametro_condicion[]="$key=?";
$values[]=$value;
}
}
$parm=implode(",",$parametro);
if(count($condiciones)>0){
$condiciones=implode(" AND ",$parametro_condicion);
$sql="UPDATE $table SET $parm WHERE $condiciones";
}
else{
$sql="UPDATE $table SET $parm";
}
$update=$this->_conect->prepare($sql);
$update->execute($values);
}
catch(PDOExeption $e){
echo $e->getMessaage();
}
}
/*borra registros de la base de datos*/
public function deleteAll($table,$condicion = NULL,$return = false)
{
try{
foreach($condicion as $key=>$value){
$de=explode(".",$value);
if(count($de)>1){
$valorCondicion[] = "$key=".$value;
}
else{
$valorCondicion[] = "$key='".$value."'";
}
}
$condiciones = implode(" AND ",$valorCondicion);
$this->_result = $this->_conect->exec("DELETE FROM $table WHERE $condiciones");
if($return){
return $this->_result;
}
}
catch(PDOExeption $e){
echo $e->getMessaage();
}
}
#reinicia la base de datos
public function reiniciarTabla($table){
try{
$this->_result = $this->_conect->exec("TRUNCATE TABLE $table");
}
catch(PDOExeption $e){
echo $e->getMessaage();
}
}
}
si se fijan en el constructor de nuestra esta clase es donde comienza la magia (:-) e instanciamos la clase dbfactory que es la que se va a encargar de que se llamen a las clases que necesitamos, luego tenemos una serie de metodos para la ejecucion de consultas sql como usar:
<?php
#incluimos el archivo donde estan todas las clases
include("dbfactory.php");
#instanciamos la clase db() que es la que se encarga de trabajar el estandar e instanciar la clase dbfactory
$db = new db();
$rows = $db->selectAll("tabla",array('campo'=>'condicion'));
?>si se fijan utilice el metodo select all si hicieramos un print_r($rows) si la consulta trajo resultados se mostrara
Array ( [0] => Array ( [correlativo] => SAL-0 [0] => SAL-0) [1] => Array ( [correlativo] => SAL-1 [0] => SAL-1))
como se puede notar todas las consultas son consultas preparadas, menos las de borrar y reiniciar la tabla, estan bastante facil de entender su funcionamiento y estan comentadas espero que este articulo le sirva, saludos
Hola carlos_belisario
ResponderEliminarpues buen aporte el que haces, imagino
disfrutaste bastante haciendo el asunto,
y bueno, espero también que le sirva a
otros
saludos
att: morti
Gracias por tu comentario Morti, y por supuesto que lo disfrute ya que estoy haciendo lo que me gusta, ademas de ayudando a otros y a la vez aprendiendo en el intento, saludos y estamos en contacto
ResponderEliminarY muy agradecidos por el ejemplo, hace ratos me venia quebrando la cabeza con este asunto de pdo
ResponderEliminarMil gracias
me alegra que le haya gustado los ejemplos, saludos
ResponderEliminarHola Carlos Belisario. Es un gusto enorme. Me ha ayudado mucho su post. Mi nombre es Carlos Javier. Soy músico y vendedor. Vivo en Córdoba capital, Argentina. Hace pocos años comencé explorando este maravilloso mundo del diseño web y la programación. Tengo conocimientos básicos de jquery, css, html y poco de php. Le comento que tengo un proyecto que avancé muchísimo pero aún creo que falta poquito para llegar al éxito y le pido ayuda por favor, de hace varias semanas trato de aprender más qué sucede con esta conexión por PDO. ¿Tendrá algún email por favor? que pueda contactarme con Ud. y enviarle 2 carpetas adjuntas: 1 con el proyecto que funciona excelente con arrays. Y otra es la que necesito reemplazar esos arrays para que los tome de la BD; allí le enviaré todos los progresos alcanzados.
ResponderEliminarMi email es: pruebajquery@gmail.com
Desde ya muchas gracias.
Mail enviado
Eliminar