introducción pcm y pcmb
TRANSCRIPT
Página 0
Introduccio n PCM y PCMB PHP Component Model y PCM Basic
Éste paper está orientado a la introducción a PHP Component Model, un modelo de
trabajo basado en componentes, que tiene como objetivo mejorar la reusabilidad,
extensibilidad y calidad de un código en php.
[Seleccione la fecha]
Introducción PCM y PCMB 2013
1 Redactado por Alexander Eberle Renzulli para Underc0de.org Puede visitar mi blog en console-input-output.blogspot.com
Introduccio n
PCM es la sigla de PHP Component Model, la idea de éste documento es redactar de la forma
más simple y concisa una introducción a ésta idea de componentes en php.
PCMB es la denominación de un código básico diseñado para soportar PCM y demostrar su
funcionamiento, podría para ilustración del lector compararse con un Framework, pero no
pretende serlo, más bien pretende ser la representación práctica de PCM.
Es importante siendo el segundo párrafo de éste paper, que se explique al lector, que PCM en
Ningún momento puede llegar a compararse con otros modelos de componentes como COM
(Component Object Model de Microsoft), pero esto no se menciona a lo largo del paper
porque se asume que el lector entiende las limitaciones de PHP y que en realidad éste modelo
trata de mejorar la forma de trabajar en php para acercarse lo más posible a un modelo de
componentes real, no obstante no es posible llegar a un grado en el que pueda ser comparado
con otros modelos de componentes.
PHP no fue diseñado para trabajar con componentes, el objetivo de éste modelo es y será el
de apoyar a aquellos programadores de php que quieran empezar a entender la forma de
trabajo con componentes, conocer que existe y las ventajas de trabajar de ésta forma, para
que a la hora de cambiar de lenguaje no represente demasiada complejidad.
Dicho esto, PCM se divide en dos grandes partes, los componentes (Components) y el código
que controla y valida dichos componentes (Component Library System).
A su vez, los componentes se dividen en 4 partes, una de las cuales es opcional por lo que en
realidad se divide en 3 partes importantes, tales partes son, Component Body, Component
Interface, Component Library.
Quiero aclarar que ésta es una versión más actualizada, y si ustedes leen las publicaciones de
mi blog pueden encontrar algunos términos denominados de diferente forma, pero hacen
referencia a las mismas divisiones.
A lo largo de éste paper explicaremos cada parte de PHP Component Model (de ahora en más
PCM), y cómo funciona PHP Component Model Basic Example (de ahora en más PCMB) en
referencia a PCM.
Es de suma importancia aclararle al lector que PCM está en estado experimental cuando se
escribió este documento, por lo que puede sufrir grandes cambios de estructura e ideales en
cuanto PCM valla madurando.
Lamentablemente para que el lector pueda tener una clara comprensión de éste documento,
tiene que tener conocimientos del patrón MVC, de programación orientada a objetos (P.O.O.)
y debe tener dominio de conocimientos tales como Clases, Abstracciones, Herencia, Traits,
Interface. En general estos últimos términos pueden ser encontrados con su explicación en la
página de la documentación de PHP. (referencia a www.php.net)
Introducción PCM y PCMB 2013
2 Redactado por Alexander Eberle Renzulli para Underc0de.org Puede visitar mi blog en console-input-output.blogspot.com
Antes de comenzar con los temas importantes, quiero redactar una breve explicación de la
razón de existir de éste modelo y éste paper.
Yo soy Alexander Eberle Renzulli, estudio en una escuela técnica de argentina, específicamente
en Mar Del Plata, Buenos Aires, Argentina. Y la idea de realizar un modelo de componentes
para php surgió luego de mi idea de implementar diseñar el property para php (que lo pueden
encontrar en el foro underc0de.org, también lo pueden encontrar en infiernohacker.com y
portalhacker.net), cuando yo diseñé el property supongo que ya estaba empezando a
formularme un poco la idea de construir código reusable, ya que diseñé el property con la
única idea de simplificar mis clases a quien la use, no específicamente para mí, por lo que
supongo que ya estaba pensando en ello, pero no lo recuerdo, si sé que luego de diseñar el
property, unas semanas después se me ocurrió empezar a desarrollar clases que fueran lo
suficientemente independientes como para funcionar en cualquier código de cualquier
persona sin tener que recibir ningún tipo de modificación en el código, también les integré
unas cutres interfaces, y pasada una semana se me ocurrió la idea de establecer una forma
explícita para crear dichas clases, que incluya reglas de lo que no se debe hacer y lo que se
debe hacer para tener un orden general en todas las clases, que luego llamé componentes, ya
que pueden ser encastrados en un código y desencastrados de la misma forma (o esa es la
idea) sin realizar ningún tipo de cambio en los componentes.
Quizá el lector se pregunte, ¿Para qué me puede llegar a servir esto? Es bastante simple, cada
componente actúa como un código separado que puede ser utilizado en otro código, y si
seguimos las reglas de éste modelo, ese código no puede ser alterado, está encapsulado por lo
que ni siquiera es necesario conocer su funcionamiento interno, y plantea una interfaz sencilla
y documentada que establece las funciones y atributos de dicho componente, véase su
representación gráfica como un integrado, donde las patas son las funciones y la interfaz es el
datasheet o la hoja con las especificación de que hace cada pata y que valores se esperan de
entrada.
Siguiendo esa idea de componentes como un integrado, piense que dicho integrado puede ser
usado en múltiples circuitos electrónicos, de forma que, en código los componentes pueden
ser integrados en muchos códigos sin tener que reescribir o rediseñar para cada código las
mismas funciones, y sin tener que hacerle ninguna alteración al código, en pocas palabras uno
puede integrar pedazos de código con muchas funciones, que sea seguro, robusto y estable,
usarlos, sin pensar en nada más que las instrucciones de uso que el componente tiene, sin
tener que tocar ni una línea de código, usted tendría armada gran parte y ya estaría
funcionando.
Entonces con solo pensar un poco, usted se dará cuenta que es muy útil, el hecho de no tener
que estar escribiendo una y otra vez el mismo código para cada uno de los proyectos, piense el
tiempo que ahorrará al escribir un código una vez e implementarlo en el resto de sus códigos
futuros sin tener que tocar ni una línea de código.
Y como dice el dicho, el tiempo vale oro.
Por otra parte esa no es la única ventaja, tenga en cuenta que este modelo exige que el
componente pueda evolucionar por separado de cualquier código que lo use, esto es un punto
muy importante, note que usted podrá mejorar, extender y arreglar cualquier componente
Introducción PCM y PCMB 2013
3 Redactado por Alexander Eberle Renzulli para Underc0de.org Puede visitar mi blog en console-input-output.blogspot.com
defectuoso y luego actualizar todos sus códigos que usen ese componente al mismo tiempo,
de forma tal, que usted solo crea una actualización y todos sus códigos que usen dicho
componente podrán actualizarse sin generar absolutamente ningún inconveniente.
Esto último responde a la idea de separar especificación de implementación, y realmente es
muy útil.
Pero si pensabas que esas grandes ventajas eran solo las únicas que tiene esta forma de
programar, estás muy equivocado, dijimos que, te ahorras tiempo porque puedes volver a usar
el mismo código sin tener que tocarlo en varios muchos proyectos, además, puedes actualizar
todos los proyectos con solo modificar el componente sin afectar a cada proyecto en
particular, pero te has puesto a pensar qué ocurrirá cuando ya tengas muchos componentes,
lo más probable es que cuando tengas que crear un nuevo proyecto, tengas casi todo
programado, ya que lo más probable será que tengas componentes para cada necesidad, pero
por supuesto no cobrarás menos el trabajo porque ya tengas hechos todos los módulos,
entonces cuanto más tiempo programes de esta forma, cada vez menos costo tendrás al
desarrollar un proyecto, y por ende más ganancias.
Y además tiene otras ventajas que no me pondré a explicar porque me llevaría demasiado
tiempo. Quizá te hayas puesto a pensar, o deberías haberlo pensado, si esto es tan útil, ¿por
qué no hay muchísima gente que lo use? Esto no es nada nuevo, desde Windows 98 se puede
apreciar que muchos programas tienen este modelo (véase famosas DLLS, que si se fijan la
descripción de un archivo dll dice “extensión de aplicación”), hace muchos años que esto se
está usando, pero el costo inicial de desarrollar de esta forma es muy alto, programar a
mansalva como hace la mayoría, una línea tras otra, no requiere mucha complejidad, de hecho
la mayoría de los programadores que siguen esos ideales, programa y programa y programa,
pero no se pone a pensar qué es lo que está haciendo, en cambio, programar componentes es
más complejo, hay que pensar bien cada componente para que pueda trabajar correctamente
en cualquier situación, no sea dependiente del sistema que lo usa, y pueda evolucionar
fácilmente sin afectar el funcionamiento del sistema que use una versión anterior.
Inicialmente programar de esta forma lleva mucho más esfuerzo y tiempo que programar de la
otra forma más común, y de ésta forma cuesta trabajo diseñar componentes para todas las
situaciones, a mí me llevó unos meses poder llegar a ésta idea, quizás a alguien más “aceitado”
le cueste mucho menos trabajo, pero al no ser la costumbre el programar de ésta forma, y
menos en php, requiere de bastante tiempo para acostumbrarse, lograr una cantidad
importante de componentes para que empiecen a verse los frutos, por lo que es una actividad
más bien a futuro.
Supongo que también se preguntarán si no hay algo así y estoy reinventando la rueda, en
realidad no puedo afirmarlo, pero no vi un modelo de componentes para php que realmente
hiciera lo que dice, la mayoría de ellos no logra que la gente pueda realizar componentes de
prácticamente cualquier parte de su código.
Hasta aquí llegamos con la introducción, traté de realizar cada párrafo de la forma más concisa
y pequeña posible.
Introducción PCM y PCMB 2013
4 Redactado por Alexander Eberle Renzulli para Underc0de.org Puede visitar mi blog en console-input-output.blogspot.com
Componentes
Como expliqué en la introducción, PCM se divide en dos partes, el Componente y el
Component Library System.
En ésta parte del paper explicaré una introducción de los componentes, luego en otra parte
explicaré el Component Library System.
Los componentes se dividen en tres partes, Component Body, Component Interface y
Component Library.
Características generales de componentes Un componente debe tener ciertas características, en términos generales son:
- Ejecución Independiente
- Evolución Independiente
- Funcionalidad Independiente
- Compatibilidad absoluta a lo largo de versiones
- Eficacia absoluta
- Máxima robustez posible
Si un componente no cumple con las características expresadas previamente, el componente
en realidad no es estable, y puede generar un funcionamiento errático, explicaré a
continuación cada una de las características.
Ejecución Independiente El componente debe poder ser ejecutado de forma independiente, sin ningún tipo de
implementación, más que una implementación básica que pruebe el componente y cada una
de sus funciones.
No obstante la implementación debe únicamente hacer uso del componente, no puede tener
nada más que, la creación de una instancia del componente, y una llamada por cada función.
Si el componente no es capaz de ejecutarse y funcionar sin necesidad de líneas de código extra
(como la conexión a la base de datos, o inclusión de un archivo de configuración, ni siquiera
llamar a la función sesión_start(); u ob_start();) y solo teniendo en la implementación
funciones del propio componente, dicho componente no es válido, y es dependiente del
sistema que lo utiliza.
Evolución Independiente Un componente debe poder ser mejorado por si solo, extendido y ampliado por si solo, sin
necesidad de conocer el sistema para el cual se amplía, ni tenerlo, debe poder ser mejorado y
extendido únicamente teniendo el código del componente.
Si dicho componente no puede ser mejorado, modificado, etc. Sin la necesidad de tener el
código del sistema que lo utiliza, el componente está atado a la evolución del sistema, y es
inválido.
Introducción PCM y PCMB 2013
5 Redactado por Alexander Eberle Renzulli para Underc0de.org Puede visitar mi blog en console-input-output.blogspot.com
Funcionalidad Independiente El componente debe contener funciones que respondan a la especificación del propio
componente, esto quiere decir, que no debe tener código que no corresponda a su objetivo,
por ejemplo, no debe tener conexiones a la base de datos, ya que genera una dependencia
importante, primero hacia el controlador de base de datos que se esté utilizando en el
componente (por ejemplo PDO) lo cual evita al que implemente dicho componente tener la
libertad de elegir su propio controlador de base de datos. Y por otra parte genera una
dependencia hacia la configuración y base de datos en sí que esté utilizando.
No debe depender de funciones externas al componente, únicamente funciones de PHP que
no generen dependencias hacia miembros externos.
Compatibilidad absoluta a lo largo de versiones Un componente debe dar soporte para versiones anteriores cuando haya evolucionado, de
modo tal, que si se borra una función, se notifique al Component Library System de la
eliminación de dicha función, si se cambia el nombre a una función debe ser notificado como
alias de función x, Si una versión nueva del componente no tiene declaradas (mas no es
necesario definirlas), dicho componente puede generar errores con códigos viejos que utilicen
el componente y lo hayan actualizado, generando así un conflicto.
De modo que el componente que no cumpla esta condición la nueva versión es inválida y
desaconcejada, lo más probable es que el Component Library System, note la falta de una
función y desactive el componente guardando la notificación en el log de errores del
Component Library System, y dando de baja dicho componente del registro de componentes.
Eficacia absoluta El componente no debe tener funciones en estado deprecated o experimental, tales funciones
pueden tener un comportamiento errático, y generar un conflicto en el componente, si un
componente no cumple esta condición está ABSOLUTAMENTE DESACONCEJADO! Ya que
puede comprometer la integridad del sistema que lo utilice.
Desarrollar componentes de esta forma describe al autor del componente como
incompetente.
Cuando php.net lanza una nueva versión, se debe revisar los componentes creados y actualizar
las funciones que hayan sido quitadas.
Lo que ocurre es que un componente debe ser eficaz, y si se implementan funciones inestables
o desaconsejadas, pueden hacer al componente ineficaz.
Máxima robustez posible Si bien php presenta limitaciones a la hora de hacer código, es necesario, que cada
programador que desarrolle un componente, lo haga teniendo en cuenta que quien use dicho
componente puede ser un ignorante, (que muchos hay en el mundo) y enviar cualquier dato, o
usar los componentes de forma errática, por ejemplo si hay que utilizar ciertas funciones
primero y otras funciones después, hay que prever que el usuario no llame a las funciones en
el orden correcto, o que si una función utiliza un dato de tipo numérico, el usuario mande un
dato de tipo string, por lo que es necesario que se utilicen técnicas como el casteo para
asegurarnos de que los datos sean correctos.
Introducción PCM y PCMB 2013
6 Redactado por Alexander Eberle Renzulli para Underc0de.org Puede visitar mi blog en console-input-output.blogspot.com
Eso entre otras cosas, no puedo escribir todos los posibles usos erróneos porque me llevarían
muchas hojas, por lo que dejo a criterio de cada desarrollador tener en cuenta éste punto y
tomar las medidas necesarias.
Si un componente no puede asegurar robustez, el mismo puede tornarse inestable en
situaciones inesperadas y comprometer a todo el sistema.
Es necesario que el método constructor de la clase principal del componente no tenga
parámetros obligatorios, por el simple hecho de no generar una dependencia externa.
Component Body Teniendo en cuenta que ya expliqué las características generales que debe cumplir un
componente para ser válido, ahora explicaré la primera parte de un componente, que es
denominada Component Body o cuerpo del componente, ésta parte es en general la parte
más importante, debe contener una clase (ya que los componentes deben estar escritos bajo
el paradigma de programación orientada a objetos) que represente al componente, y que
incluya las funciones públicas, privadas, los atributos, getters y setters que proveerá el
componente.
Todas las partes de los componentes deben estar dentro de una carpeta con el nombre del
componente.
Es necesario que el archivo que contenga el Component Body, se llame con el prefijo
Component por ejemplo, para un componente de corrección ortográfica, le llamaremos
ComponentCorrector.php y que la clase principal que represente al componente se llame de
igual forma, por ejemplo: Class ComponentCorrector
Hay una cuarta parte en los componentes, que se llama extensión, si necesitas tener más de
una clase puedes crear archivos de extensión con el prefijo “Extension” por ejemplo
ExtensionGamatical.php en el ejemplo podría ser una clase para el corrector gramatical.
Ahora bien, volviendo al tema del Component Body, la clase debe cumplir con las
características que había explicado antes, y debe además hacer uso del trait ComLib
(Component Library).
Hay algo que necesito aclarar, vi en varias ocasiones, y hasta yo al principio lo hacía así, que la
gente programa las clases pensando en por ejemplo listar todos los registros de la tabla
usuarios, por lo que crean una clase usuarios y crean funciones tales como, obtener usuarios,
editar usuario, etc. En donde utilizan la clase como un medio para acceder a los registros de
una tabla, es un error fatal, en realidad una clase representa a un objeto, el objeto tiene
atributos, y funciones, la clase lo que hace es definir las características de dicho objeto, sin
darle valores particulares, de modo que luego, al instanciar dicha clase, se creen los valores
particulares de un objeto, usar la clase para manipular varias cosas a la vez, es un error, la
clase debe estar diseñada para luego instanciarse y crear un objeto, no un objeto que
represente a muchos. Por lo que es imperativo que utilicen las clases con el fin para las que
fueron creadas, y cuando diseñen un componente creen las clases pensando en que
representan a varios objetos, pero que en realidad cuando se instancie, lo que se cree será un
Introducción PCM y PCMB 2013
7 Redactado por Alexander Eberle Renzulli para Underc0de.org Puede visitar mi blog en console-input-output.blogspot.com
objeto por instancia, y no 300 registros por instancia. (Además de que obviamente en este
modelo no se puede utilizar base de datos dentro de un componente salvo de que el
componente sea específicamente para manipulación de base de datos, pero era para dar un
ejemplo).
A la hora de crear el componente, se crea la parte Component Body, y se incluye el
Component Library, que dependiendo del framework o código base que utilicen puede estar
cargado ya, por lo que es necesario comprobar que haya sido cargado para no cargarlo más de
una vez (verificando la existencia de la constante COM_LIB_LOAD). Luego hay que tener en
cuenta que hay que incluir las extensiones que utilice dicho componente, lo único que no debe
incluirse es la interface, el Component Library System, carga el Component Interface, el
Component Body y dependiendo del desarrollador del Component Library System, también
carga el Component Library, pero en ningún caso carga las extensiones.
Si se desea borrar una función de un componente, es necesario dejar la declaración de la
función, pero en su definición es necesario dejar simplemente un ; para que quede explícita la
eliminación de dicha función. Y en el constructor del componente llamar al notificador de
eliminación del Component Library (una función diseñada para avisar al Component Library
System que la función fue eliminada), si dicha función no está declarada, el Component Library
System registrará la nueva versión y notará la falta de dicha función y no cargará el
componente por incompatibilidad, luego tirará un Fatal Error notificando que el componente x
es incompatible, que por favor vuelva a la versión x del componente o hable con el
desarrollador.
Si se desea cambiar el nombre a una función, debe dejarse la función vieja como alias de la
primera llamando a la función del Component Library notificador de alias quien simplemente
registrará el alias y llamará a la función nueva.
Aunque también es válido directamente llamar a la nueva función.
Quiero aclarar, que los notificadores son funciones del Component Library, que son accesibles
una vez que se especifica que la clase usa el trait Component Library.
Si se desea modificar una función, agregando parámetros, es necesario que sean opcionales,
pero únicamente si solo se desean agregar nuevos parámetros.
Por el contrario si se desea modificar los parámetros cambiándolos de lugar o quitando alguno,
es necesario hacer un bridge (puente), para evitar que los sistemas viejos sigan llamando
erráticamente a las funciones con parámetros viejos.
El puente consiste en llamar desde la función vieja a la función nueva con nuevos parámetros,
ordenando los parámetros viejos como deberían estar en la función nueva.
También es necesario que si un cambio de este tipo ocurre se les notifique a los usuarios del
complemento para que tomen las medidas necesarias para que su antiguo sistema acepte o
pueda utilizar las nuevas características, de lo contrario utilizará únicamente características
anteriores.
Introducción PCM y PCMB 2013
8 Redactado por Alexander Eberle Renzulli para Underc0de.org Puede visitar mi blog en console-input-output.blogspot.com
Si se aplican las medidas previamente explicadas, se puede cumplir con la característica de
compatibilidad absoluta a lo largo de versiones.
Es necesario también que cada función contenga en las primeras líneas un control de tipo de
dato, y fuerce cada tipo al que se espera recibir (incluido string) por ejemplo $numero1 = (int)
$numero1;
Además que si una función requiere por obligación la previa llamada de otra, se realice la
llamada dentro de la función, o se compruebe si ya fue llamada,
Éstas dos medidas colaboran con la característica de máxima robustez posible, no obstante no
es lo único que se debe implementar, por lo que dejo a decisión del desarrollador que tome las
medidas que crea pertinentes.
Además los componentes deben responder a Encapsulación y Ocultamiento de información.
El component body NO debe tener comentarios que expliquen lo que cada función hace, lo
que una línea hace, o lo que en general hace la clase, es mejor si no tiene directamente ningún
tipo de comentario, las razones serán explicadas en el apartado de Component Interface.
Y por último y no menos importante el Component Body debe cumplir los requisitos del
Component Library, dichos requisitos serán explicados en la parte del paper que hable
específicamente de Component Library.
Component Interface Una de las cosas que son necesarias para que el modelo de componentes funcione
correctamente es necesario que un componente tenga comentarios adecuados, pero esto no
significa que se llene el código con una explicación línea por línea de lo que se hace, no solo no
es necesario, sino que además no tiene sentido alguno, la idea de los componentes es que
sean fáciles de usar, simplemente se carguen, y se consulte la interface para obtener un
resumen de las funcionalidades y el detalle sobre lo que cada parámetro exige, además del
tipo de dato esperado.
La interface cumple la función de datasheet de un componente de electrónica por ejemplo,
que especifica que hace cada función, que entradas se esperan, y que salida se obtendrá, por
lo que es necesario que todas las funciones públicas sean declaradas en esa sección, y sean
explicadas con comentarios. Pero que los usuarios sepan que funciones hay y qué hacen no
significa que tenga que explicarles a los que usen sus componentes como el componente hace
lo que hace, de hecho eso resulta negativo, si utiliza la creación de componentes como
actividad comercial.
El archivo Component Interface debe tener de nombre el nombre del componente, pero de
prefijo la palabra Interface, quedando por ejemplo “InterfaceCorrector.php” y dentro debe
tener la estructura Interface de php (véase la documentación de php con respecto al
constructor Interface), que de nombre debe tener también el prefijo interface, por ejemplo:
Introducción PCM y PCMB 2013
9 Redactado por Alexander Eberle Renzulli para Underc0de.org Puede visitar mi blog en console-input-output.blogspot.com
interface InterfaceCorrector
{
}
La clase del Component Body debe implementar dicha interface, no obstante, las extensiones
deben tener las interfaces dentro de cada extensión.
El único momento donde se permite omitir la implementación de una interface aunque debe
estar hecha, es cuando el Component Body está compuesto por una clase abstracta, aunque
esté desaconcejado el uso de clases abstractas en el component body, se puede hacer, y en las
extensiones se puede hacer con tranquilidad.
La interface debe tener primero las funciones getters y setters para que el usuario pueda
conocer los atributos, y debe comentarse si son accesibles o no. Si se usa el Trait Property
debe explicarse en comentarios que se hace uso del Trait Property y no es necesario utilizar las
funciones getters y setters, que se puede utilizar el atributo directamente.
Luego deben estar las funciones públicas (incluido el constructor) especificando con
comentarios, que hace la función, que datos y tipos se espera en cada parámetro, y que dato y
tipo se retornará de la función.
Antes de la declaración de la interface se debe escribir un comentario explicando cual es el
objetivo del componente.
RECUERDE: en la interface es el único lugar del componente donde deberían haber
comentarios, ya que la idea es que la persona que use el componente no tenga que abrir nada
más que la interface para conocer su funcionamiento.
Component Library
Es la sección del componente encargada de comunicarse con el mecanismo de control de
componentes (Component Library System) para asegurar la validez y evitar comprometer a un
sistema, si el componente es alterado, incompatible, o puede llegar a generar errores.
El ComLib debe ser un trait, que se encuentre en el archivo ComLib.php dentro de la carpeta
del componente, para asegurar su portabilidad e independencia del sistema que lo utilice.
Además si bien en PCM se permite la creación de componentes formados de clases de tipo
abstracta (según la definición de clases abstractas de php), PCMB NO permite que la clase
principal del componente sea abstracta (no obstante clases dentro de archivos de extensión si
son permitidos).
El trait ComLib debe contener un mecanismo para devolver información del componente, que
normalmente se ubica en un archivo com.json dentro de la carpeta del componente, y que
contiene un json con un arreglo asociativo con los siguientes valores:
Introducción PCM y PCMB 2013
10 Redactado por Alexander Eberle Renzulli para Underc0de.org Puede visitar mi blog en console-input-output.blogspot.com
{
“component_version” : “1”,
“component_autor”:”Alexander Eberle”,
“component_contact”:”alexander171294@gmail”,
“php_support_version”:”5.4”,
“comlib_version”:”1”,
“last_update”:”01/11/13”
}
Explicando un poco lo que es cada cosa:
Component_version es la versión del componente, cuando se realiza un cambio se debe
aumentar la versión en +1
Component_autor: es el nombre del autor del componente, si un componente es
implementado y luego en alguna actualización, dicho nombre cambia, el Component Library
System generará un warning error advirtiendo que el autor fue alterado
php_support_version: versión de php en la que fue escrito el componente
comlib_version: versión de component library para la que fue escrito el componente
last_update: última actualización del componente
El trait ComponentLibrary debe proveer una función que devuelva al ComponentLibrarySystem
las funcionalidades que puede realizar dicho componente, para que el component library
system pueda llevar un control de compatibilidad.
Component Library System
Los componentes deben ser controlados, deben ser validados, y se debe llevar un registro de
los componentes que son válidos, para que si cambian, se pueda verificar la compatibilidad.
Component Library System es en términos generales lo que podría ser considerado un
Protocolo de validación y carga de componentes, su objetivo es validar un componente para
no comprometer el sistema, revisando que dicho componente cumpla con las expectativas,
tenga una interfaz, y otras reglas de componentes previamente explicadas.
Si un componente no es válido, el mismo no será cargado, evitando así comprometer todo el
sistema.
En CPMB el Component Library System está conformado por una clase estática.
En primer lugar el Component Library System debe llevar un registro de los componentes
existentes, en PCMB, el Component Library System guarda el registro en el archivo
Components.ini, lo carga una vez inicializado el código, y lo guarda una vez terminada la
ejecución del código, mientras tanto este registro de componentes es cargado en memoria
para un manejo rápido y flexible.
Introducción PCM y PCMB 2013
11 Redactado por Alexander Eberle Renzulli para Underc0de.org Puede visitar mi blog en console-input-output.blogspot.com
Si un componente no está registrado por el ComponentLibrarySystem debe ser registrado
cuando es solicitado por primera vez, controlando la existencia de los archivos que lo
conforman (tales como el Component Body, Component Interface y Component Library),
controlando también que el componente implemente la interface y el component library (no
solo que lo tenga entre los archivos del componente).
Para poder registrar el componente, el CLS (component library system) debe llamar a la
función del ComLib y obtener información sobre el componente, para luego comparar si la
versión del comlib para la que fue creado el componente es la misma que está usando el
sistema.
Luego debe registrar tanto la información como la lista de funciones que actualmente puede
realizar el componente.
Si el componente ya está registrado, debe obviarse el paso anterior, y comenzar con las
validaciones, donde se valida obligatoriamente:
- Que los archivos estén
- La versión del component lib sea válida
- Si el que utiliza dicho componente especificó que la versión tiene que ser una en
específico (la versión del componente), se tiene que validar que dicha versión sea
correcta.
- Se tiene que validar que datos relevantes como el autor no hayan sido alterados.
- Se tiene que validar que las funciones que tenía anterior mente sigan estando
disponibles para conservar la compatibilidad (para esto debe hacerse la llamada al
comlib del componente que obtiene la lista de funciones del mismo).
Si el componente hasta este punto es válido, se libera el CLS dejando disponible dicho
componente para su uso.
En caso de que un componente no tenga una función, pero el que hace uso del componente y
desarrolló el sistema, ya preparó el sistema para que soporte las nuevas características y deje
de usar características viejas, lo único que debe hacer es vaciar el components.ini obligando así
a que el CLS vuelva a registrar todos los componentes que hayan sido actualizados.
ESTO SOLO DEBE HACERSE SI SE AJUSTÓ EL CÓDIGO PARA QUE FUNCIONE SIN LAS FUNCIONES
QUE FUERON QUITADAS.
Uso correcto de componentes
Quizás a usted no le interese en realidad conocer en detalle, o de forma introductoria el
funcionamiento de PCM y solo desea crear un componente, por lo tanto, dedicaré éste
apartado a detallar la creación de un componente válido.
En primer lugar tiene que entender que hay ciertas reglas que ustede debe conocer y se
detallan en la parte de “Componentes” de éste pdf, en especial la introducción a componentes
y la sección Component Body.
Introducción PCM y PCMB 2013
12 Redactado por Alexander Eberle Renzulli para Underc0de.org Puede visitar mi blog en console-input-output.blogspot.com
Podemos definir a un componente como un bloque de código, que tiene características tales
como, individualidad (con esto me refiero a que, el componente puede ser tanto ejecutado,
como desarrollado, actualizado y evolucionado, de forma individual, sin el requerimiento de
cualquier código que lo implemente), esto es parte de la idea de “Separar la implementación
de la especificación”, es de carácter crucial, que se desarrolle y prueba el componente fuera de
cualquier sistema antes de implementarlo en uno, para asegurar su funcionamiento individual.
Los componentes están divididos en partes que ya expliqué, y deben tener un cuerpo principal,
o una clase que represente al componente en sí, el componente también debe tener una
interface y un archivo de información, (además de una librería que por ejemplo PCMBasic ya
incluye).
Lo primero que vamos a hacer a la hora de crear un componente es pensar un nombre sin
espacios y sin caracteres especiales, solo letras y números, empezando con una letra.
Por ejemplo MensajesPrivados, a partir de ahora tomaremos este como el ejemplo para crear
un componente.
Yo como soy el creador de PCMB obviamente que lo voy a usar, por lo que voy a copiar y pegar
renombrando la carpeta example, dentro de models/components (ubicación por defecto de
los componentes en PCMB) para ya tener todos los archivos de ejemplo, y no tener que estar
creándolo uno por uno.
Primeramente voy a editar (o crear) el archivo com.js que contiene la información de mi
componente, cada vez que quiera hacer una edición al mismo debo actualizar este archivo.
Voy a citar un capítulo anterior donde explicaba éste archivo:
{
“component_version” : “1”,
“component_autor”:”Alexander Eberle”,
“component_contact”:”alexander171294@gmail”,
“php_support_version”:”5.4”,
“comlib_version”:”1”,
“last_update”:”01/11/13”
}
Explicando un poco lo que es cada cosa:
Component_version es la versión del componente, cuando se realiza un cambio se debe
aumentar la versión en +1
Component_autor: es el nombre del autor del componente, si un componente es
implementado y luego en alguna actualización, dicho nombre cambia, el Component Library
System generará un warning error advirtiendo que el autor fue alterado
php_support_version: versión de php en la que fue escrito el componente
comlib_version: versión de component library para la que fue escrito el componente
last_update: última actualización del componente
Introducción PCM y PCMB 2013
13 Redactado por Alexander Eberle Renzulli para Underc0de.org Puede visitar mi blog en console-input-output.blogspot.com
Una vez que tenemos el archivo de información de nuestro componente pasamos a crear
nuestra clase principal del componente, para lo cual creamos o editamos si ya lo tenemos el
archivo ComponentExample.php (ahora será llamado ComponentMensajesPrivados.php)
Primero que nada se incluye si no se realizó hasta el momento, el comlib, para lo cual
verificamos la existencia de la constante COM_LIB_LOAD.
Luego pasamos a requerir cualquier extra que necesitemos (recuérdese que los extras
únicamente pueden ser partes del componente, que deceamos tener en archivos externos, ya
sean clases abstractas, o lo que fuere).
Y ahora si construimos nuestra clase, que hará uso del trait comlib.
Recuerde que la clase debe llamarse ComponentNOMBRECOMPONENTE, en nuestro ejemplo
ComponentMensajesPrivados.php.
Recuerde también que si se requiere hacer uso del método constructor sus parámetros deben
ser opcionales.
Recuerde también que no se debe hacer uso directo de bases de datos en componentes salvo
que dicho componente sea una simplificación de un controlador de bases de datos, por
ejemplo si usted quiere simplificar el uso de pdo y crear un componente que se llame
PDOSIMPLE donde haga las conexiones y simplifique la sintaxis de pdo o la quiera hacer a su
gusto, en ese caso es válido, pero no si usted quiere obtener un registro de un mensaje
privado por ejemplo.
Por otro lado recuerde que en un componente no debe tener dependencias hacia otros
componentes o cualquier cosa externa a dicho componente.
Por ejemplo no debe tener funciones tales como “echo” ya que debe permitírsele al usuario
que utilice el componente, poder especificar la forma en que mostrar los datos.
Una vez que tengas armado el componente que haga todo lo que desees, debes crear la
interface para nuestro ejemplo sería el archivo InterfaceMensajesPrivados.php que
documente cada función, sus parámetros, los tipos, lo que retorna, solo para funciones
públicas.
Puede revisar la sección de este pdf que habla sobre ComponentInterface para una mejor
referencia.
Cuando ya en tu carpeta tienes el ComponentMensajesPrivados.php, el
InterfaceMensajesPrivados.php, el ComLib.php, y el com.json (también puedes tener
ExtensionAutor.php, ExtensionBusqueda.php, etc.) tu componente ya está listo
(Recuerda que debe cumplir con todas las exigencias que se describen a lo largo de éste
documento).-
Introducción PCM y PCMB 2013
14 Redactado por Alexander Eberle Renzulli para Underc0de.org Puede visitar mi blog en console-input-output.blogspot.com
PCMB Introduccio n
PCMB es un mini código diseñado para trabajar como la base minina e indispensable para
comprobar el funcionamiento de PHP Component Model, este código además lo utilizo para
mis proyectos personales (con previas modificaciones a mi gusto), no presenta un código muy
complejo, más bien simple, que está basado en el patrón de diseño de código de PHP MVC,
donde se separa el código en Modelo Vista Controlador, la vista es la parte del código que
tiene el diseño, los modelos son una abstracción de la base de datos, y los controladores son el
nexo entre los modelos y las vistas, pero a esto se le agregó un poco de complejidad en la
sección de modelos, donde se agregó el modelo de componentes, permitiendo cargar
componentes en los modelos.
PCMBasic no pretende ser un código para uso diario, más bien un simple demostrativo para la
implementación de componentes, si uno tiene en cuenta esto, hay que agregar cosas como un
gestor de plantillas para limpiar los diseños web, yo en lo personal construí un componente en
base a RainTPL (el gestor de plantillas).-
Por otra parte un gestor de base de datos (diseñé un componente propio que actúa como
gestor de base de datos).
Entre otras cosas, ambos componentes los agregaré en PCMBasic, para simple demostración,
pero no están incluidos en documentación ni se da soporte para estas partes del sistema.
Además también se incluyó un archivo .htaccess para simplificar el manejo de urls, (comentaré
un poco más de su estructura en la sección de este pdf que habla sobre PCMB Otros detalles)
Para finalizar, quiero solicitarle al lector que utilice el código para la función que fue
desarrollado y no para otras cosas, ya que a diario veo a usuarios, utilizar códigos para cosas
para las que no fueron diseñados, y cuando no funcionan correctamente le echan la culpa del
mal funcionamiento al autor del código.
PCMB Controladores
En esta sección del pdf trataré de explicar de la forma más sencilla el funcionamiento de los
controladores y la forma en la que fueron diseñados…
Para empezar les comentaré que los controladores están conformados por clases, que son
instanciadas y llamadas las funciones de forma automática basada en la configuración de links,
que se encuentran en el archivo permitidos.json, donde se crea un arreglo de controladores y
sus funciones internas que son permitidas, notese que el archivo está escrito bajo la normativa
de JSON, puede buscar en google la documentación respectiva.
Las acciones son el primer texto que luego se le asigna un arreglo compuesto por la función
que está permitida.
Introducción PCM y PCMB 2013
15 Redactado por Alexander Eberle Renzulli para Underc0de.org Puede visitar mi blog en console-input-output.blogspot.com
Es necesario que los controladores extiendan la clase controller, y hagan uso del trait
Singleton, como en el de ejemplo.
También es obligatorio que se escriba la función init(); que hace de constructor, se llama de la
misma forma pero no admite parámetros, en el caso de que se le cambie la visibilidad (de
public a private por ejemplo) o se la declare de diferente forma, se logrará un error, de la
misma forma que si se agregan parámetros no opcionales.
Lo mismo ocurre con el resto de las funciones, aunque si se admite la creación de funciones
privadas para uso interno, aunque las mismas no podrán ser accedidas por url, aunque se
agreguen al archivo permitidos.json
Por último, si no se especifica que controlador cargar, se cargará el home, y si no se especifica
una función se cargará la función main (que deben estar ambos en el archivo permitidos.json).
En los controladores se puede escribir la función load_model(nombre); para cargar un modelo
específico y luego utilzarlo.
Las clases de los controladores no deben ser abstractas y no deben tener funciones estáticas.
PCMB Vistas
Las vistas pueden ser creadas y cargadas a gusto, PCMBasic no incluye ningún tipo de gestión
para las mismas, no obstante a modo demostración se agrega un componente basado en
RainTPL (puede encontrar la documentación o elegir no utilizarlo borrando la carpeta e
incorporando otro).
PCMB Modelos
Los modelos tienen que ser creados como clases estáticas, no hay razón alguna para crear un
modelo e instanciarlo, (entiéndase que los objetos deben ser creados en base a los
componentes, armados y devueltos para que los controladores hagan uso de los mismos), y
deben proveer de gestión de base de datos.
En realidad no hay más restricciones para los modelos, pero los mismos fueron diseñados para
hacer de plataforma entre los componentes, por ejemplo si se quiere mostrar una lista de
usuarios, donde hay un componente usuarios, y se tiene que instanciar la clase de dicho
componente para cada uno de los usuarios, se llamaría a la función del modelo que gestiona
los usuarios para obtener un arreglo con todas las instancias de cada usuario (es a modo de
ejemplo para que pueda entender la idea para la que fue diseñado, y esa también es la razón
por la que debería ser estática, no es requerido instanciarla y no se debería hacer).
PCMB otros detalles
Introducción PCM y PCMB 2013
16 Redactado por Alexander Eberle Renzulli para Underc0de.org Puede visitar mi blog en console-input-output.blogspot.com
Para finalizar quiero darle a entender al usuario detalles de PCMB que no tienen que ver con
MVC ni con PCM, por un lado los links pueden ser creados de dos formas, en primera instancia,
se pueden crear sin urls amigables:
Index.php?action=nombrecontrolador&f=funcioncontrolador&id=numerootexto
O de forma amigable:
/nombrecontrolador/funcioncontrolador/id/
Siempre debe terminar en / y ninguna de las 3 partes del link son necesarias.
Puede obtener cada una de ellas así:
$_GET[‘action’]
$_GET[‘f’]
$_GET[‘id’]
Por otro lado PCMB incluye soporte para multiples idiomas de forma nativa, de hecho carga un
archivo de idioma dependiendo del idioma del navegador, los lenguajes pueden ser definidos
en el archivo langs.json
PCMBasic carga el archivo idioma.php que debe encontrarse dentro de la carpeta langs/ y
debe ser escrito como un arreglo y ser devuelto con un return, luego se encuentra en cada
controlador en una variable interna $this->lang.
En el archivo index.php puede configurarse las variables de los links que son utilizadas para
cargar los controladores, por si usted desea crear otro formato de link, el display_errors, si se
desea mostrar errores, el idioma por defecto, etc.