Dentro de unas horas mi primer podcast: "El Estado del Arte y PHP5" (actualizado 2/12/2006)

Parte de la "polémica" charla "El Estado del Arte y PHP5" efectuada en el evento Debian Day (organizado por el grupo Debian Uruguay).

Evento fue realizado en UTU y se dirigía hacia un público que desconociera el tema "Software Libre".

Nota importante: en varias partes de la charla se pueden apreciar interrupciones de lo que yo llamo "talibanes del Software Libre" (en este caso particular eran fundamentalmente argentinos): individuos que se dicen ser "propulsores de la libertad" pero que son tan intolerantes que no permiten puntos de vistas distintos a los suyos. Hubieron hasta un par de "abandonos de sala".

Lamentablemente la grabación culmina unos segundos antes de finalizar mi exposición... pero a pesar de haber recibido días después algunas críticas aisladas, al final de la misma hubo un cálido aplauso de la audiencia (no de los talibanes, por supuesto) ;-)

Dentro de unas horas, luego de una pequeña "pre-producción", estará el podcast disponible.

Los "Desarrolladores PHP" debemos profesionalizarnos o quedaremos descartados por obsoletos

Esta reflexión se la escribo a todos los "Programadores PHP":

Al día de hoy la mayoría de los institutos o universidades de muchos países siguen enseñando PHP4, o mejor dicho, programación "scripting" básica. Se mueven en el viejo concepto de la "programación estructurada", trabajando constantemente sobre código que mezcla html y sintaxis PHP, todo como si de una ensalada estuviéramos hablando.

Casi paralelamente, los jóvenes autodidactas siguen por el mismo camino, tal vez ayudados por la gran cantidad de material repetido y obsoleto que se encuentra tanto en la web como en las editoriales de turno, donde a pesar que un libro haya sido impreso recientemente, los autores siguen siendo los mismos y escribiendo -una y otra vez- sobre los mismos temas elementales.

Enfrentar la realidad con madurez

Solo nos damos cuenta que estamos en un grave problema cuando nos enfrentamos a la realidad: salimos al mercado laboral y con inocente sorpresa vemos que se habla mayoritariamente de Java o .Net, de UML, desarrollos en 3 capas, lógica de negocios, persistencia, polimorfismo, frameworks, patrones de diseño, refactoring... y tú solo tienes una vaga idea de algunos conceptos, pero nulo conocimiento de si es realmente posible hacerlo con PHP...


¿No crees que algo está pasando y que tú estás quedando fuera de la "conversación"?

Este es el gran problema de la mayoría de los "Programadores PHP": se quedan en el "lenguaje", en la programación lisa y llana, rechazando todo lo que sea objetos hasta que no les queda otra salida que aprender a usarlos mínimamente... pues todas las nuevas herramientas solo hablan "ese" idioma.

¿Hasta donde piensas que podemos llegar con tan poca preparación?

Mi experiencia personal

De lo que trato de hablar en este blog es de "profesionalizarnos", de copiar y mejorar, de aprender y evolucionar. La mayoría de los temas que expongo no son nuevos, trato de basarme en autores reconocidos y darle más prioridad a los conceptos que al lenguaje, y por sobre todas las cosas: ser simple y directo (pragmático antes que dogmático, pero sin olvidarme de lo último). Hay muchas cosas que desconozco de PHP y otras que directamente no uso, y nunca me baso en la memoria, siempre voy a buscar hasta lo más elemental al manual (doy prioridad al razonamiento por sobre la retención mecánica de conocimientos). Siguiendo esta metodología, mañana deberías poder cambiar de lenguaje y seguir trabajando sin problemas, pues los conceptos base los tendrías claros y estos se aplican sin importar la plataforma que estés usando.

Muchas veces comento que los temas sobre los que escribo son elementales para muchos desarrolladores Java de nivel medio y alto, pero en el ambiente PHP esto cambia (todavía no hemos madurado hacia el concepto de "arquitectura") donde "en el mundo de los ciegos puedo ser rey". Debemos cambiar la mentalidad ahora que existe PHP5 y que su nueva sintaxis nos permite hacer muchas cosas que son habituales en el mundo Java.


Por lo tanto, tenemos todas las herramientas para "evolucionar" y no quedarnos en las excusas.

Programador versus Desarrollador

Desarrollar Orientado a Objetos va más allá que crear objetos aislados que solo contienen datos, programar usando algunos objetos es distinto a desarrollar 100% Orientado a Objetos, ser programador es distinto a ser un desarrollador, un sitio web no es lo mismo que un sistema web. Existen, además de los objetos, "Principios de Diseño (OO)", "Patrones de Diseño (OO)", el lenguaje de diseño UML, frameworks, etc, y todo es perfectamente aplicable usando PHP.


Es más, muchos de estos conceptos e ideas son independientes al lenguaje si este cumple mínimamente con las características de la OO, cosa que sucede a partir de PHP5 en adelante y que PHP4 casi carece por completo.

Finalmente, es mi visión que un programador resuelve problemas aislados usando un lenguaje, pero un desarrollador diseña e implementa una solución global, une los componentes en un único sistema integrado y es lo suficientemente inteligente y estratega para poder reutilizar la experiencia y conocimientos adquiridos en favor de los próximos desarrollos.

Los sistemas que van quedando atrás nunca serán un lastre porque podrán ser mantenidos con el mínimo costo posible, permitiendo que el desarrollador pueda afrontar nuevos y enriquecedores desafíos.

Todos estos detalles los percibimos claramente cuando nuestros desarrollos dejan de ser un "programa menor" y necesitamos crecer, pero vemos que con los conocimientos que contamos hasta el momento todo se nos hace cuesta arriba.

La culpa es enteramente nuestra

No podemos quejarnos que a los programadores Java se les paga el doble que a nosotros y que a la mayoría de los proyectos PHP se los desvalorice, se los trate como "algo menor", "poco serio", todo porque es un "simple lenguaje web" limitado en sus posibilidades.

El "Simple Lenguaje" lo hacemos todos, al ser "Simples Programadores PHP" y nuestras son las limitaciones fundamentales. Perfectamente podemos tratar de trabajar "más seriamente" como lo hacen los "desarrolladores Java", y tratando con creatividad de suplir las carencias momentáneas (como el muy sonado caso de la falta de "namespaces").

PHP se está orientando a convertir en una "arquitectura", a parecerse a un J2EE pero mucho más simple y directo.

El proceso hace tiempo que inició.

Debemos pasar de los dichos a los hechos

De la misma forma, creo que nos hace falta tener más "sentimiento de comunidad", como sucede habitualmente -hasta de forma exagerada- en el mundo GNU/Linux. No es posible que nos sigamos quejando que los proveedores de hosting siguen usando PHP4. Deberíamos hacer campañas para promover la migración a las nuevas versiones de PHP, pero fundamentalmente, incorporar en nuestros desarrollos las características avanzadas del lenguaje, e invitar a usarlo como si fuera una arquitectura, actualizar a nuestro equipo de desarrolladores, visitar empresas, universidades, etc.


¿Tú, qué vas a hacer? ¿Te vas a quedar donde estás o te vas a subir al tren?

¿Eres parte del problema o parte de la solución?

Tenemos que especializarnos y profesionalizarnos, el mundo pide POO, arquitecturas, capas, etc, y habla en "UML"... tú, en que idioma hablas?

Artículo basado en una respuesta dada en Foros del Web

Problemas de tildes relacionados con UTF8, ISO-8859-1, PHP y Eclipse...

Esto es lo que pasa cuando tienes entornos que no son homogéneos y cada aplicación se encuentra ubicada en distintas márgenes de un "río virtual", en una ribera las más antiguas soportando por defecto el viejo ISO-8859-1 y en la otra, un poco más actualizadas a los tiempos modernos, las que incluyen el soporte de UTF-8.

En un mundo ideal, donde todos los servidores y las estaciones de trabajo se actualizan a la par, contemplando los últimos cambios tecnológicos, obtendremos con el uso de UFT-8 la posibilidad de trabajar con cualquier tipo de "caracteres especiales", incluyendo los famosos "tildes" (que abundan en nuestro castellano) sin tener que usar "codificaciones html" para representarlos.

¿Quién no sufrió tener que escribir "día" y "año" para representar "día" y "año"?

En el mundo real, obviamente, sucede todo lo contrario: tu estación de trabajo puede estar con la última versión de tu sistema operativo y aplicativos, y todas ellas usarán desde hace pocos años por defecto el juego de caracteres UTF-8...

PERO... como es lógico y habitual, los servidores no se acostumbran a actualizar a la par de la tecnología (al menos no completamente de cero), puesto que si brindan servicios (que generalmente son siempre críticos) actualizar completamente un software de base o sus aplicativos sin una justificación fundamentada sería arriesgarse a que algo pudiera dejar de funcionar.

Eso lleva a que es completamente habitual encontrar que existen diferencias en las versiones de software entre desarrolladores y sus propios servidores, lo cual hay que tener en cuenta que al editar un archivo con formato ISO que incluye tildes y caracteres especiales escritos sin usar codificación html y grabarlos en una herramienta que use UTF-8 genera la pérdida completa de los mismos.

Existen muchas alternativas para paliar estos problemas:
  • Usar utilidades que tomen archivos en formatos ISO y los transformen en formato UTF, con la única contra de que no se podrá aplicar si los servidores son antiguos y desconocen el nuevo formato,
  • Migrar los servidores y las aplicaciones para unificar el formato de caracteres, pero raramente este tipo de problemas es razón suficiente para poner en riesgo toda una instalación de servidores (web, base de datos, servidores de aplicación, etc).
  • Codificar internamente todos los caracteres especiales (tildes, símbolos, etc) con su correspondiente representación en "código html", lo cual si no encontramos un editor que nos ayude a trabajar de forma transparente con ellos, nos obliga a hacerlo "a mano", con todos los caracteres. La otra contra posible es que si mañana se unifica todo a formato UTF, perderíamos la posibilidad de usar libremente cualquier caracter, lo que deberíamos entonces buscar algo que lo traduzca al nuevo formato.
  • Cambiar a todas las aplicaciones que usan por defecto UTF-8 al antiguo ISO-8859-1 para que nuestros archivos en este último formato no pierdan todos los caracteres especiales.
Esta última es la opción generalmente más elegida.

En el caso concreto de Eclipse

Hace mucho tiempo que el IDE Eclipse (el cual uso para desarrollar con PHP5) usa por defecto UTF-8, y en su momento he tenido varios problemas para cambiar "completamente" todos los lugares donde hace referencia a este juego de caracteres (sí, en más de un lado):
  • En la "configuración general" con qué formato editas los archivos.
  • El formato con el cual se graba el archivo.
Todavía no me cierra porqué se podría querer editar en un formato y grabarlo en otro, pero bueno, alguien tal vez lo pueda necesitar.

A pesar de estos cambios, los caracteres se seguían perdiendo. También hay que cambiar en:
  • Configuración -> Content Type, y para cada tipo de archivo donde diga "Default Encoding":
Por ejemplo, tenía en mi configuración por defecto:
  • Java prefs = "ISO-8859-1"
  • Javascripts = "US-ASCII"
  • XML = "UTF8"
  • DTD = "UTF8"
La mayoría dice UTF8, pero...
  • HTML = "vacío"
  • PHP Source File = "vacío"
Que asumo se debería tomar "alguna configuración general", pero al haberlas -creo- cambiado todas, les agregué el valor "ISO-8859-1".

Hasta ahora no volví a perder ningún tilde.

Resumiendo

Todo esto no sucedería si todos los aplicativos trabajaran con el mismo juego de caracteres, en particular UTF-8, el cual permite insertar caracteres especiales de forma directa y no a través de un código particular que después será traducido por el navegador de turno.

También, según como codifiques los caracteres, tienes distintos tipos de problemas:
  • Si en ISO usas literalmente los caracteres especiales, en UTF se pierden (quedan convertido en "basura").
  • Si en ISO usas los "códigos html" que corresponden con los caracteres especiales no se pierden al pasar a UTF, pero en algún momento deberás cambiarlos a caracter literal para poder sacarle provecho al formato.
  • Que no solo depende del editor de turno que formato usa, también del servidor.
Y que en Eclipse hay muchos lados para cambiar esta configuración, lo cual debo recordar para volver atrás en algún momento futuro.

Un detalle sobre PHP6 y UTF

En muchos lados se comenta como "la panacea " que la nueva versión de PHP, la versión 6, será 100% compatible con UTF-8 (sus funciones, el manejo de información de salida y entrada, etc), lo cual siempre me dio la impresión de algo menor (habiendo tantas otras cosas del lenguaje que se podrían agregar, como los namespaces). También me había sorprendido que decían que el trabajo era "una obra titánica" por la cantidad de código que tenían que modificar para incorporar ese soporte...

...pero luego de vivir este tipo de problemas y saber que hace mucho tiempo todas las aplicaciones recientes lo usan, y que de aquí en más se soluciona cualquier problema de caracteres (por lo que tengo entendido podríamos escribir directamente en japonés y debería soportarlo sin más)...

... ahora comprendí cuan grave y necesario es (aunque sigo pensando -de terco que soy- que "namespaces" debería estar en esta versión).

Los métodos "getter / setter" o "accesores / modificadores" (revisado 10/2008)

He visto mucha documentación que habla sobre el tema de los métodos "getter / setter", o traducido al castellano los métodos "accesores / modificadores", y la mayoría se va a los extremos, perdiendo de explicar de forma simple la razón de su existencia.

Trataremos de sacarle la "mística" al asunto.

Antes de usar la estrategia de los "set y get" para los atributos

En PHP4 todos los atributos de un objeto son siempre atributos públicos, es decir, cuando creamos una instancia del objeto a partir de la definición de la clase, tenemos acceso completo a cada uno de los atributos, tanto para leerlos como para modificarlos.

Definición de la clase "Usuario"

1
<?php
2
class Usuario{
3 var
$nombre;
4 var
$nombreReal;
5 var
$edad;
6 var
$clave;
7 }
8
?>



Creo el objeto "unUsuario":

$unUsuario = new Usuario();

En este momento el usuario está vacío, pues sus atributos no tienen ningún valor asignado. Por lo tanto, le daremos sentido a este objeto:

1
<?php
2 $unUsuario
->nombre = "eplace";
3
$unUsuario->nombreReal = "Enrique Place";
4
$unUsuario->edad = "33";
5
$unUsuario->clave = "pepe";
6
?>



Inventemos un escenario completamente de fantasía (surrealista diría)

Supongamos ahora que nuestro sistema es mantenido por varios desarrolladores y que una parte del sistema es mantenida por un "estudiante de programación" que decidió unilateralmente que cuando le llegue el objeto "unUsuario" le pondrá siempre el nombre en mayúsculas y le colocará una clave por defecto si esta está vacía.

1
<?php
2 $unUsuario
->nombre = strtoupper($unUsuario->nombre);
3
4 if (
is_null($unUsuario->clave)){
5
$unUsuario->clave="clavePorDefecto";
6 }
7
?>



Nosotros, como "desarrolladores experimentados", nos sentimos molestos por la tontería que acaba de hacer el "estudiante"... ahora la pregunta es, como evitamos que esto suceda?

Uno de los problemas aquí es que PHP4 no soporta la definición del "alcance" (o también llamada "visibilidad") de los atributos y métodos, algo habitual en cualquier lenguaje serio de tipo "Orientado a Objetos". Esto hace que -aunque no nos guste- el desarrollador de turno pueda hacer lo que quiera con los atributos de cualquier objeto a su alcance.

Entonces migremos a PHP5

PHP5, consciente de este problema, implementa la definición de "visibilidad" de los atributos y métodos, como lo haría Java o .Net. Si hiciéramos una migración "mecánica" de nuestro código, este cambiaría la sintaxis a esta forma (ya que la sintaxis "var" pasa a desuso y esta definía a los atributos siempre "públicos"):

1
<?php
2
3
class Usuario{
4 public
$nombre;
5 public
$nombreReal;
6 public
$edad;
7 public
$clave;
8 }
9
10
?>



Ahora disponemos de las siguientes opciones gracias a la nueva sintaxis: public, private y protected.

Ahora bien, si queremos que el "estudiante" no pueda modificar nuestros datos, podemos pasar a colocar todos los atributos como "private":

1
<?php
2
class Usuario{
3 private
$nombre;
4 private
$nombreReal;
5 private
$edad;
6 private
$clave;
7 }
8
?>



Pronto, ahora cuando el "estudiante" quiera ver o modificar un atributo, el sistema le enviará un error. El problema ahora es que nosotros queremos que:
  1. La edad se pueda saber y cambiar en todo momento.
  2. Se pueda saber el nombre del usuario, pero no modificarlo
  3. No nos interesa que se sepa el nombre real del mismo
  4. Pero queremos que pueda colocar una nueva clave si el usuario se la olvida, pero no saber la que existe actualmente

Esto no lo podemos hacer ni teniendo todos los atributos públicos como sucedía con PHP4 ni restringiendo toda la visibilidad como nos permite ahora PHP5.

¿Cómo se hace entonces?

Por un tema de principios de la POO los atributos de los objetos deben ser siempre "privados" (concepto "encapsulación": no son accesibles desde fuera del objeto, solo el objeto tiene la potestad de usarlos directamente) y se deberán crear métodos públicos que sustituya una u otra operación, o ambas, cada vez que la situación lo amerite: un método "setter" para "cargar un valor" (asignar un valor a una variable) y/o un método "getter" para "retornar el valor" (solo devolver la información del atributo para quién la solicite).

Requerimiento 1) la edad se puede acceder y modificar en todo momento, por consiguiente se deben agregar los dos métodos, un "get" y un "set" para ese atributo:

1
<?php
2
class Usuario{
3 private
$nombre;
4 private
$nombreReal;
5 private
$edad;
6 private
$clave;
7
8 public function
getEdad() {
9 return
$this->edad;
10 }
11 public function
setEdad($edad){
12
$this->edad = $edad;
13 }
14 }
15
?>



Pronto, ahora el atributo se puede consultar o modificar no directamente, solo a través de los métodos "get / set". En este caso no se nota la utilidad, pero pasemos al siguiente requerimiento.

Requerimiento 2) poder saber el nombre del usuario pero no modificarlo, para eso hay que agregar solo un método get para ese atributo:

1
<?php
2
3
class Usuario{
4 private
$nombre;
5 private
$nombreReal;
6 private
$edad;
7 private
$clave;
8
9 public function
getEdad() {
10 return
$this->edad;
11 }
12 public function
setEdad($edad){
13
$this->edad = $edad;
14 }
15 public function
getNombre(){
16 return
$this->nombre;
17 }
18 }
19
?>



Ahora se puede consultar el nombre pero no modificar, pues el atributo no es visible desde fuera del objeto, solo a través de los métodos públicos que vamos definiendo.

Requerimiento 3) no nos interesa que se sepa el nombre real del usuario

Lo dejamos como está y queda inaccesible desde fuera del objeto.

Requerimiento 4) queremos que pueda colocar una nueva clave si el usuario se la olvida, pero no saber la que existe actualmente

Para eso, hacemos lo contrario que con el atributo nombre, agregamos un método "set" pero no el "get":

1
<?php
2
class Usuario{
3 private
$nombre;
4 private
$nombreReal;
5 private
$edad;
6 private
$clave;
7
8 public function
getEdad() {
9 return
$this->edad;
10 }
11 public function
setEdad($edad){
12
$this->edad = $edad;
13 }
14 public function
getNombre(){
15 return
$this->nombre;
16 }
17 public function
setClave($clave){
18
$this->clave = $clave;
19 }
20 }
21
?>



Pronto, usando simples métodos podemos reforzar el diseño de nuestro objeto, restringiendo según nuestra necesidad el acceso a sus atributos.

Formalicemos: "Getter/Setter es solo un tema de conceptos"

Cuando empezamos a aprender a usar Objetos el primer error que cometemos es dejar todos los atributos públicos, lo que permite que cualquier usuario de nuestra clase pueda hacer y deshacer sin control nuestro objeto (modificando y consultando sus valores).

Generalmente nuestros objetos deberían contener determinada información que no necesariamente el usuario de nuestro objeto debería saber, porque no conviene, o porque directamente no corresponde y permitirle acceder a la misma es aumentar innecesariamente la complejidad del uso del objeto.

Regla: "Evitar que el objeto muestre detalles de su implementación"

Otro ejemplo: si tu sabes que tu objeto "Persona" tiene una fecha de nacimiento y calculas su edad, no deberías poder permitir que alguien "de afuera del objeto" cambie la edad, pues está relacionada con otra información (fecha de nacimiento) y a partir de ella es que se genera (calcularEdad()). Lo correcto sería modificar la fecha de nacimiento para que el propio objeto la vuelva a calcular.

Los detalles del funcionamiento del objeto son internos, y el usuario del objeto (otro desarrollador u otro sistema) no debe ni necesita conocerlos. Por consiguiente ya tenemos otro caso claro, el atributo "edad" no debería poder ser modificado externamente, pero sí consultado cada vez que se necesite. Si este fuera un atributo público sería imposible restringir una operación y habilitar la otra. De ahí que nace el concepto de "getter / setter", o de "métodos accesores / modificadores", o como muchos autores se refieren a estos métodos especiales como "propiedades" (pero creo que puede generar confusiones con el concepto "atributo", pues muchos otros autores usan las mismas palabras indistintamente).

Si tú colocas atributos privados, estos serán solo "vistos / accedidos / usados / modificados" dentro de la propia clase. Si tu quieres que puedan ser accedidos desde fuera de la clase, debes crear métodos públicos que internamente "accedan" a los atributos, pero que los dejarán "resguardados" dentro del objeto (no hay que olvidar que en un caso pueden hacer una operación u otra, no necesariamente ambas).

Recalco, digo "nomenclatura", puesto que los nombres de los métodos pueden llamarse como quieras, pero si cumplen con ambas definiciones (get/set), complirá con la esencia de la funcionalidad. El tema es, por convención, se tiende a reconocer así a los métodos que solo sirven para "hacer operaciones básicas como si trabajáramos con atributos públicos", y que además, no deben tener más complejidad que esa. De lo contrario, ya sería mejor que crearas un método comunes y corriente, asignándole un nombre claro a su acción.

Errores más comunes

Definir todos los "get" y "set" para todos los atributos existentes. Es casi lo mismo que si fueran todos públicos, careciendo de utilidad. Lo habitual es que esto no suceda, cuanto más escondamos de nuestro objeto mejor será, pues disminuimos la complejidad de su uso y evitamos que cambie a un estado que no queremos, y cuando menos se sepa de como trabaja internamente, más fácil será poder reutilizarlo en contextos distintos (deberá ser raro que debas dejar disponible todo y no existan algunos que sean solo de uso interno).

Otro error común es agregarle más lógica que asignar un valor o retornar el valor del atributo. Si necesitas agregarle lógica, ya dejan de ser "get / set", lo cual es mejor que cambiemos de nombre y lo dejemos con los demás métodos comunes de nuestra clase.

Por ejemplo: si para cambiar el nombre del usuario, antes de asignar el valor voy a la base de datos y verifico que no exista otro igual, y luego en caso de nombre duplicado genero otro alternativo, etc, yo preferiría o desglosar el método setNombre en varias llamadas a métodos privados, o directamente crear un método nuevo que se llame cambiarNombre, reflejando un proceso fuera del simple get/set.

Nota: esto es muy a nivel personal, hay opiniones encontradas sobre tener una lógica elemental dentro de un set/get o hacerlo tan extenso como necesitemos. Claramente yo estoy en el primer grupo.

Como detalle, para que quede más evidente y visualmente claro

Como todo es convención a la hora de definir la forma de trabajo en un entorno de desarrollo, es habitual que los atributos siempre vayan juntos al principio de la clase e inmediatamente -antes de empezar a definir los métodos- deberían estar los métodos "accesores / modificadores". Lo que se suele hacer, pues son métodos muy simples y generalmente carentes de mucha lógica (como se explica en el punto anterior), tal vez sería mejor hacerlos en una sola línea, sin indentación:

1
<?php
2
3
class Usuario{
4 private
$nombre;
5 private
$nombreReal;
6 private
$edad;
7 private
$clave;
8
9
/** getter / setter */
10
public function getEdad() {return $this->edad;}
11 public function
setEdad($edad){$this->edad = $edad;}
12
13 public function
getNombre(){return $this->nombre;}
14
15 public function
setClave($clave){$this->clave = $clave;}
16
17 }
18
?>


Nota: De todas formas no tomar esto más de un ejemplo, ya que el estándar oficial de condificación para PHP (el que define la empresa Zend) no sugiere en ningún momento esta práctica.

En resumen

El tema no es tan complejo, de forma genérica esta es la explicación de qué es "getter/setter" y para qué sirve y cómo se usan.

También quiero destacar que a pesar de existir esta técnica, no quiere decir que deba ser usada o que su uso esté completamente permitido. Hay que entender que la POO no debería hacer uso de de los getter y setters ya que tendríamos acceso de forma directa al "estado del objeto" (la información que tienen los atributos de un objeto) y permitir el acceso o modificación genera el mismo efecto de manipulación que si fuera una operación de "corazón abierto". Nuestro objeto debería estar protegido del exterior y no permitir tener acceso directo a sus atributos, y trabajar siempre sobre sus métodos ("los métodos definen el comportamiento del objeto"). En caso de no poder hacerlo, se podría priorizar disponer de "get" (obtener valor de un atributo de forma directa) y no "set" (modificar un valor directo de un atributo), y en el peor de los casos, tener un uso muy controlado de los "set".

Para más información sobre diseño OO, discusiones teóricas, buenas prácticas, etc, consultar escritos de gurúes como Martín Fowler.

Artículo basado en una respuesta dada en Foros del Web

Desde Zend Framework se puede hablar con los servidores de Google

"En muchas ocasiones, los desarrolladores de estas aplicaciones desean insertar datos provenientes de otros servidores, como por ejemplo de los de Google, el cual ha ordenado la información a través de diferentes servicios. Así, ha surgido (tal y como se anuncia en este post oficial) la librería 'Zend Google Data Client Library', la cual permite incorporar a nuestros desarrollos datos provenientes de 'Google Base', 'Google Calendar', Blogger o 'Google CodeSearch'. "

Noticia completa en: Dirson

Diferencias entre un ambiente PHP4 y un ambiente PHP5

Cuando migré mi entorno de desarrollo a la distribución Fedora Core 5, una de las primeras en incluir PHP5 de serie, tuve que hacer "pruebas de compatibilidad" para asegurarme que los sitios que necesitaran seguir usando PHP4 no dejaran de funcionar.

Google Trends mostrando las tendencias de las búsquedas de los usuarios sobre ambas versiones de PHP, comparándolas entre ellas. El salto que hace la línea roja, que representa a PHP5, fue justamente el año de liberación del mismo (2004).

Recientemente se repitió una situación similar: en la universidad donde empecé a dar clases de programación con PHP5 hubo que acondicionar la infraestructura de los laboratorios para que soportaran esta versión. El primer miedo que se generó fue que al actualizar la herramienta los cursos que seguían usando PHP4 se encontraran con el problema de que sus aplicaciones dejaran de funcionar.

Las únicas diferencias que recuerdo me causaron alguna dificultad cuando quise probar sitios PHP4 en el nuevo entorno PHP 5 fueron:
  1. Las variables pasadas por la URL - en PHP4 quedan disponibles inmediatamente, pero en PHP5 es obligatorio usar $_GET, $_POST, o directamente $_REQUEST.
  2. Las variables globales - aunque por suerte nunca usé (no es recomendable), están deshabilitadas en la configuración en PHP5 (register_globals = Off).
  3. Objetos siempre por referencia - en PHP4 todo es por valor a menos que se diga explícitamente (&), en PHP5 los objetos son automáticamente por referencia, no así las variables (que quedan igual que antes, por valor).
Fundamentalmente el punto 1 fue lo único que hizo que alguna aplicación no funcionara.

Con respecto a la configuración general

Existen algunos detalles que recuerdo de la configuración que creo importantes tener presentes ante cualquier problema que pueda surgir (en muchos casos la primer línea comentada con mi sigla EP es la original, la segunda corresponde a mis valores actuales):

; Enable compatibility mode with Zend Engine 1 (PHP 4.x)
; Es el valor por defecto, y php4 debería funcionar de todas formas
zend.ze1_compatibility_mode = Off

;EP error_reporting = E_ALL
error_reporting = E_ALL & ~E_NOTICE & ~E_STRICT

;EP display_errors = Off
display_errors = On

;EP display_startup_errors = Off
display_startup_errors = On

;EP ignore_repeated_errors = Off
ignore_repeated_errors = On

Documentación del manual

"Aunque PHP 5 ofrece varias características nuevas, está diseñado para ser tan compatible con versiones anteriores de PHP como es posible, y con muy poca funcionalidad afectada en el proceso."

Capítulos del manual oficial: Faq Migration y Migration5

Artículos varios:

No es tan dramático el cambio, pero hay que tener en cuenta estos detalles y hacerlo sin prever las consecuencias de una posible migración de software que luego fuera complicado revertir.

Consideraciones sobre el uso del Patrón Singleton desde un entorno web con PHP

Uno de los usos habituales del Patrón de Diseño Singleton es concentrar en un único objeto todas las llamadas a la base de datos y que este se encargue de que nuestro sistema use una única conexión, compartida por todos los que la necesiten.

La lógica del patrón es simple

La lógica es simple, la primera vez que alguna parte de nuestro sistema necesita conectarse a la base de datos, se le pide una instancia de conexión al Singleton implementado en nuestra clase de Persistencia (una clase que separa nuestro código de "lógica de negocio" del código explícito para trabajo con base de datos). Si en las siguientes peticiones esta instancia existe, el Singleton devuelve siempre la misma, así se reutiliza sin crear nuevas.

Ventajes del uso del patrón

Esto evita que nuestro sistema, en un momento dado, tenga innumerables y descontroladas conexiones a la base de datos, consumiendo recursos y tal vez, el máximo permitido por vez (configurado en la misma base de datos). A su vez, al tener todas las conexiones centralizadas, podemos implementar todo tipo de controles y auditorías (registrar cantidad de conexiones, que partes de nuestro sistema realiza más conexiones, horarios para las mismas, etc, etc).

El problema

Lo habitual en "sistemas de escritorio" (no web) es que esta instancia se mantenga generalmente durante toda la vida del sistema, lo cual sería acertado decir que la instancia reutilizada de conexión es siempre la misma (única). Pero en ambientes web, el contexto es distinto y la forma de trabajo cambia.

Por esta razón es muy común que se repita la siguiente consulta en foros:

"Una vez ejecutado el patrón en un página/fuente/scripts, los objetos se destruyen, desapareciendo la instancia del Singleton. Por lo que si se ejecutara nuevamente, todo volvería a repetirse de cero, y no se aprovecharía en toda la aplicación, solo por página."

El problema es ese, el mundo "stateless" ("estado desconectado") de la web, donde queda claramente evidenciado al intentar implementar el patrón "Singleton".

Cuando tu estás, por ejemplo, en una aplicación desktop hecha en Java, tu código está siempre corriendo, de forma permanente. Si tu creas una conexión con la base de datos, siempre estará ahí mientras viva la aplicación (o te desconecte el servidor de base de datos, etc), y cada vez que invoques el "singleton" este funcionará correctamente en todos los casos.

En situaciones "típicas" de la web (sin las conexiones persistentes), luego de terminar la ejecución de un página, pasamos al "estado desconectado" y perdemos todos los objetos. En este contexto, solo tendría sentido el "singleton" si tu página debe hacer llamadas a varios objetos que tienen acceso a la base de datos y tu quieres tener control sobre estos accesos.

Pero luego de concluida la página (terminamos de ejecutar la última línea de nuestro php) terminó la función del "singleton", y el próximo contexto será una nueva ejecución de la página, esta misma u otra distinta.

Conclusiones finales

Resumiendo, serían:

"Se puede implementar perfectamente el patrón Singleton con PHP, pero por el contexto web, este se aplicará normalmente durante la vida de una única página, a menos que implementemos algún mecanismo para persistir el objeto Singleton y así lograr que este perdure durante toda la vida de la aplicación web"

Estas son mis conclusiones aplicadas al mundo PHP desde el mundo Java; si no les gustan, tengo otras

Artículo basado en una respuesta que di en Foros del Web:

Smarty: cambiar el idioma del "html_select_date"

El motor de templates Smarty dispone de muchos comandos que una vez invocados generan un componente (compuesto por código html) para nuestra interfaz web.

En este caso concreto conoceremos a html_select_date, que con solo invocarlo dentro del código de un formulario (encerrado entre los tags <form> y </form>) generará 3 combos con el día, mes y año. Esto es útil para cuando queremos hacer un formulario que consulte a partir de una fecha, o entre un rango de fechas. Smarty nos da las herramientas para no tener que lidiar con el código html y poder rápidamente disponer de estos componentes.

Nota: deberemos contar con una estructura base para poder poner esto en funcionamiento.

En nuestro archivo de template deberemos tener el código estándar html para el formulario, más el tag correspondiente para el componente generado por Smarty:


<form NAME="form1" ACTION="generarConsulta.php">

<!--{html_select_date}-->

<button name="Aceptar">Aceptar</button>

</form>


Y esto generará el siguiente resultado:


También podríamos hacer un formulario que tuviera un rango de dos fechas para filtrar los datos de nuestra consulta, por que lo que podríamos hacer el siguiente código, ajustando algunos parámetros:


Que dará por resultado la siguiente interfaz:

La documentación sobre este componente es muy clara, ofreciéndonos varios parámetros para adecuar el mismo a nuestras necesidades.

Pero el primer problema que nos encontramos, y que no aparece claramente en la documentación, es como cambiar el idioma del contenido del mismo (como se ve en ambas capturas de pantalla, los meses se encuentran en inglés).

Aprender a pescar, no a comer de la mano

Consejo: cuando no encuentres algo en la documentación de Smarty, ve al foro del sitio oficial (enlace arriba a la derecha) y busca dentro de las consultas de los usuarios... y generalmente encontrarás lo que buscas.

Smarty usará la configuración del idioma, fechas, etc, que venga definido desde el entorno de PHP, por lo que deberemos para este caso tener correctamente la fecha configurada con setlocale:


setlocale (LC_TIME,"spanish");

Y obtendremos el resultado esperado:


Si no sabes como empezar a trabajar con Smarty, además de sugerirte que recorras el manual (que tiene una versión en castellano), puedes ver otros artículos que he escrito al respecto.

Espero que te sea útil este "detalle" del idioma ;-)

¡Hoy iniciamos el curso en Universidad ORT!

Confirmando: el curso finalmente se abrió y los días asignados son los lunes y miércoles, de 19:30 a 22:30... y hoy es oficialmente la primera clase. ;-)

En primera instancia eran los martes y jueves, pero me informó la administración de ORT que siempre es una locura esta semana, entre la apertura de las carreras y los cursos, se están moviendo de salón constantemente, y por una razón locativa (somos un grupo reducido) quedamos asignados en estos días.

Con respecto al "podcast", al momento no dispongo de los recursos técnicos para hacer una grabación digital de la clase (todavía no me doy por vencido, veremos que se puede solucionar).

Con respecto a los materiales, estoy viendo de dejarlos disponibles en la web (no será lo mismo sin acompañar con explicaciones, pero por lo menos es un registro de la ruta seguida).

Dentro de algunas horas, más novedades.

En los próximos días iniciamos el curso "Desarrollo de Sistemas Web con PHP5"

Quiero recordar a los posibles interesados en el tema de Desarrollo de Sistemas Web Orientados a Objetos basados en el lenguaje PHP5 y en conocer todas las herramientas disponibles para potenciarlo, que estaríamos abriendo el primer curso los próximos días de la semana que viene en la Universidad ORT.

A pesar de que ya he dictado con esta temática capacitaciones a medida para empresas, este es el primer curso de inscripción abierta que se dicta en la plaza.

Como hay que pagar el derecho de piso por ser un curso completamente nuevo y casi desconocido en el mercado, pero que ha generado muchas expectativas por su rico y extenso contenido, se ha decidido abrirlo a pesar de que el primer grupo pueda ser reducido.

También podrán conocer un breve resumen que describe mi visión personal del contenido del curso.

Veremos lo último de lo último del ambiente PHP, tratando de subir el perfil de los desarrolladores al nivel de plataformas como Java o .Net, y si no lo vemos en el curso, es porque no existe siquiera una beta para probarla ;-)

No dejes que mañana vengan a discriminarte en una entrevista de trabajo con el título de "Programador PHP" (alguien que conoce el lenguaje y que solo sabe hacer "scripts estructurados") o "Diseñador PHP" (que sabe algo de diseño web y muy poco de programación de sistemas). Tu puedes conocer y entender todas las disciplinas necesarias para ser un Desarrollador de Sistemas Web Orientados a Objetos.

¿Seremos conformistas con nuestros conocimientos o nos animaremos a evolucionar?

¿Vas a participar de la "Era Web" como usuario o como desarrollador?

Muchos de los temas que vamos a ver se dan a lo largo de una carrera de más de 2 años (UML, Diseño OO, Patrones de Diseño, Refactoring, Frameworks, Webservices, Ajax, etc).

Si te gustan los retos, te espero ;-)

Entradas populares