Вы находитесь на странице: 1из 4

DESARROLLO PHP - CHEAT SHEET

versin 0.1 LGICA DE PROGRAMACIN


Programacin en clases independientes de la interfaz de usuario (WEB, consola, etc.). Directorio ../Entidades Clases que representen el mundo real. Un archivo por clase. Nombre del archivo: NombreClase.php (mayscula la primera)
<?php /** * Descripcin del propsito de esta clase. * @author ejemplo@experteam.com.ec (e-mail). */ class Ejemplo { //Nombre inicia con mayscula //Variables privadas, empiezan con guin bajo. private $_nombreParametro1; private $_nombreParametro2; /** * Constructor de la clase Ejemplo. * @param String $vParametro1 //Tipo Parmetro * @param Float $vParametro2 //Tipo Parmetro */ //Variables sin guin bajo. function __construct($Parametro1, $Parametro2 = 0) { //Lgica adicional de programacin. $this->_nombreParametro1 = $Parametro1; $this->_nombreParametro2 = $Parametro2; } /** * @return String - Descripcin parmetro 1 * (ej. para que sirve, de que se trata). */ // Empieza con minscula, get o set, // y el nombre del parmetro. public function getNombreParametro1() { return $this->_nombreParametro1; } /** * @return Float - Descripcin parmetro 2. */ public function getNombreParametro2() { return $this->_nombreParametro2; } /** * @param String $NombreParametro1 */ public function setNombreParametro1($nombreParametro1) { //Variables sin guin bajo. $this->_nombreParametro1 = $nombreParametro1; } /** * @param Float $_nombreParametro2 */ public function setNombreParametro2($nombreParametro2) { //Variables sin guin bajo. $this->_nombreParametro2 = $nombreParametro2; } // Siempre sobrecargar la funcin __toString(). // Representa un texto con el que se identifica al objeto. /** * @return String Texto que representa la clase Ejemplo. */ function __toString() { return $this->_nombreParametro1; } /** * Verifica si el objeto $obj es igual a $this * @param Ejemplo $obj * @return Boolean True si son iguales, caso contrario, * false. */ function __equals($obj) { //Usar esta sintaxis $obj // Cuando haga falta comparar dos objetos, // se debe crear la funcin __equals(). if ($obj instanceof Ejemplo) { //Realizar las comparaciones necesarias if ($this->_nombreParametro1 == $obj->_nombreParametro1) { return true; } } /** * Clase genrica de excepcin de base de datos. */ abstract class DbException extends InnerException {} /** * Excepcin fatal que proviene de la BDD. * Cuando se capture esta excepcin se debera * detener el proceso. */ class FatalDbException extends DbException {} /** * Excepcin recuperable que proviene de la BDD. * Cuando se capture esta excepcin se debera reintentar la * ejecucin del proceso, antes de detenerlo definitivamente. */ class RecoverableDbException extends DbException {} //====================================================== // // // // // Despus del separador, van las funciones de la clase, primero las que dependen de la clase (pblicas o privadas); y, segundo, las que se les pasa todos parmetros y no dependen de la clase (estticas siempre).

/** * * Sumo uno a $_nombreParametro2 */ function sumarUno() { // No se le pasa parmetros puesto que se va a sumar // uno a $_nombreParametro2 que es propio de la clase. $this->_nombreParametro2 += 1; } /** * * Suma dos nmeros. * @param Float $numero1 * @param Float $numero2 * @return Float La suma de los dos nmeros. */ static function sumarDosNumeros($numero1, $numero2) { // Es esttica porque no se utiliza ningn campo // de la clase Ejemplo. // Sin embargo, se debe evitar la programacin de // funciones estticas puesto que no son adecuadas // para pruebas unitarias. return $numero1 + $numero2; } } ?>

MANEJO DE EXCEPCIONES
Para reportar errores en los procesos se utilizaran exepciones, procurando que las mismas representen el error que se produjo. Para esto se pueden definir exepciones personalizadas que sern lanzadas entre las capas. Las mismas se ubican en el archivo Entidades\CustomExceptions.php:
<?php /** * Clase que aade la funcionalidad de excepcin proveniente. * Se utiliza para almacenar la excepcin original. */ abstract class InnerException extends Exception { private $_innerException; /** * Inicializa una Exception del tipo InnerException * @param String $message * @param String $code * @param Exception $innerException */ public function __construct($message, $code, Exception $innerException) { parent::__construct ($message, $code); $this->_innerException = $innerException; } /** * @return InnerException La excepcin asociada. */ public function getInnerException() { return $this->_innerException; }

} return false;

/** * Excepcin que se produce por datos que el usuario * ingreso incorrectamente, o que el usuario los * puede corregir, ingresando nuevamente o por * parametrizacin. */ class UserException extends Exception {} ?>

CLASE DATABASE
Se utiliza para el acceso a la base de datos, implementando los procedimientos ms recurrentes. Se utiliza:
require_once '../DAL/Database.php';

Para crear un objeto Database:


$db = new Database();

Cuando en una Entidad llame a la BDD, slo tendra que manejar excepciones de tipo Db (personalizada) , y no preocuparse por capturar cada caso. En el caso de UserException, la capa de Lgica debera lanzarla y la interfaz grfica debera capturar esta excepcin para mostrarla al usuario. Se pueden aadir excepciones para controlar diferentes eventos, de ser necesario. Lgica del Negocio: >No recuperable:
try { $db->executeNonQuery($comm); } catch (FatalDbException $e) { //Validar si el error lo puede solucionar el usuario. Ej.: //Verificar si el error se produce por una clave fornea. if (stristr($e->getInnerException()->getMessage(), 'FK') === FALSE) { throw $e; //Relanzar la misma excepcin. } else { //Lanzar la excepcin personalizada a la capa de //interfaz grfica. throw new UserException('Uno o ms parmetros no estn en la BDD.'); } }

Procedimientos Almacenados: > Crear el comando:


$commandString = '[dbo].[ActualizarTablaEjemplo]'; $comm = $db->getStoredProcCommand($commandString);

Es opcional poner las varibles del procedimiento almacenado con arroba @) > Agregar parmetros de entrada:
$db->addInParameter($comm,'PA_IDPAIS',$pais,SQLVARCHAR,false); $db->addInParameter($comm,'ID',$ID,SQLVARCHAR,false);

> Agregar parmetros de salida:


$db->addOutParameter($comm,'NUMERO',&$numero,SQLINT4,6);

> Agregar variable de retorno:


$db->addReturnValue($comm, &$retorno);

> Ejecutar el procedimiento almacenado (NonQuery):


try { $db->executeNonQuery($getNumeroActual); } catch (Exception $e) { // Lgica para control del error, o logging. // ... // Se lanza el mismo error a la siguiente capa. throw $e; }

>Recuperable (procesos crticos):


$repeticiones = 0; $slot = 1; //Segundos do { try { $db->executeNonQuery($comm); return; } catch (RecoverableDbException $e) { if ($repeticiones < 3) { $sleep = rand(1, ++$repeticiones + 1); sleep($sleep); } else { //Proceso de limpieza, logging del error. //.. //Lanzar la excepcin a la capa superior. throw new MiException('Se super el nmero de reintentos', -1); } } } while (true);

Ejecutar el procedimiento almacenado (Query): [Pendiente]

ACCESO A LA BDD
Se debe seguir la lgica de funciones bsicas CRUD: OPERACIN Create Read (Retrieve) Update SQL INSERT SELECT UPDATE TIPO NonQuery* Query** NonQuery* NonQuery*

Interfaz Grfica (Web):


try { actualizarBaseDeDatos('valor'); } catch (UserException $e) { //Notificar el mensaje, la capa de lgica //ya se encarg de procesar el error. echo $e->getMessage(); } catch (MiExcepcion $e) { //Esta excepcin no se muestra al usuario. echo 'Hubo un error tcnico durante el proceso'; }

Delete (Destroy) DELETE

*Que no devuelve una consulta. Puede devolver variables OUTPUT **Que devuleve una consulta. Las clases debern implementar las funciones CRUD, segn corresponda.
function insertar() { //Lgica adicional de insercin. // ... //Insertar en la BDD. $db = new Database(); $commandString = '[dbo].[InsertarEjemplo]'; $comm = $db->getStoredProcCommand($commandString); $db->addInParameter($comm,'PARAM1', $this->_nombreParametro1, SQLVARCHAR, false); $db->addInParameter($comm, 'PARAM2', $this->_nombreParametro2, SQLFLT4, false); try { $db->executeNonQuery($comm); } catch (Exception $e) { throw $e; } }

NOTAS: - No se debe capturar exepciones que no se conoce el motivo. El objetivo de capturar una excepcin es procesarlas.
try { //Proceso que lanza una excepcin. //.. } catch (Exception $e) { //Se captura una excepcin genrica. echo $e->getMessage(); //No se sabe porque se produjo. //Para qu mostrar el error? }

- No se debe silenciar las excepciones.


try { //Proceso que lanza una excepcin. //.. } catch (Exception $e) { } //??

-El manejo de excepciones capturadas, es responsabilidad de la capa que la captura.

function actualizar() { //Lgica adicional de actualizacin. // ... //Insertar en la BDD. $db = new Database(); $commandString = '[dbo].[ActualizarEjemplo]'; $comm = $db->getStoredProcCommand($commandString); $db->addInParameter($comm, 'PARAM1', $this->_nombreParametro1, SQLVARCHAR, false); $db->addInParameter($comm, 'PARAM2', $this->_nombreParametro2, SQLFLT4, false); try { $db->executeNonQuery($comm); } catch (Exception $e) { throw $e; }

/** * Construye la prueba. Por defecto, sin valores. */ public function __construct() { } /** * Tests Ejemplo->getNombreParametro1() */ public function testGetNombreParametro1() { //Verifica si el valor de retorno es con el //que se inicializ. $this->assertEquals('Hola mundo', $this->Ejemplo->getNombreParametro1());

/** * Tests Ejemplo->getNombreParametro2() */ public function testGetNombreParametro2() { //Verifica si el valor de retorno es con el //que se inicializ. $this->assertEquals(1, $this->Ejemplo->getNombreParametro2()); } /** * Tests Ejemplo->setNombreParametro1() */ public function testSetNombreParametro1() { $this->Ejemplo->setNombreParametro1('Hola mundo 2'); //Verifica si en realidad cambio el valor //del atributo. $this->assertAttributeEquals('Hola mundo 2', '_nombreParametro1', $this->Ejemplo); } /** * Tests Ejemplo->setNombreParametro2() */ public function testSetNombreParametro2() { $this->Ejemplo->setNombreParametro2(0); //Verifica si en realidad cambio el valor //del atributo. $this->assertAttributeEquals(0, '_nombreParametro2', $this->Ejemplo); } /** * Tests Ejemplo->__toString() */ public function test__toString() { //Verifica que se devuelva el valor esperado. $this->assertEquals('Hola mundo', $this->Ejemplo->__toString()); } /** * Tests Ejemplo->__equals() */ public function test__equals() { $obj = new Ejemplo('Hola mundo'); $this->assertTrue($this->Ejemplo->__equals($obj)); } /** * Tests Ejemplo->sumarUno() */ public function testSumarUno() { $this->Ejemplo->sumarUno(); //Verifica si en realidad se sum uno al //valor del atributo. $this->assertAttributeEquals(2, '_nombreParametro2', $this->Ejemplo); } //Pruebas con proveedor de datos (verificando). /** * Tests Ejemplo::sumarDosNumeros() * Con proveedor de datos. * @dataProvider provider */ public function testSumarDosNumeros($numero1, $numero2, $resultado) { //La funcin provider() devuelve un array de arrays //que contiene los valores de entrada de este test. $this->assertEquals($resultado, Ejemplo::sumarDosNumeros($numero1, $numero2)); }

function eliminar() { //Lgica adicional de eliminacin. // ... //Insertar en la BDD. $db = new Database(); $commandString = '[dbo].[EliminarEjemplo]'; $comm = $db->getStoredProcCommand($commandString); $db->addInParameter($comm, 'PARAM1', $this->_nombreParametro1, SQLVARCHAR, false); try { $db->executeNonQuery($comm); } catch (Exception $e) { throw $e; }

PRUEBAS UNITARIAS
Se utiliza por estndar PHPUnit: Deben ser persitentes a lo largo del tiempo: no depender de datos actuales. Deben ser automticas: no deben tener variables de ingreso. Deben verificar todos los casos de uso de una funcin, pero uno por uno. Se deben programar antes de programar la funcin o la clase. (TDD: Test-Driven Development; Desarrollo Guiado por Pruebas). En general, la lgica del negocio se debe programar en las Clases, pero si un mtodo utiliza un Procedimiento Almacenado (PA), el programador del PA ser quien haga la prueba unitaria en la BDD; y el programador de la aplicacin validar nicamente que este devuelva el valor correcto de retorno, o en su defecto que no devuelva un error en el caso feliz.
<?php require_once 'Entidades\Ejemplo.php'; require_once 'PHPUnit\Framework\TestCase.php'; class EjemploTest extends PHPUnit_Framework_TestCase { /** * @var Ejemplo */ private $Ejemplo; /** * Prepara el entorno antes de ejecutar la prueba. */ protected function setUp() { parent::setUp (); // Inicializa la clase ejemplo. $this->Ejemplo = new Ejemplo('Hola mundo',1); } /** * Limpia el entorno despus de ejecutar la prueba. */ protected function tearDown() { // Establece en null el objeto para liberar memoria. $this->Ejemplo = null; } parent::tearDown ();

public function provider() { return array( array(1, 2, 3), array(-1, -2, -3), array(1, -2, -1), array(-2, 1, -1) ); } //Pruebas con dependencia. /** * Tests sumar uno con dependencia */ public function testSumarUnoDependencia() { $this->Ejemplo->sumarUno(); $this->assertAttributeEquals(2, '_nombreParametro2', $this->Ejemplo); //Una vez que se ha superado la prueba, //se devuelve el objeto modificado que //sirve de ingreso para la siguiente prueba: return $this->Ejemplo; }

/** * Tests recuperar valor con dependencia. * @depends testSumarUnoDependencia */ public function testGetNombreParametro2Dependencia( Ejemplo $obj) { //En setUp() se inicializ en 1, en el test //dependiente se sum uno al valor (actual 2). //En esta funcin, se pasa de parmetro el //resultado del test anterior. Por lo tanto, //la aseveracin es correcta pues el valor //comparado es 2. $this->assertEquals(2, $obj->getNombreParametro2()); }

NOTAS: Los test son independientes, no importa el orden en que se ejecuten las funciones. Slo son dependientes cuando se indica explcitamente con la anotacin @depends.

Вам также может понравиться