Reglas básicas para trabajar con clases bajo PHP (actualizado)

Discutiendo sobre el tema en un foro hice el siguiente resumen básico de cómo deberíamos trabajar con clases bajo PHP:
  1. Una clase debe estar en un solo archivo/fichero, y el nombre del archivo/fichero debe ser el mismo que el nombre de la clase. Por ej, "Cliente.php" y la clase internamente debe llamarse "Cliente", en "ningún caso" [1] los nombres deben diferir (simil Java).
  2. Cada clase debe manejar su relación con otras clases de forma independiente de las clases con las cuales interactúa: para que una clase sea consistente esta debe saber a qué clases llamar para poder trabajar, sin importar que otra clase con la que debe relacionarse comparta una misma relación. A pesar que PHP permita colocar todos los include/require a las clases en un archivo centralizado (como muchas veces se hace en "index.php") , debemos evitarlo. Lo único que logramos es que la clase sea inconsistente en otro contexto al fallar porque ella no sabe resolver sus relaciones (imaginemos que una de esas clases no se usará en index.php, por lo tanto no estará la lista de include/require de clases que necesita para poder funcionar).
  3. En la relación entre las clases debes usar require_once, lo que resuelve si dos clases que se relacionan entre sí dependen a su vez de la misma clase, por consiguiente solo se invoca una vez, y seguimos manteniendo la independencia de la clase, ya que si nos llevamos una de esas clases a otro contexto, esta seguirá funcionando correctamente y permitirá el reuso normal de la misma sin dar ningún tipo de error de "clase ya requerida" (si usas solo include o require, no puedes llamar dos veces a la misma clase, por eso existen include_once y require_once).
  4. En un mismo contexto, nunca redefinir la misma clase, ya que pierde consistencia el diseño del sistema. Por ej, en un sistema contable tener una clase Cliente que según la clase que la llame puedan "reescribir" internamente la clase para que su diseño sea distinto a la clase original. Una clase debe ser única en un mismo sistema, no puede ser que existan dos versiones de la implementación de una misma clase.
  5. Anexo: debemos usar todos el mismo estándar de codificación (Zend)
Originado a partir de una consulta en un foro: "¿Redeclarar un clase?"

Notas complementarias

  • [1] - Estamos hablando de lo básico de POO para PHP, particularmente este punto puede variar como lo hace trabajar con una herramienta como Zend Framework, ya que PHP no encuentra por sí solo la ubicación física de una clase usan la "artimaña" de colocar en su nombre la ruta para llegar a ella. Esta práctica no es un "estándar" y debería en algún momento caer en desuso si se implementa correctamente el manejo de "namespace" en alguna versión futura de PHP. Pero volvemos al principio, con esta práctica el nombre de la clase queda distorsionado, ya que ahora, además del nombre está la ruta para llegar a la clase y esto es solo por un tema de la incapacidad de PHP y no tiene nada que ver con la POO (gracias GeL/T0 por tus valiosos comentarios ;-))

6 comentarios:

GeL/T0 dijo...

Buenas,

Yo discrepo ligeramente con el primer apartado, o mejor dicho puntualizo, porque por ejemplo tenemos el caso del framework de Zend que a la clase no la llama exactamente como al archivo, sino como la ruta completa del archivo. Esto es muy útil y yo siempre lo utilizo porque da mucha mayor libertad a la hora de estructurar un proyecto.

Digamos algo del estilo.
Archivo: /Data/Db/Mysql.php
La clase se debería llamar: Data_Db_Mysql

Esto se puede ver mejor explicado en el framework de Zend, que para ser un comentario ya es bastante denso. ;-)

PS: Lógicamente con esto lo que consigues es poder utilizar métodos mágicos que te ahorren los includes... Pero eso daría ya por completo para un post.

enrique_place dijo...

Estimado GeL/T0:

Sabes que tienes razón, el post lo hice pensando en lo "básico" de trabajar con POO en PHP, y en ese punto en particular, sobre la costumbre de algunos desarrolladores de crear nombre distintos para el archivo y la clase sin justificación alguna.

Lamentablemente PHP aún no sabe resolver el problema de encontrar un archivo de una clase sin tener que decirle donde está cada uno, por lo tanto entramos en estas "artimañas" para poder hacerlo.

Bien dices, esta es una práctica que incorpora ZF y que perfectamente podría hacer otro desarrollador, por lo tanto es una excepción a la regla (es con una justificación concreta).

Veo entonces de ajustar el post, gracias ;-)

A.M. dijo...

Yo declaro en un archivo (que siempre llamo de antemano) una serie de constantes como por ejemplo: APP_ROOT, DIR_CLASES, etc. Estas constantes tienen la ruta física de cada uno de esos directorios en base a las variables $_SERVER. Cuando las declaro, directamente pongo require(DIR_CLASES . "/clase.class.php"); y listo. Me despreocupo de la carpeta desde la cuál incluya la clase.

Isra dijo...

A partir de la versión 5.3 de PHP, require y require_once se comportan de la misma forma (y lo mismo con include e include_once).

enrique_place dijo...

Que tal A.M. ;-)

Es correcta tu práctica, algunos consejos:

- puedes revisar como hacen algunos frameworks que definen en su arranque (todo centralizado desde su index) usando set_include_path, y no tener que hacerlo en todos los lugares donde incluyes una clase.

- de todas formas, no soy partidario que las cargas sean automáticas (sé que no es el caso, pero aprovecho a comentarlo), creo que más que organizar en un directorio de clases, deberías pasar al concepto de "paquetes" e incluir solo las clases "fachada" de ese paquete (reusas a nivel de paquetes y no de clases, organizas a más alto nivel, y solo dependes de una clase fachada y no de todas las clases que están en el paquete).

No es complejo y así es cómo trabajan en sistemas como Java o .Net.

Saludos! ;-)

enrique_place dijo...

Que tal Isra ;-)

No estaba al tanto de ese cambio, gracias por comentarlo ;-)

PD: hace años que solo uso casi exclusivamente el require_once por el tema de los objetos.

Saludos! ;-)

Entradas populares