PHP moderno: Parte 1/3

PHP moderno (Parte 1)

PHP fue uno de los lenguajes de programación back-end originales para la web. Desafortunadamente, no es el mejor lenguaje de propósito general y las versiones originales carecían de las sutilezas organizativas de los lenguajes de programación modernos.


Como tal, hay muchos sitios web ejecutados con PHP menos que perfectos y muchos de ellos necesitan ser corregidos o mejorados.

¿Quiere empezar a trabajar como freelance? Un vistazo rápido a las listas de trabajos de Upwork y verá PHP como uno de los principales proyectos en los que la gente necesita ayuda. La mayoría de los listados querrán que limpie el desorden de otra persona, algún programador desafortunado haciendo demasiadas noches sin conseguir algo que (apenas) funcione. No es lindo. Pero ahí es donde está el dinero de los freelance. Probablemente haya estado en uno de estos sitios donde las cosas no funcionan como esperaba o carecen del flujo fluido de los sitios web modernos de SPA. Eso es en lo que estarás trabajando.

PHP ahora tiene un administrador de dependencias llamado Composer y voy a usar el marco Symfony. Todo esto requerirá la versión 7 de PHP, lo que podría ser un problema si tiene que trabajar en versiones anteriores de PHP. Pero aprender la nueva forma le facilitará el uso de algunas de las herramientas de piedra de antaño que puede encontrar.

Instalemos las cosas. Primero, si aún no tiene PHP, debería obtenerlo. Como estoy en una Mac, la versión de PHP preinstalada es la 5, por lo que puede usar brew para obtener una instalación de la versión 7. si tiene otro sistema operativo, puede seguir las instrucciones aquí.

A continuación, debe instalar Composer. Encontrará las instrucciones de instalación aquí. Habrá que mover el script que ejecuta Composer para poder acceder a él globalmente con este comando:

php

Ahora debería poder escribir composer en el símbolo del sistema y obtener la lista de ayuda.

Finalmente, debes instalar Symfony. Descárguelo con estas instrucciones y pruébelo:

php

Ahora ejecute Symfony para crear una nueva aplicación web

php

Esto creará un directorio llamado phpapp y colocará su nueva aplicación web en él. También creará un repositorio de git para su nueva aplicación. Deberíamos conectarlo a GitHub para que podamos guardar nuestro estado inicial. En GitHub, cree un repositorio vacío llamado phpapp . Luego, de vuelta en la línea de comando, emita estos comandos:

php

Esa es nuestra línea de base. Pero, ¿qué podemos hacer con él? Póngalo en marcha y veamos:

php

php

Bastante ingenioso para una pantalla 404. De vuelta en la línea de comando, presione Ctrl-C para detener el servidor.

¿Ahora que? Una buena parte del trabajo independiente necesita formularios agregados a una aplicación existente o una nueva aplicación que solo presentaría un formulario. El formulario estaría respaldado por una base de datos y, al estilo de la vieja escuela, esa base de datos probablemente fuera MySQL.

 

Mudarse a la nube

En los viejos tiempos, tendrías la pila LAMP; Linux, Apache, MySQL y PHP. Voy a ponerme un poco moderno en ti y a DNMP, que no es un acrónimo tan bueno, pero funcionará en un mundo moderno en contenedores. Usaremos Docker, Nginx, MariaDB y PHP. Note que dije usar y no instalar. El beneficio es que lo único que necesita instalar en una máquina virtual en la nube es Docker y un archivo docker-compose.yml. Todo se carga a partir de imágenes prediseñadas. Puede usar Docker desde Mac para probarlo, pero si no; lo puede descargar aquí.

Entonces aquí es donde se vuelve un poco extraño. PHP no fue escrito para ser contenedor. Espera una máquina virtual con todo tipo de accesorios instalados y disponibles y tenemos que codificar esa instalación. Algunas de estas cosas son para construir y otras para correr, y la distinción entre los dos es borrosa. En los viejos tiempos, solo se construía en la misma máquina en la que se ejecutaba, así que no importaba. Ahora queremos contenedores delgados que solo tengan lo necesario para su ejecución, y el proceso de compilación tiene lugar mientras construimos el contenedor. Normalmente, usaríamos compilaciones de varias etapas en Docker.

Sin embargo, vamos a crear una imagen amplia con solo incluir todo lo que instalamos anteriormente. Vamos a crear un archivo llamado Dockerfile y en él agregamos todas las instrucciones de instalación que acabamos de seguir. Podemos comenzar con PHP 7.3 como imagen base, luego instalar Composer y finalmente instalar Symfony. Esto es lo que ocurrió:

php

Esto de ninguna manera está optimizado. Pero, de nuevo, cuando trabaja para alguien que solo quiere un formulario para su base de datos en la nube, lo simple gana siempre.

Ahora para que esta cosa esté construida y funcionando. Aquí tienes todo lo que necesitas:

php

¡Ahora puede abrir su navegador a http://localhost/ y listo! Debería ver la página que tenía antes. Tenga en cuenta que no tuvimos que usar el puerto 8000 porque lo asignamos a 80. En el futuro, dejaremos que Nginx lea el puerto 80 y lo reenvíe a nuestra aplicación que ejecuta 8000. Ctrl-C para detener el servidor.

Debo mencionar que esta puede no ser la forma óptima de hacerlo. Tanto Apache como Nginx tienen complementos que se comunicarán con un backend PHP de manera más eficiente. Pero nuevamente, simple es el camino a seguir en la mayoría de los casos. Si alguien quiere soluciones escalables y eficientes, no buscará Upwork, y esa es la razón por la que estoy aprendiendo este idioma anticuado en primer lugar. La gente de Upwork quiere un nuevo formulario para que coincida con una nueva tabla en la base de datos y lo quieren mañana. Olvídese de la elegancia y hágalo hoy mismo.

 

Implementar en la nube

Antes de pasar a la base de datos, hay un truco más que podemos realizar, ya que está en contenedores. Movamos esto a la nube. Resulta que tengo una cuenta con Google Cloud Platform, un nombre de dominio y una cuenta de CloudFlare. Consigamos esto en Internet real. Si no tiene esas tres cosas y no desea configurarlas, puede omitir esta sección. Esto también debería funcionar con la mayoría de los otros servicios en la nube que ofrecen VM desnudas con imágenes estándar de Linux. Para empezar, enviemos la imagen que creamos a DockerHub para que nuestra computadora en la nube pueda encontrarla

php

En su panel de GCP, vaya a la página de instancias de Compute Engine / VM y agregue una nueva VM. Use la VM más pequeña que tengan, generalmente micro-algo. Por ejemplo, una imagen base de Ubuntu 20.04 con 10 Gigabytes de disco duro y acceso HTTP abierto. Después de instalarlo, debería ver algo como esto en su lista de VM.

Image for post

Haga clic en el botón SSH para abrir una ventana a la VM. Tendrá que instalar Docker, iniciar sesión en Docker y ejecutar el mismo comando que usó antes

php

Debería verlo desplazarse por el registro hasta que diga que está escuchando el puerto 8000.

La segunda dirección IP en la lista de VM es la externa, puede ir a CloudFlare DNS y configurar un registro A con un nombre de host y esa IP. Ahora su aplicación debería estar disponible como http://hostname.yourdomain.com/

Piense en esto: si su VM explota y necesita volver a crear su aplicación, son tres líneas de código para una instalación completa. Tres líneas. Si necesita actualizar la aplicación, es solo una línea. Es incluso más sencillo si utiliza un servicio de orquestación como Kubernetes. Los contenedores harán que tu vida en la nube sea ingrávida.

 

Agregar páginas

Antes de conectar la base de datos, hagamos algunas páginas. Para comenzar, crearemos una página de inicio, una página de información y una página de lista que solo tienen texto simple. Agreguemos algunas dependencias:

php

Estos deberían estar disponibles en su entorno local de inmediato y estarán en la imagen de Docker la próxima vez que lo reconstruya. Esto permitirá crear plantillas, algo de notación de formas básicas, una fácil inclusión de activos como CSS e imágenes, y algunas utilidades y acceso a la base de datos.

Vamos a comenzar con un Bootstrap básico de Twitter, y puedo configurarlo en la plantilla base. Entonces, cualquier cosa que herede de esa plantilla tendrá un diseño estándar y un conjunto de estilos con los que trabajar. Todo esto va en el archivo  templates/base.html.twig.

El bloque div con el content del bloque es donde irá su contenido. Por ejemplo, creemos una página de acerca de simple llamada templates / about.html.twig:

php

Como puede ver, se extiende a base.html.twig y tiene un bloque llamado contenido. Tendrá que agregar nuevas páginas a config / routes.yaml:

php

Y extiende la src/Controller/Home.php:

Como solo estamos agregando texto simple a cada página, home.html.twig y list.html.twig serán copias de about.html.twig con algunos cambios de texto para que sepamos que hemos conectado la página correcta a la ruta URL correcta. Cuando lo juntamos, se ve así:

Image for post

 

Agregar una base de datos

Los sitios web que no son estáticos necesitan algún tipo de tienda de backend. Vamos a utilizar MariaDB. MariaDB se bifurcó de MySQL después de que Oracle adquiriera MySQL, ya que el desarrollador original sintió que Oracle podría tener un conflicto de intereses para mantenerlo. MariaDB todavía es casi completamente compatible con complementos, por lo que debería poder intercambiar uno por otro sin cambios de programación.

Para nuestro desarrollo local, no vamos a instalar MariaDB, vamos a utilizar una imagen de Docker que está disponible públicamente. No vamos a cambiar la imagen de Docker, solo configuraremos un docker-compose.yml que iniciará MariaDB y una aplicación de administración. Así es como se ve:

php

Esto incluye una consola de administración. Tenga en cuenta que se asignó el puerto externo para la consola de administración a 7000 ya que tenemos una instancia de Jenkins ejecutándose en 8080. Tenga en cuenta también que la contraseña es solo para desarrollo, obviamente la leeremos del entorno o en otro lugar cuando la implementemos en cualquier lugar público. Para comenzar a ejecutar este comando:

php

Verá mucho desplazamiento y eventualmente se detendrá. Ahora puede ir a http://localhost:7000/ e iniciar sesión con root / example y dejar la base de datos en blanco por ahora. Deberías ver esto:

Image for post

Puede detener la base de datos y la consola de administración con Ctrl-C y retendrá sus datos la próxima vez que la inicie (los datos existen dentro del contenedor). Pero si baja el contenedor:

php

Perderá los datos. Eso puede ser útil en el desarrollo, pero obviamente es algo que no queremos en producción. No entraremos en cómo resolver ese problema aquí, tal vez en una publicación posterior. Por ahora, tiene una base de datos que puede subir y bajar.

En el archivo .env encontrará la URL de la base de datos. Puedes cambiarlo a:

php

Nuevamente, estamos usando una contraseña solo para desarrollo, esto se anulará en una implementación de producción. También notará que el nombre de host es mariadb. Eso es para que se ejecute dentro de la ventana acoplable cuando queramos probarlo con una ventana acoplable-compose. Para que se ejecute fuera de la ventana acoplable, edito mi archivo / etc / hosts para incluir mariadb como alias de localhost.

Asegurándonos de que su base de datos y la consola de administración aún estén activas, podemos usar una utilidad que se instaló con el paquete orm para crear una base de datos. Obtendrá el nombre de la base de datos de la URL.

Ahora actualice su consola de administración para asegurarse de que esté allí

Image for post

Ahora podemos hacer una clase de entidad con otra utilidad:

Este comando lo guiará por los campos. Vamos a crear los campos winewine_descriptioncheesecheese_description y pairing_notes. Una vez que haya terminado, debería tener un nuevo archivo src/Entity/WinePairing.php. Si observa de cerca, notará que creó un campo de id para usted. También creó  src/Repository/WinePairingRepository.php  que le dará los métodos findAllpersist, que es todo lo que usaremos por ahora. Ahora puede crear la tabla en la base de datos:

Esto creará un script para crear la base de datos. La salida del comando tendrá el siguiente comando, que será algo como esto:

Puede confirmar que la tabla se creó en la consola de administración de MariaDB.

 

Creando páginas CRUD

Solo vamos a hacer una lista y una página para agregar, una vez que la domine, las otras deberían ser relativamente fáciles de entender. Primero la página de lista. Ya tenemos la ruta, solo necesitamos agregar la lista real. Lo siguiente enviará la lista completa al formulario de lista a través de src / Controller / Home.php:

Asegúrese de agregar el use App/Entity/WinePairing para traer la clase. No vamos a abordar la paginación por ahora. Ahora en templates / list.html.twig puedes completarlo:

Observe que agregamos un botón “Add” al final de la lista. Si va a la página de la lista ahora, no verá una lista porque aún no hay datos, pero verá el botón Agregar. Si hace clic en él, obtendrá un error porque la ruta no está definida. Así que agrégalo a su config/routes.yaml:

Entonces puedes definirlo en su  src/Controller/Home.php:

¡Esto es mucho! Pero básicamente va a utilizar el generador de formularios integrado de Symfony. Esta ruta maneja tanto la visualización de formularios como el envío de formularios a través de los verbos GET y POST. El condicional if($form->isSubmitted() && $form->isValid()) hará que los datos del formulario se guarden en la base de datos y luego lo redirigirán de nuevo a la lista. De lo contrario, utilizará el archivo templates/add.html.twig para representar el formulario. Así es como se ve esa plantilla:

La mayor parte de su trabajo se realizó en el controlador. Una última cosa es decirle que use el tema bootstrap. Modifique su config/packages/twig.yaml a esto:

Sus estilos de arranque ya están cargados por su plantilla base. Ahora presione el botón “Add” nuevamente en la pantalla de lista y tendrá su pantalla de agregar

Image for post

Es cierto que es algo feo, pero la mayoría de las veces, cuando se lanza a un proyecto, ya habrá estilos más apropiados configurados para usted. Todo lo que tiene que hacer es copiar y pegar un formulario similar.

Hemos logrado mucho aquí, pero hay más por venir. Necesitamos una forma de configurar esa base de datos en nuestro servidor de GCP. En mi próximo artículo, le mostraré cómo puede ejecutar todos los comandos necesarios en el servidor sin cargar archivos cada vez que necesite realizar cambios. Todo se llevará junto con la imagen que construimos en nuestra computadora de desarrollo; todo lo que tenemos que hacer es enviar al repositorio de imágenes y luego estará disponible en la nube.