Bitácora: Desarrollo de un framework ligero para PHP

  • Autor Autor DanielDiaz
  • Fecha de inicio Fecha de inicio

DanielDiaz

Delta
Diseñador
Verificación en dos pasos activada
Buenas compañeros. Como normalmente se hacen bitácoras de muchos temas, pero rara vez se toca asuntos de programación (porque imagino que ya es tedioso tener que estar trabajando, que también redactando 😅), pensé para los interesados, ir escribiendo mi procedimiento de trabajo en un framework en PHP que estoy realizando para algunos de mis proyectos y para liberarlo cuando esté testado.

Así que, ¿me sigues a lo largo de esta aventura?

Otro Framework PHP, ¿para qué?​

Pues siendo sincero, si me pidieras consejo sobre si usar un framework que lleve ya años en el mercado y con una comunidad desarrollando y corrigiendo errores (sobre todo de seguridad), o si usar un framework que solo lleva una persona, la recomendación sería obvia. Por mucho esfuerzo y consideración que tenga con muchos aspectos, siempre podré dejarme algo, o que mi conocimiento no termine de ver bugs que para mí estén ocultos, y esto será mayor en cuanto escale las funcionalidades y tecnología.

PHP es uno de los primeros lenguajes que hemos tocado muchos en el foro, y con el que hemos entrado en el mundo. Al principio sabíamos que era un lenguaje que no era de lo más, pero que era el que mejor nos encajaba para el desarrollo de aplicaciones webs. A día de hoy se sigue actualizando y a cada versión da pasos de gigantes sobre todo en optimización y rendimiento. Yo mismo sigo usándolo para muchos proyectos de clientes, o bueno, directamente en el desarrollo de plugins y themes en wordpress.

Aclaro antes de que me salte mucho hater, que hay más y mejores lenguajes para el desarrollo de aplicaciones webs, aunque esto y en como muchos otros sitios, es también un poco opinión más allá de números. Puedes sacrificar rendimiento a cambio de estilos o patrones arquitectónicos, o seguridad, ... . Sí debo confirmar que el lenguaje que mejor se ha adaptado a muchos de los atributos que busco en el desarollo web esa NodeJS (de hecho mi lenguaje de programación de servidor principal ahora mismo).

En qué momento la idea de crear un nuevo framework​

Para muchos proyectos personales, lo primero de donde tiro es de un proyecto base que me permita escalar a una primera versión utilizable o mvp (minimum viable product). Esto es así porque puedes decidir vender tu idea poco a poco y que el público tenga algo que le gusta y vea crecer, o puedes invertir un tiempo bestial en darle a tu público todo, y que posiblemente te quedes:
  1. Sin ganas a largo plazo ante un proyecto tan grande que te consume poco a poco
  2. Con un proyecto que no puedes respaldar solo
El framework que tengo entre manos busca cubrir esta necesidad principalmente. Instalas el framework, y utilizas módulos ya creados - aka plugins - que te añadan las funcionalidades, rutas, controladores, los accesos a la base de datos... Entonces por ejemplo, si una vez tú o alguien que ya use el framework, desarrolló un módulo de usuarios que le permitió tener login/registro y un rol que tuviera acceso o restricciones a controladores, no tendrás que volver a hacerlo. Si ese módulo tuvo bugs en su momento, se corrige en su respectivo git.

Para hacer un framework que te permita hacer un proyecto rápido y furioso, es importante dar desde atrás mucha funcionalidad incluida para que no tengas que estar constantemente reinventando la rueda y puedas basarte en funcionalidades más probadas y perfeccionadas con el tiempo. Por eso, mi idea básica es reinventar la rueda solo una vez más, para ofrecer lo que ya nos encontramos en otros muchos otros frameworks y que son conceptos o ideas interesantes, pero en un mismo sitio. Por ejemplo, nos encontramos de primeras (puede que + en siguientes versiones):
  • Wordpress
    • Semántica de funciones: Muchos nombres de funciones comparten o se parecen a los que ya se están usando en Wordpress aunque su funcionamiento es diferente (no he comprobado cuánto de diferente)
    • Hooks: Sistema de "ganchos". De definen de manera predeterminada muchos hooks en el framework. Muy útil para extender la funcionalidad del sistema sin tener que modificar directamente los archivos del núcleo del framework.
      • Ya existe la función enqueue_style() --> wp_enqueue_style(). Ésta aprovecha el recurso css que le pasamos por argumento, y la añade a la pila de estilos en su respectivo hook
      • Ya existe la función enqueue_script() --> wp_enqueue_script(). Igual que con enqueue_style, esta funcion mete rutas de scripts dentro de la pila de un hook que se ejecuta en el footer de la web
  • Spring, Django, ExpressJS:
    • Estilo MVC (modelo, vista controlador). Esto es un estilo arquitectónico muy utilizado que invierte rendimiento para favorecer cohesión y división de responsabilidades en el proyecto. Es decir, para cada "modulo" que hagamos, si queremos que guarde información en la base de datos, tendremos que crear el modelo de datos y su lógica con la base de datos queda recogida en un "servicio". Si entramos por ejemplo en la url miproyecto.com/user/add estaríamos buscando una ruta que encontraremos en el Controlador de usuario, que utilizará los servicios y modelos de usuario, y que finalmente renderizará con lógica simple la vista que queremos mostrar.
    • Modelos y esquemas de base de datos. Si alguna vez has programado en estos frameworks, algo que viene muy bien a la hora de agilizar el desarrollo de proyectos, es que no tienes que estar tocando casi nada la base de datos. Esto es porque definimos modelos de información que se acogen a un schema de la base de datos, y están sincronizados. Si hacemos un cambio al modelo de datos "Usuario", en el que cambiamos name por first_name, automáticamente el framework lo reconoce y hace las respectivass migraciones en las tablas de la base de datos.
  • Un poco en general
    • SQL Builder: en la mayoría de frameworks se incluyen formas directas de acceder a la base de datos sin que tengas que sanalizar data o crear tú la query.
    • Validator: En vez de validar uno a uno los datos, se generalizan las entradas y se declaran que son de x tipo (cadena, texto largo, contraseña, email...). Para todos estos tipos, se crean validaciones generales. En vez de comprobar que un email tenga sea una cadena superior a 0 caracteres, que tenga formato email con regex, ... , queda esta validación ya declarada y usable.
    • Router: a diferencia de muchos frameworks donde tienes que definir todas las rutas, yo estoy buscando que las rutas queden declaradas en los controladores tal y como hace Spring. De todas maneras, también se pueden declarar rutas manuales para el caso de que existan rutas fuera de módulos
    • AutoInstaller: Cada script que creamos instala las bases de datos y el sistema en general. Me gustaría romper un poco con esto, y que un installer general sea capaz de instalar el proyecto de aplicación web sea el que sea

¿Quieres colaborar?​

Me encantaría una comunidad que llevara éste o proyectos open source. Como sabéis, estamos en años de decadencia del software libre. Muchas empresas cogen directamente códigos libres y los venden, cosa que está cabreando al personal y haciendo que el software deje de mantenerse o pase a ser de propietario.

De momento no he publicado nada del framework, puesto que lo estoy haciendo al mismo tiempo que llevo el proyecto de un cliente. Una vez tenga algo estable, subiré versiones a github. Mientras tanto todo permanecerá sin versión, sino más bien como el conjunto de ideas.


- SQL Builder:


- Hooks:


- Validator:



- Controladores, Servicios, Modelos...
- Bastantes cosas más, a la espera de que avance y publique github y changelog

Changelog​

Versión 0.0.1​

  • Enrutamiento
    • Rutas automáticas en controladores de módulos
    • Ruta raíz en SystemController
    • Enrutamiento manual a través de routes.php
    • Respuestas, Peticiones en métodos HTTP
  • Sistema base y core
    • Modelos
      • DBSchema
      • Script para migraciones automáticas en las tablas de la DB si hay cambios en DBSchema
      • [...] Pendiente de desglose
    • Controladores
      • Controladores de módulos extienden Controller para definir rutas y callbacks
      • Renderizado de templates con variables del controlador y del enrutamiento
      • Redireccionamientos
      • Respuestas http y errores
      • [...] Pendiente de desglose
    • Servicios
      • Servicios de módulos extienden Service para definir la lógica ejecutada en los controladores
      • Servicios tienen acceso al Repositorio para ejecutar métodos con acceso a la base de datos
      • [...] Pendiente de desglose
    • Repositorios
      • Repositorios extienden Repository para tener acceso al SQLBuilder y a la base de datos
      • CRUDRepository como clase con métodos predeterminados para Creación, Lectura, Actualización y Borrado de cualquier DBSchema
      • [...] Pendiente de desglose
    • Vistas
      • Renderizado de vistas
      • Variables en vistas exportadas en el renderizado
      • [...] Pendiente de desglose
  • Funcionalidad del framework
    • Hooker
      • Definición de hooks por todo el código desde init del core
      • Se pueden enganchar funciones (callbacks) a los hooks
      • Se puede añadir el order de los hooks (predeterminado en 10)
      • Se puede pasar variables o argumentos a los hooks
    • Validator
      • Establecimiento de validación múltiple a través de matrices
      • Pila y devolución de errores de validación
      • Pila y devolución de variables sanalizadas si no hay error
      • Devolución de errores como matriz
      • Devolución de errores como construcción de componente html
      • Tipos automáticos de validación
        • Text o String
        • Email
        • Password
        • Integer o Number
        • Float
          • Detección si el número se pone con coma o punto
      • Restricciones
        • String
          • Length
            • Max
            • Min
          • [...] Pendiente de desglose
        • Integer o Number
          • Size
            • Min
            • Max
          • [...] Pendiente de desglose
        • Email
          • AllowedHosts
          • [...] Pendiente de desglose
        • [...] Pendiente de desglose
      • Sanalización
        • [...] Pendiente de desglose
      • Restricciones múltiples
    • SQLBuilder
      • MYSQL
        • Generación de queries SELECT ...
          • Query simple
          • Offset
          • Limit
          • Joins
          • [...] Pendiente de desglose
        • Generación de queries INSERT ...
          • Query simple
          • [...] Pendiente de desglose
        • Generación de queries UPDATE ...
          • Query simple
        • [...] Pendiente de desglose
      • DBSchema to query
      • [...]Pendiente de desglose
  • Extensibilidad por carpeta src
    • Sustitución de librerías o archivos del core
    • CMS de ejemplo
    • [...] Pendiente de desglose

What's next​

- Funcionalidades de usuario y rol de administrador
  • Sesiones, login, registro, olvidé contraseña, editar mi cuenta...
  • Roles de cliente, administrador y moderador
  • Panel de administrador en el que se importen las opciones de cada módulo
- Generación de formularios y protección csrf
- Formalización de documentación automática. SI eres administrador, la documentación se generará a partir de comentarios dentro del código y se mostrará por páginas dentro del panel.
- Bombardeo de pruebas de seguridad (se buscan hacker éticos que puedan ayudar a analizar errores y fallas de seguridad :=) )
- Renderizado de templates con template engines como PUG u algún otro
- Pruebas de rendimiento y optimización
- Integración con github. Todas las versiones de las extensiones que hagan desarrolladores se llevarán a través de repositorios de github que se podrán buscar desde el panel de adminsitrador del framework
- Copias de seguridad automáticas a google drive
- SQL extendido para otros motores de bases de datos
 
Última edición:
Nice, sigo tema
 
Actualizado con un poco más de detalle. En unas dos semanas se subirá git con un proyecto de ejemplo y un demo para ir teniendo algo que enseñar 🙂

--
Francamente no estoy centrado en la parte de diseño - aún -, pero estresa estar tantas horas programando y viendo todo tan feote. Esta mañana se ha invertido en la parte de controladores y renderizado de vistas, y he dejado algunos estilos base:


 
Última edición:
Interesante proyecto.
El “curro” de un framework es altamente complejo por todo el tema de componentes ha implementar, pero oye si te van a pagar por hacerlo todo de nuevo, bienvenido sea.

Un saludo y suerte con el proyecto 👍
 
Interesante proyecto.
El “curro” de un framework es altamente complejo por todo el tema de componentes ha implementar, pero oye si te van a pagar por hacerlo todo de nuevo, bienvenido sea.

Un saludo y suerte con el proyecto 👍
Empecé esto esta manera por tener tiempo para disfrutarlo (a parte de ser remunerado, claro x)). No me importa tampoco invertirle más tiempo con tal de tener algo que me simplifique mis aplicaciones webs! Gracias por el los ánimos 🙂🙂🙂
 
Que buenisimo, me gusta los frameworks, mi favorito en JS -> React, en PHP -> Laravel (sé poquito), en HTML/CSS -> Bootstrap 4 sin dudas.

Tener un pequeno framework requiere el maximo esfuerzo y tiempo x los componentes, estilos, etc., debe ser costoso si logras hacer uno, yo hace un tiempo pensaba crear un framework html/css a estilo sordo, pero me di cuenta que requiere harto tiempo.

Mucha suerte con tu framework, sigo el tema.
 
Siempre es interesante intentar este tipo de cosas por profundizar en lo que sabemos. Aunque no salga, nunca es tiempo perdido, a no ser que te quedes en bucle. De momento las vistas se renderizan por petición, pero tengo en mente en alguna versión añadir un proyecto de ejemplo que incluya algún framework en JS (sinceramente tenía pensado vue) y que los componentes se rendericen con endpoints.

Para los estilos base estoy intentando crear un archivo mínimo de css con algunos estilos muy base para grid, botones y algunos otros componentes que integre. Voy actualizando esto, en cuanto tenga algo interesante que subir a git lo tienes para jugar y atreverte a meterle React 🙂
 
Sigo tema, felicidades por tu conocimiento
 
Menudo curro te metes shur.
 
Actualización:
  • Añadida funcionalidad de repositorios y servicios. Ahora un servicio auto-importa su repositorio si existe, y permite acceder a la base de datos mediante un SQL Builder
  • Login, Registro, Creación de sesiones por tokens, cookies
  • Empezando panel de administración
 
Sigo tema!
 
Actualización:
  • Rutas a controlladores, y módulos para CP (control panel)
  • Datatables como componente que muestra automáticamente una tabla con paginación, búsqueda, filtrado...
  • Vistas de actualización y creación de usuarios y entidades en general automáticas a partir de un DBSchema
 
Algunas capturas:

Dashboard de admin



Crear usuario


Me queda poca programación para terminar con el proyecto del cliente. Aún así he dejado muchas cosas atrás que me hubieran gustado añadir. Una vez entregado seguramente lo suba a git y lo trabaje para futuros proyectos.
 
Cómo te va actualmente?
 
Terminé el proyecto del cliente y está muy funcional, no terminé de publicarlo porque por razones de tiempo tuve que hacer algunas decisiones que reducían la personalización del framework. Quizás este año si me lo aceptan como trabajo de tfg en la universidad lo deje publicado. Un saludo y gracias por seguirlo!
Cómo te va actualmente?
 
Algo pasó con tu proyecto compañero? Pues he visto el post recién ahora que busco info sobre PHP. has invitado colaboradores y me quiero unir, pero no veo seguimiento, y quisiera ver el github, si todo sigue en pie quiero sumarme a colaborar.