patrones de diseño en PHP

Patrón de diseño (design patterns) es:

  1. Una solución estandar para un problema común de programación.
  2. Un lenguaje de programación. de alto nivel.
  3. Conexiones entre componentes de programas.
  4. La forma de un diagrama de un objeto.

Para que una solución sea considerada un patrón debe:

  1. Ser reusable.
  2. Ser flexible.
  3. Haber resuelto problemas similares en ocasiones anteriores.

Existen muchos patrones que se pueden implementar en PHP de acuerdo a nuestras necesidades(Singleton, MVC, Factory, entre otros), les mostrare un pequeño ejemplo de como implementar un patrón, para esto utilizaremos el patrón Factory Method.

Patrón Factory Method en PHP5

Este patrón nos permite instanciar las clases accediendo por una clase Fabrica(en este caso Database),

Primero crearemos la clase Fabrica

abstract class Database
{
    public static function crear($clase)
    {
        return new $clase;
    }
}

Crearemos las clases MySQL y PostGreSQL

// Clase MySQL
class MySQL
{
	function __toString()
    {
    	return 'Clase MySQL';
    }
}
// Clase PostGreSQL
class PostGreSQL
{
	function __toString()
    {
    	return 'Clase PostGreSQL';
    }
}

La forma clásica de crear seria de esta manera

$oMysql = new MySQL();

Con el patrón Factory Method seria de esta manera

$oMySQL = Database::crear('MySQL');
$oPostG = Database::crear('PostGreSQL');
echo $oMySQL.'<br />';
echo $oPostG;

Con esto podríamos dar mas seguridad a nuestras instancias, realizando algunas rutinas dentro de la clase Database.

Recursos

Forzar tipo de parametros en php

p>PHP 5 introduce Type Hinting(elección de tipo ), que sirve para restringir el tipo de objeto que debe ser un parametro, especificando el nombre de la clase antes del nombre del parametro.

Ejemplo:

// Clase Reporte
class Reporte
{
    public function ver(Alumno $obj)
    {
        return
        'Nombre:   '.$obj->nombre.'<br />'.
        'Apellido: '.$obj->apellido.'<br />'.
        'Nota:     '.$obj->nota;
    }
}
// Clase Alumno
class Alumno
{
    public $nombre = 'Cesar';
    public $nombre = 'Mancilla';
    public $nota   = '20';
}

Al no satisfacer el tipo al que se le hace referencia resulta en un error fatal.

// instanciamos cada clase
$reporte = new Reporte();
$alumno  = new Alumno();
// Fatal Error: Argument 1 must be an object of class Alumno
$reporte->ver('Cesar');
// Fatal Error: Argument 1 must not be null
$reporte->ver(null);
/*
Nombre:   Cesar
Apellido: Mancilla
Nota:     20
*/
$reporte->ver($alumno);

	

Web Developer Toolbar – Complemento para Firefox

Web Developer Toolbar es un complemento para firefox que tiene una serie de herramientas que nos facilitan los accesos en nuestro desarrollo.

Una lista con algunas utilidades muy importantes

  • habilitar y deshabilitar javascript, css, cache
  • Control de cookies
  • Edición de CSS de una página en tiempo real
  • Información , código de pagina
  • Regla para alinear una pagina
  • Redimensionar la página
  • Outline, remarca los elementos para una fácil ubicación

Lo puedes descargar de aquí.

Mostrar archivos ocultos en Mac

Mac OS X por defecto no muestra los archivos ocultos y Finder no dispone de ninguna opción para modificar este comportamiento. Estos archivos suelen comenzar por un punto, como por ejemplo

.DS_Store
Para ver estos archivos podemos escribir estas dos instrucciones en la Terminal que se encuentra en Applications/Utilities.

Mostrar archivos ocultos


[javascript]
defaults write com.apple.finder AppleShowAllFiles TRUE
killall Finder
[/javascript]

Cuando no quieras ver los archivos ocultos nuevamente, puedes ejecutar el mismo script, pero cambiando “TRUE” por “FALSE”.

Ocultar archivos ocultos (valga la redundancia)


[javascript]
defaults write com.apple.finder AppleShowAllFiles FALSE
killall Finder
[/javascript]

 

Hidden Files Widget

Hidden Files es un Widget para el Dashboard de la Mac, con ella podemos realizar el mismo proceso de ocultar y mostrar los archivos “ocultos”, la manera mas rapida precionando un simple boton que nos indicara el estado del archivo, la podemos descargar desde Apple.
Dashboard.

Finder

Descargar Hidden Files Widget
También te puede interesar: Descomprimir archivos .RAR en Mac

convertir array a objeto en PHP

Esta conversión nos sirve mucho ya que a veces requerimos accesar a un conjunto de datos por medio de arrays, y otras veces accesarlos con punteros(Objetos).

En el siguiente ejemplo lo utilizaremos para recoger los datos de un formulario enviado por el metodo POST, y accesarlo como un objeto

$objetos = (object)$_POST;
print_r($objetos);

Ahora, si queremos algo inverso, tendremos que crear una función.

function obj2array($object)
{
  if(is_array($object) || is_object($object))
  {
    $array = array();
    foreach($object as $key => $value)
    {
      $array[$key] = obj2array($value);
    }
    return $array;
  }
  return $object;
}
$arrays = obj2array($objetos);
print_r($arrays);

Recursos

Syntax Highlighter – WordPress

p>Syntax Highlighter es un plugin para WordPress, el cual nos permite poner nuestro codigo con los respectivos colores.

Descargar

SyntaxHighlighter

 

Caracteristicas

  • 100% del lado del cliente
  • Multiples lenguajes soportados
  • Muy ligero

Lenguajes soportados

  • C++ (cpp, c, c++)
  • C# (c#, c-sharp, csharp)
  • CSS (css)
  • Delphi (delphi, pascal)
  • Java (java)
  • Java Script (js, jscript, javascript)
  • PHP (php)
  • Python (py, python)
  • Ruby (rb, ruby, rails, ror)
  • Sql (sql)
  • VB (vb, vb.net)
  • XML/HTML (xml, html, xhtml, xslt)

Ejemplo

<pre name="code" class"php">
echo ‘Prueba con SyntaxHighlighter’;
</pre>

echo 'Prueba con SyntaxHighlighter';

	

Expresiones regulares mas usadas en php

Una Expresión regular, también llamada patrón, es una forma de representar a los lenguajes regulares (finitos o infinitos) y se construye utilizando caracteres del alfabeto sobre el cual se define el lenguaje.

Este articulo lo encontre en RoughGuideToPhp.com y tiene una lista con 10 expresiones regulares mas usadas con PHP en nuestros proyectos.

 

1. Validar Nombre de usuario

Esta validación sigue las siguientes reglas:

  • Un nombre de usuario debe empezar con un minúsculas o mayúsculas carta
  • Un usuario sólo puede contener letras, números o pone de relieve
  • Un nombre de usuario debe tener entre 8 y 24 caracteres
  • Un usuario no puede terminar en un guión bajo

[php]
function validarUsuario($nombre)
{
return preg_match("#^[a-z][da-z_]{6,22}[a-zd]$#i", $nombre);
}
//ejm:
if(validarUsuario("nombreUsuario"))
{
echo "usuario valido";
}
else
{
echo "usuario invalido";
}
[/php]

2. Validar Dirección Email

Aquí un ejemplo general para validar un email.

[php]
function validarEmail($email)
{
$reg = "#^(((([a-zd][.-+_]?)*)[a-z0-9])+)@(((([a-zd][.-_]?){0,62})[a-zd])+).([a-zd]{2,6})$#i";
return preg_match($reg, $email);
}
//ejm:
if(validarEmail("cesar@gmail.com"))
{
echo "email valido";
}
else
{
echo "email invalido";
}
[/php]

3. Validar Fecha

Esta validación acepta la fecha en formato DD-MM-YYYY, con separadores (/),(-) y (.);

[php]
function validarFecha($fecha){
$sep = "[/-.]";
$req = "#^(((0?[1-9]|1d|2[0-8]){$sep}(0?[1-9]|1[012])|(29|30){$sep}(0?[13456789]|1[012])|31{$sep}(0?[13578]|1[02])){$sep}(19|[2-9]d)d{2}|29{$sep}0?2{$sep}((19|[2-9]d)(0[48]|[2468][048]|[13579][26])|(([2468][048]|[3579][26])00)))$#";
return preg_match($reg, $fecha);
}
//ejm:
if(validarFecha("12/01/2009"))
{
echo "fecha valida";
}
else
{
echo "fecha invalida";
}
[/php
<h3 id="validar_ip">4. Validar Direcci&oacute;n IP </h3>
<p>Valida que una dirección IP este dentro del rango 0.0.0.0 a 255.255.255.255</p>
[php]
function validarIP($ip)
{
$val_0_to_255 = "(25[012345]|2[01234]d|[01]?dd?)";
$reg = "#^($val_0_to_255.$val_0_to_255.$val_0_to_255.$val_0_to_255)$#";
return preg_match($reg, $ip, $matches);
}
//ejm:
if(validarIP("192.168.1.1"))
{
echo "IP valida";
}
else
{
echo "IP invalida";
}
[/php]

5. Validar Numero de Telefono

El formato utilizado seria así: 000 000 0000,(000)-000-0000. Donde los primeros 3 números serian el código de tu País.

[php]
function validarTelefono($numero)
{
$reg = "#^(?d{3})?[s.-]?d{3}[s.-]?d{4}$#";
return preg_match($reg, $numero);
}
//ejm:
if(validarTelefono("(511)-311-4541"))
{
echo "telefono valido";
}
else
{
echo "telefono invalido";
}
[/php]

6. Validar Numero de tarjeta de credito

Al realizar una aplicación de comercio electrónico es muy importante validar los distintos tipos de tarjetas de credito que hay, esta es una simple función para validarla, solo tiene que llamar a la función getTipoTarjeta(“4111 1111 1111 1111”);

[php]
function validarTarjeta($num_tarjeta)
{
$num_tarjeta = preg_replace("/D|s/", "", $num_tarjeta);
$length = strlen($num_tarjeta);
$parity = $length % 2;
$sum=0;
for($i=0; $i&lt;$length; $i++)
{
$digit = $num_tarjeta[$i];
if ($i%2==$parity) $digit=$digit*2;
if ($digit&gt;9) $digit=$digit-9;
$sum=$sum+$digit;
}
return ($sum%10==0);
}
function getTipoTarjeta($cc)
{
$cards = array(
"visa" => "(4d{12}(?:d{3})?)",
"amex" => "(3[47]d{13})",
"jcb" => "(35[2-8][89]ddd{10})",
"maestro" => "((?:5020|5038|6304|6579|6761)d{12}(?:dd)?)",
"solo" => "((?:6334|6767)d{12}(?:dd)?d?)",
"mastercard" => "(5[1-5]d{14})",
"switch" => "(?:(?:(?:4903|4905|4911|4936|6333|6759)d{12})|(?:(?:564182|633110)d{10})(dd)?d?)",
);
$names = array("Visa", "American Express", "JCB", "Maestro", "Solo", "Mastercard", "Switch");
$matches = array();
$pattern = "#^(?:".implode("|", $cards).")$#";
$result = preg_match($pattern, str_replace(" ", "", $cc), $matches);
if($result > 0)
{
$result = (validarTarjeta($cc))?1:0;
}
return ($result>0)?$names[sizeof($matches)-2]:false;
}
//ejm:
echo getTipoTarjeta("4111 1111 1111 1111");
[/php]

En foros es muy utilizado la función para reemplazar simples direcciones web por enlaces HTML.

[php]
function convertirURL($url)
{
$host = "([a-zd][-a-zd]*[a-zd].)+[a-z][-a-zd]*[a-z]";
$port = "(:d{1,})?";
$path = "(/[^?&lt;&gt;#"s]+)?";
$query = "(?[^&lt;&gt;#"s]+)?";
$reg = "#((ht|f)tps?://{$host}{$port}{$path}{$query})#i";
return preg_replace($reg, "&lt;a href=’$1’&gt;$1&lt;/a&gt;", $url);
}
//ejm:
echo convertirURL(" visita http://www.google.com");
[/php]

8. Limpiar palabras groseras

Esta expresión regular filtra las palabras groseras que algunos de nuestros usuarios podrían poner.

[php]
function deswear($string){
function prep_regexp_array(&$item){
$item = "#$item#i";
}
function stars($matches){
return substr($matches[0], 0, 1).str_repeat("*", strlen($matches[0])-1);
}
$swears = array("idiota", "invecil");
array_walk($swears, "prep_regexp_array");
return preg_replace_callback($swears, "stars", $string);
}
//ejm:
echo deswear("marcianito es un idiota");
[/php]

9. Eliminar código Javascript

[php]
function limpiarTags($source, $tags = null)
{
function clean($matched)
{
$attribs =
"javascript:|onclick|ondblclick|onmousedown|onmouseup|onmouseover|".
"onmousemove|onmouseout|onkeypress|onkeydown|onkeyup|".
"onload|class|id|src|style";
$quot = ""|’|`";
$stripAttrib = "’ ($attribs)s*=s*($quot)(.*?)(\2)’i";
$clean = stripslashes($matched[0]);
$clean = preg_replace($stripAttrib, ”, $clean);
return $clean;
}
$allowedTags=’&lt;a&gt;&lt;br&gt;&lt;b&gt;&lt;i&gt;&lt;br&gt;&lt;li&gt;&lt;ol&gt;&lt;p&gt;&lt;strong&gt;&lt;u&gt;&lt;ul&gt;’;
$clean = strip_tags($source, $allowedTags);
$clean = preg_replace_callback(‘#&lt;(.*?)&gt;#’, "clean", $source);
return $source;
}
//ejm:
echo limpiarTags("este código es malicioso &lt;script&gt;alert(‘hola!’)&lt;/script&gt;");
[/php]

10. Remplazar BBCode por HTML

BBCode(Bulletin Board Code) es una manera simple de realizar nuestra propia norma de etiquetas en nuestra web, en vez de etiquetar con código HTML(<strong>) escribiremos [strong] y nuestra función la reemplazara a momento de visualizarla por etiquetas HTML.

[php]
function convertirBBcode($string)
{
$string = strip_tags($string);
$patterns = array(
"bold" =&gt; "#[b](.*?)[/b]#is",
"italics" =&gt; "#[i](.*?)[/i]#is",
"underline" =&gt; "#[u](.*?)[/u]#is",
"link_title" =&gt; "#[url=(.*?)](.*?)[/url]#i",
"link_basic" =&gt; "#[url](.*?)[/url]#i",
"color" =&gt; "#[color=(red|green|blue|yellow)](.*?)[/color]#is"
);
$replacements = array(
"bold" =&gt; "&lt;b&gt;$1&lt;/b&gt;",
"italics" =&gt; "&lt;i&gt;$1&lt;/i&gt;",
"underline" =&gt; "&lt;u&gt;$1&lt;/u&gt;",
"link_title" =&gt; "&lt;a href="$1"&gt;$2&lt;/a&gt;",
"link_basic" =&gt; "&lt;a href="$1"&gt;$1&lt;/a&gt;",
"color" =&gt; "&lt;span style=’color:$1;’&gt;$2&lt;/span&gt;"
);
return preg_replace($patterns, $replacements, $string);
}
//ejm:
echo convertirBBcode("[b]letra negrita[/b]");
[/php]

Pack de iconos – redes sociales

En BlogPerfume han publicado un pack de iconos sobre redes sociales tal cual muestra la imagen.

Muy util para proyectos y aplicaciones futuras en las que necesitemos iconos de redes sociales, en este pack estan incluidos los las populares como: Twitter, Delicious, Digg, Facebook, Youtube, Flickr, MySpace, entre otros.

Este pack la puedes descargar en formato comprimido .rar o .zip

Resetear auto_increment en MySQL

Cuando estamos trabajando con tablas de MySQL que tienen la llave(Primary key) de tipo entero autoincremental, cometemos a veces el grave error de no resetearlo al terminar el proyecto, esto hace que cuando ingrese un “primer registro” el id sea mayor a “1”.

El siguiente script sirve para crear una tabla llamada usuarios, es importante usar los acentos agudos (`) antes y despues del nombre de una base de datos, tablas, y campos en MySQL, esto evitara que no salga error en caso de haber puesto como nombre alguna palabra reservada de MySQL.

CREATE TABLE `user`
(
  `id` int(11) NOT NULL auto_increment,
  `name` varchar(100) NOT NULL,
  `email` varchar(100) default NULL,
  PRIMARY KEY  (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;

Ahora ingresamos 2 registros

INSERT INTO `user`(`name`,`email`) VALUES('Juan','juan@gmail.com');
INSERT INTO `user`(`name`,`email`) VALUES('Maria','maria@gmail.com');

Al haber ingresado dos registros nuestro valor incremental se a posicionado en 3 que es lo correcto, pero que pasa si eliminamos los registros con delete, no se reseteara el valor autoincremental.

DELETE FROM `user` WHERE `id`=1;
DELETE FROM `user` WHERE `id`=2;

Si ingresamos un nuevo registro su id sera 3.

INSERT INTO `user`(`name`,`email`) VALUES('Usuario Tres','tres@gmail.com');

Para resolver este problema una vez que hallamos borrado nuestros registros de la tabla, ejecutemos el script para reseter los valores autoincrement de cada tabla.

ALTER TABLE `user` AUTO_INCREMENT=1

Otra forma de borrar y resetar a la vez es usar la función TRUNCATE de MySQL, esta función limpia la tabla de registros y si tiene un campo autoincremental lo resetea.

TRUNCATE `user`

Ya se que es mucho mas fácil pero lo puse al final, ya que en nuestros proyectos la forma que usamos para borrar los registros en usando el sistema y de paso probandolo y no con scripts directos en la DB.

Lazy Loading en PHP

p>Lazy Loading es un patrón de diseño que se utiliza mucho programación

En que consiste?

Su implementación en PHP consiste en no incluir las clases a utilizar en nuestro proyecto.

Como las reconoce?

De esto se trata Lazy Loading, cuando necesitas de una clase es recien cuando la llama. Este proceso lo realizamos con la función mágica que trae PHP5 __autoload($nombreClase), en un POST anterior escribí un completo ejemplo para su uso.

Que de bueno tiene este patrón?

Al no incluir todas las clases el inicio de cada pagina php, estamos ahorrando un proceso, ganando un poco de performance y obteniendo un código mas limpio en nuestra aplicación.

Ejemplo de Código

primero cambiaremos nuestras Clases con el mismo nombre del archivo(como en Java).
Si tenemos una Clase Clientes(), nuestro archivo podría llamarse Clientes.php, Clientes.class.php, ClientesClass.php, lo importante es que el nombre de la clase aparezca completo en el archivo.

function __autoload($class_name)
{
	//direfentes rutas separas por ","
    $include_path = '/lib,/include,/class';
    $include_path_tokens = explode(',', $include_path);
    foreach($include_path_tokens as $prefix)
    {
      $path[0] = $prefix . '/' . $class_name . '.php';
      $path[1]= $prefix . '/' . $class_name . '.class.php';
      foreach($path as $thisPath)
      {
        if(file_exists($thisPath))
        {
          require_once $thisPath;
          return;
        }
      }
    }
}

Con esto nos olvidaremos de muchos includes que bajan la performance en nuestras aplicaciones.

Recursos