Introducción PCM y PCMB
2013
Si se aplican las medidas previamente explicadas, se puede cumplir con la característica de compatibilidad 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 O cultamiento 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 mo delo 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” “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:
8 Redactado por Alexander Eberle Renzulli para Underc0de.org Puede visitar mi blog en console-input-output.blogspot.com
Introducción PCM y PCMB
2013
interface InterfaceCorrector InterfaceCorrector { }
La clase del Component Body debe implementar dicha interface, i nterface, no obstante, las extensiones deben tener las interfaces dentro de cada extensión. El único momento donde se permite omitir omiti r la implementación de una interface aunque debe estar hecha, es cuando el Component Body está compuesto por una clase abstracta, aunqu e 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 ( 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, i ncompatible, 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 c lases 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 ( 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:
9 Redactado por Alexander Eberle Renzulli para Underc0de.org Puede visitar mi blog en console-input-output.blogspot.com
Introducción PCM y PCMB
2013
{ “component_version” “component_version” : “1”, “component_autor”:”Alexa “component_autor”:”Alexander nder 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 Lib rary System 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 r eglas 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.
10 Redactado por Alexander Eberle Renzulli para Underc0de.org Puede visitar mi blog en console-input-output.blogspot.com
Introducción PCM y PCMB
2013
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 co nocer y se detallan en la parte de “Componentes” de éste pdf, en especial la introducción i ntroducción a componentes componentes
y la sección Component Body.
11 Redactado por Alexander Eberle Renzulli para Underc0de.org Puede visitar mi blog en console-input-output.blogspot.com
Introducción PCM y PCMB
2013
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 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 c uerpo 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 c rear 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” “component_version” : “1”, “component_autor”:”Alexa “component_autor”:”Alexander nder 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
12 Redactado por Alexander Eberle Renzulli para Underc0de.org Puede visitar mi blog en console-input-output.blogspot.com
Introducción PCM y PCMB
2013
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 c onstante COM_LIB_LOAD. Luego pasamos a requerir cualquier extra extr a que necesitemos (recuérdese que los extras únicamente pueden ser partes del componente, que deceamos tener en archivos ex ternos, 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, 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 ar chivo InterfaceMensajesPrivados.php que documente cada función, sus parámetros, los tipos, ti pos, 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 car peta tienes el ComponentMensajesPrivados.php, el InterfaceMensajesPrivados.php, 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).-
13 Redactado por Alexander Eberle Renzulli para Underc0de.org Puede visitar mi blog en console-input-output.blogspot.com
Introducción PCM y PCMB
2013
PCMB Introduccion 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 par a 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é ag regaré 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.
14 Redactado por Alexander Eberle Renzulli para Underc0de.org Puede visitar mi blog en console-input-output.blogspot.com
Introducción PCM y PCMB
2013
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 l a misma forma pero no admite parámetros, en el caso de que se le l e 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 contro ladores 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 co ntroladores 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 15 Redactado por Alexander Eberle Renzulli para Underc0de.org Puede visitar mi blog en console-input-output.blogspot.com
Introducción PCM y PCMB
2013
Para finalizar quiero darle a entender al usuario detalles de PCMB P CMB 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.
16 Redactado por Alexander Eberle Renzulli para Underc0de.org Puede visitar mi blog en console-input-output.blogspot.com
Introducción PCM y PCMB
2013
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 po r 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 c on 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
2 Redactado por Alexander Eberle Renzulli para Underc0de.org Puede visitar mi blog en console-input-output.blogspot.com
Introducción PCM y PCMB
2013
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 c uando 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 c ada 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 m e 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, hac iendo, 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 ucho 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 t odas las situaciones, a mí me llevó unos meses poder llegar a ésta idea, i dea, 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 l os 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.
3 Redactado por Alexander Eberle Renzulli para Underc0de.org Puede visitar mi blog en console-input-output.blogspot.com
Introducción PCM y PCMB
2013
Componentes Como expliqué en la introducción, PCM P CM 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. c omponente. 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.
4 Redactado por Alexander Eberle Renzulli para Underc0de.org Puede visitar mi blog en console-input-output.blogspot.com
Introducción PCM y PCMB
2013
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 c ual 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 g enerar 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 ll ame 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.
5 Redactado por Alexander Eberle Renzulli para Underc0de.org Puede visitar mi blog en console-input-output.blogspot.com
Introducción PCM y PCMB
2013
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 l as 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 o rientada a objetos) que represente al componente, y que incluya las funciones públicas, privadas, los lo s 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 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 c rean 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 com ponente creen las clases pensando en que representan a varios objetos, pero que en realidad cuando se instancie, lo que se cree será un
6 Redactado por Alexander Eberle Renzulli para Underc0de.org Puede visitar mi blog en console-input-output.blogspot.com
Introducción PCM y PCMB
2013
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 c argarlo 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 ag regar 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 lo s sistemas viejos sigan llamando erráticamente a las funciones con parámetros par ámetros viejos. El puente consiste en llamar desde la l a 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 c ambio 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.
7 Redactado por Alexander Eberle Renzulli para Underc0de.org Puede visitar mi blog en console-input-output.blogspot.com
Introducción PCM y PCMB
2013
Si se aplican las medidas previamente explicadas, se puede cumplir con la característica de compatibilidad 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 O cultamiento 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 mo delo 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” “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:
8 Redactado por Alexander Eberle Renzulli para Underc0de.org Puede visitar mi blog en console-input-output.blogspot.com
Introducción PCM y PCMB
2013
interface InterfaceCorrector InterfaceCorrector { }
La clase del Component Body debe implementar dicha interface, i nterface, no obstante, las extensiones deben tener las interfaces dentro de cada extensión. El único momento donde se permite omitir omiti r la implementación de una interface aunque debe estar hecha, es cuando el Component Body está compuesto por una clase abstracta, aunqu e 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 ( 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, i ncompatible, 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 c lases 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 ( 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:
9 Redactado por Alexander Eberle Renzulli para Underc0de.org Puede visitar mi blog en console-input-output.blogspot.com