Modelos en PHP: cosas buenas/malas del lenguaje

PHP es un lenguaje muy fácil de aprender si se tienen conocimientos en C/C++/Java/C# o similares.  Es muy fácil de utilizar y es muy fácil de desarrollar aplicaciones pequeñas-medianas con él.

También, como todo en la vida, tiene sus desventajas.  Lo interesante es que a mi parecer, las ventajas del lenguaje son también desventajas y viceversa según como se miren, es decir, según lo que se necesite.

En este momento me interesa mencionar dos de ellas:

  • Fuera de la caja de se obtiene lo básico, un lenguaje para empezar a escribir código, a diferencia de otros lenguajes que incluyen por si mismos todo un framework o ambiente de desarrollo.
  • Es un lenguaje señoritero, la falta de tipos y de la mucha rigurosidad de los demás lenguajes hace que hasta la gente que no sabe desarrollar software crea que si lo hace.

Estas son verdades: el lenguaje es deficiente para muchas cosas aunque les duelan a algunos que les gusta desgastarse simulando fanatismos hasta por un lenguaje de programación.  Pero como mencioné anteriormente, son cosas buenas/malas según como se les mire.

  • La independencia de tanta infraestructura que tal vez excede lo que necesitamos evita que las soluciones pequeñas y puntuales se conviertan en todo un circo de capas y niveles que consumen tiempo, recursos y paciencia.  Sería como utilizar JSF+Hibernate+Spring para hacer un HolaMundo.  Las soluciones son de la forma y el tamaño como el desarrollador las quiera: el problema es saber que querer y como lograrlo.De todos modos hay muchos frameworks para PHP allá afuera, desde los diminutos, los medianos y los grandes: MoonPHP, Picora, CodeIgniter, KohanaPHP, CakePHP, Prado, Symfony y Zend para nombrar a solo unos pocos del montón que existen en esta Internet que es tan larga como ancha.
  • Esta falta de rigurosidad bien utilizada, nos permite aprovecharla para hacer cosas cosas interesantes.  Todo es un arma peligrosa o una herramienta útil según quien la esté sosteniendo.

Y es con la flexibilidad que confiere la falta de rigurosidad la que permite o facilita la implementación -rápida- de códigos útiles.  MyModel 0.1 es solamente una demostración de las cosas que se pueden hacer con PHP y estoy seguro casi nadie conoce.

Los modelos son la representación de las clases de la lógica del negocio en una aplicación.  Algunos dicen que coinciden 1:1 con las entidades de persistencia: tablas de la base de datos.

Para los modelos, clases ellos con atributos y métodos, gracias al encapsulamiento acostumbramos a definir sus atributos como private/protected y a implementarles métodos setter/getter (obt/pon) para modificar o consultar su estado.

Este procedimiento trae consigo consecuencias negativas en medio de todo lo útil que es el encapsulamiento.

  • Hay que hacer métodos set/get para todos los atributos (que sea interesantes) de todas las clases de los modelos.
  • La mayoría de las veces hacemos unos métodos setter/getter que daría lo mismo que los atributos fueran public.
  • Es tedioso hacer los métodos, mas aún si como acabo de mencionar no incluyen siempre una ventaja tangible.  Los IDEs amables acostumbran a hacer por nosotros las plantillas básicas de estos métodos.

Este mes estuve pensando como poder hacer algo para solucionar estos problemas con PHP y recordé los métodos __set/ __get incluídos en toda clase PHP y se me ocurrió intentar implementar algo como las propiedades de .NET pero que funcionaran de manera automática.

Rápidamente implementé una primera versión que permite hacer esto.

Persona es una clase con un atributo llamado $nombre.  Si Persona hereda de MyModel estará entonces posibilitada para hacer esto:

$p -> Nombre = "Jorge";
echo $p -> Nombre;

La sobreescritura de los métodos mencionados antes me permiten decirle al modelo que cuando le hablen de la propiedad Nombre haga referencia al atributo nombre.  Mas aún, cuando le hablen de Nombre primero verifique si existen los métodos setNombre y getNombre y haga uso de ellos.

Una segunda mini versión le agregó un poco mas de encapsulamiento.

  • Si el atributo es private, no se puede acceder de ninguna manera.
  • Si el atributo es protected sólo se puede acceder desde el exterior si tiene setter/getter.
  • Si el atributo es public se puede acceder externamente.
  • Si el atributo es public pero tiene setter/getter, estos métodos serán utilizados en lugar del acceso directo.
  • Sólo las propiedades cuyos métodos setter/getter sean public pueden ser accedidas desde el exterior.

Con esto podemos hacer, digo yo, los modelos con atributos public y filtrar con métodos setter/getter los que nos interese restringir su acceso.

Ejemplo:

Téngase en cuenta a la clase User cuya implementación es de la siguiente manera.

class User extends MyModel
{
    private   $id;
    public    $username;
    public    $password;
    protected $name;

    public function getPassword()
    {
        return str_repeat("*", strlen($this -> password));
    }

    public function setName($value)
    {
        $this -> name = "--- " . $value . " ---";
    }

    public function getName()
    {
        return strtoupper($this -> name);
    }
}

Considérese un programa que la utiliza como se muestra a continuación.

$u = new User();

// $u -> id = 7;                               // Inválido porque $id es private y no ha métodos set/get.

$u -> Username = 'jimezam';                  // Se accede directamente porque $username es público.
echo "username: " . $u -> Username . "
";    // Se accede directamente porque $username es público. $u -> Password = 'secreto';                   // Se accede directamente porque $password es público. echo "password: " . $u -> Password . "
";    // Se ejecuta getPassword. $u -> Name = "Jorge Ivan";                   // Se ejecuta setName. echo "nombre: " . $u -> Name . "
";        // Se ejecuta getName.

El resultado es el siguiente por los motivos explicados en los comentarios frente a cada línea del código.

username: jimezam
password: *******
nombre: --- JORGE IVAN ---

Se aceptan sugerencias constructivas para ir complementando a MyModel.

Enlaces:

2 thoughts on “Modelos en PHP: cosas buenas/malas del lenguaje”

  1. No tengo una sugerencia =(
    Solo tengo algunas dudas al respecto porque soy nuevo en el mundo de la POO

    Donde dices
    $u -> Name = “Jorge Ivan”; // Se ejecuta setName.
    echo “nombre: ” . $u -> Name . “”; // Se ejecuta getName.

    Como save la clase User que cuando le dices “$u -> Name = “Jorge Ivan”; ” se ejecute el la ” funcion setName” y para su $value use la variable “protected $name;”?

    Ahora que pasa los constructores y destructores?

    Gracias por información que publicas

  2. Saludos @AarD, gracias por el comentario.

    La lógica del llamado al método setName cuando se asigna un nombre y al método getName cuando se solicita el valor del nombre reside en la implementación de los métodos __set y __get respectivamente, de la clase MyModel Por favor descarga el código y lo revisas.

    La utilidad de estos métodos, también conocidos como mágicos, es precisamente esa, son invocados de manera inteligente tan pronto como se intenta modificar un atributo del objeto u obtener un valor de uno de ellos. Lo que hace MyModel es aprovechar esto para crear un (propuesta muy básica de) modelo flexible.

    El constructor se ejecuta tan pronto se crea la instancia con el operador ‘new’, es decir, este proceso debe suceder antes de utilizar el modelo ya que antes de eso sólo tenemos el valor de ‘null’.

    El destructor, de manera antagónica, se ejecuta cuando ya no existan referencias al objeto, es decir, cuando ya no sea útil. El uso del modelo transcurre entre estos dos hitos.

    La siguiente URL te puede aclarar aún mas el concepto de los métodos mágicos de PHP.

    http://www.php.net/manual/en/language.oop5.overloading.php#language.oop5.overloading.members

Leave a Reply

Your email address will not be published. Required fields are marked *