Ya llevamos bastante tiempo hablando sobre PHP, sobre como hacer TDD con PHP, como refactorizar clientes en PHP,… en definitiva, intentando entender todos los entresijos del lenguaje y mejorando poco a poco nuestros conocimientos.
En este pequeño artículo vamos a comprender un poco más acerca del estándar PSR-4 de como estructurar un paquete para que sea compatible y así hacer que nuestro código sea más reusable.
La estructura de directorios
La primera cosa que debemos tener en cuenta es que es necesario tener un orden (más o menos lógico) en nuestra estructura de directorios dentro de nuestro paquete de ejemplo: Gazpacho
Así que lo primero es crear un directorio llamado gazpacho
, y dentro de éste, dos directorios: uno llamado src
y otro llamado test
.
Todo el código de nuestro «paquete» estará dentro de la carpeta src
y todos los tests que necesitemos estarán dentro del directorio tests
.
El siguiente paso es crear el repositorio de git con git init
. Así al final tendremos algo como esto:
JesusLC@ ~/Documents/Desarrollo $ mkdir gazpacho
JesusLC@ ~/Documents/Desarrollo $ cd gazpacho/
JesusLC@ ~/Documents/Desarrollo/gazpacho $ mkdir tests
JesusLC@ ~/Documents/Desarrollo/gazpacho $ mkdir src
JesusLC@ ~/Documents/Desarrollo/gazpacho $ git init
Initialized empty Git repository in /Users/JesusLC/Documents/Desarrollo/gazpacho/.git/
JesusLC@ ~/Documents/Desarrollo/gazpacho $
Composer
Composer es una herramienta que nos permite gestionar paquetes y dependencias dentro de nuestro proyecto. Anteriormente ya hemos hablado de Composer en como sacarle partido a composer.
Dentro del directorio gazpacho
creamos un archivo llamado composer.json
, más o menos el archivo tiene que contener esta información:
{
"name": "jeslopcru/gazpacho",
"description": "I like gazpacho soup,",
"license": "MIT",
"keywords": ["gazpacho"],
"authors": [
{
"name": "Jesús LC",
"email": "jeslopcru@gmail.com",
"homepage": "http://jesuslc.com"
}
],
"require": {},
"require-dev": {
"phpunit/phpunit": "4.0.*"
},
"autoload": {
"psr-4": {
"JesLopCru\\Gazpacho\\": "src"
}
}
}
Dentro del archivo composer.json
definimos todos los metadatos de nuestro paquete. Como vemos en él especificamos el nombre, la descripción la licencias,…
Las 3 partes más importantes del archivo son require
, require-dev
y autoload
.
require
: es donde especificamos las dependencias de nuestra librería.require-dev
: es donde especificamos las librerías que nos ayudan a desarrollar, en nuestro caso PHPUnit para los tests.autoload
: indicamos como se hará el autoload. Composer puede gestionar como «autocargar» nuestros ficheros, solo necesitamos especificarle como queremos hacerlo. En este caso le estamos indicando que vamos a utilizarPSR-4
.
Una vez que tengamos todo esto solo tenemos que ejecutar
composer install
Este comando nos creará un directorio llamado vendor
en el que se incluyen todas las dependencias del proyecto.
Archivos especiales
Ahora que ya tenemos nuestras dependencias descargadas en el proyecto podemos empezar a desarrollar nuestro paquete.
Sin embargo, cuando nosotros colgamos el paquete para que pueda ser utilizado, lo mejor es no tener las dependencias dentro, ya que de eso se encarga composer y además si todas las librerías colgasen la carpeta vendor dentro de sus repositorios tendríamos muchísimo código duplicado.
Así que lo que vamos a hacer es crear nuestro archivo .gitignore
e incluir en el la carpeta vendor
.
Si vamos a utilizar GitHub podemos aprovecharnos de muchas ventajas, aparte de tener el código bajo control de versiones, como por ejemplo TravisCI. Travis es un SaaS que proporciona servicios de integración continua que ejecutarán nuestros tests. Esta funcionalidad es genial, porque si recibimos algún pull-request podremos pasar tests en diferentes versiones de PHP de una manera sencilla.
Para integrar travis en nuestro paquete creamos un archivo llamado .travis.yml
con el siguiente contenido:
language: php
php:
- 5.4
- 5.5
- 5.6
- hhvm
before_script:
- composer self-update
- composer install --prefer-source --no-interaction --dev
script: phpunit
Con esta configuración estamos indicándole a Travis que vamos a utilizar PHP, que es necesario ejecutar los tests en una serie de versiones de PHP, que antes de ejecutar los tests es necesario actualizar composer e instalar las dependencias y que cuando todo eso esté hecho para lanzar los tests solo tiene que ejecutar phpunit.
Nuestros tests
Antes de empezar a escribir código es comenzar escribiendo los tests, o al menos dejarlo todo listo para allanar el camino. PHPUnit requiere un archivo de configuración llamado phpunit.xml
este archivo lo crearemos en la raíz del proyecto y tendrá todo lo siguiente:
<?xml version="1.0" encoding="UTF-8"?>
<phpunit backupGlobals="false"
backupStaticAttributes="false"
bootstrap="vendor/autoload.php"
colors="true"
convertErrorsToExceptions="true"
convertNoticesToExceptions="true"
convertWarningsToExceptions="true"
processIsolation="false"
stopOnFailure="false"
syntaxCheck="false">
<testsuites>
<testsuite name="Gazpacho Test Suite">
<directory suffix=".php">./tests/</directory>
</testsuite>
</testsuites>
</phpunit>
No tenemos que preocuparnos demasiado por este archivo, básicamente definimos donde están los tests y poco más.
Lo siguiente es crear nuestro primer test, que nos servirá para saber si todo está correcto. Para ello creamos un archivo llamado GazpachoTest.php
dentro de la carpeta de tests
:
<?php
use JesLopCru\Gazpacho\Gazpacho;
class GazpachoTest extends PHPUnit_Framework_TestCase
{
public function testNothing()
{
$this->assertTrue(true);
}
}
Ahora solo tenemos que ejecutar los test así:
JesusLC@ ~/Documents/Desarrollo/gazpacho $ vendor/bin/phpunit
PHPUnit leerá la configuración automáticamente y nos dirá que todo está OK. Si no es así, debemos revisarlo. Para crear test solo tenemos que crear métodos que empiecen por testXX dentro de clases que terminen por la palabra Test, las clases deben extender siempre de PHPUnit_Framework_TestCase
.
Escribiendo código
Dentro de la carpeta src
podemos escribir nuestro código, empezaremos por un fichero llamado Gazpacho.php
en el que escribiremos:
<?php
namespace JesLopCru\Gazpacho;
class Gazpacho
{
public function hasTomatoes($bool = true)
{
return $bool;
}
}
Como podemos observar todo el código está dentro de la carpeta src
y con el namespaces definimos el nombre.
Ahora vamos a escribir algún test para nuestro código.
<?php
use JesLopCru\Gazpacho\NacGazpachoho;
class GazpachoTest extends PHPUnit_Framework_TestCase
{
public function testNothing()
{
$this->assertTrue(true);
}
public function testGazpachoHasTomatoes()
{
$gazpacho = new Gazpacho();
$this->assertTrue($gazpacho->hasTomatoes());
}
}
Composer, junto con toda la configuración que hemos realizado se encargará de instanciar todas las clases y crear todo lo necesario para que al ejecutar vendot/bin/phpunit
nuestro test pasen en verde.
Documentación
Por último solo nos queda crear el archivo readme.md
con la documentación. Este archivo es el que podemos ver por defecto en GitHub, así que es bueno describir que hace nuestras librerías y como funciona.
Si queremos podemos incluir la licencia, en nuestro caso hemos elegido MIT
Pusheando el código a Github
Ahora ya podemos dar por finalizada nuestra librería en PSR-4, solo nos queda dejarla disponible en GitHub y Packagist,
Para poder ‘pushear’ el código en github primero tenemos que crear un nuevo repositorio
git remote add origin git@github.com:jeslopcru/gazpacho.git
git push -u origin master
Para integrarnos con Travis debemos autenticarnos con nuestra cuenta de GitHub.
Conclusiones
En este post hemos visto como desarrollar paso a paso una librería siguiendo el estándar PSR-4. Como podemos ver la estructura de una librería/paquete en PHP es realmente simple y siguiendo el estándar hace que sea mucho más simple.
Utilizar autoload con Composer es algo que al principio puede parecer costoso, pero que una vez superados los primeros inconvenientes, no podrás vivir sin él.
Este tutorial esta basado en: http://culttt.com/2014/05/07/create-psr-4-php-package/
Enhorabuena.
Me ha parecido muy bien explicado y desde luego a tener en cuenta para cualquier desarrollo a día de hoy. Solo indicarte que en authors, la clave «site» debería ser «homepage», si no, composer se queja.
Me gustaMe gusta
Muchas gracias por leerme 🙂
Ya he modificado lo de authors 😉
Me gustaMe gusta