Diferencia entre revisiones de «Usuario:ManuelRomero/composer»
| Línea 4: | Línea 4: | ||
*PHP es un lenguaje para programar orientado a objetos | *PHP es un lenguaje para programar orientado a objetos | ||
*Las buenas prácticas de programación nos llevan a crear diferentes objetos estructurados en distintas carpetas implementadas en ficheros independientes. | *Las buenas prácticas de programación nos llevan a crear diferentes objetos estructurados en distintas carpetas implementadas en ficheros independientes. | ||
| + | *Para cargar de forma automática las clases ya hemos visto como realizar un autoload de cada clase que necesitemos. | ||
| + | *Para ello escribimos el código en la función anónima que recibe en callback como argumento la función | ||
| + | '''''spl_autload_register'''''. | ||
| + | Suponiendo que las clases las tenemos en el directorio '''''Classes''''' del proyecto | ||
| + | <source lang=php> | ||
| + | spl_autoload_register(function ($clase)){ | ||
| + | require("Clases/$clase.php"); | ||
| + | } | ||
| + | </source> | ||
| + | *Esto también lo podríamos poner escrbiendo la función nominada | ||
| + | <source lang=php> | ||
| + | function autocarga($clase){ | ||
| + | require("Clases/$clase.php"); | ||
| + | } | ||
| + | |||
| + | spl_autoload_register(autocarga); | ||
| + | </source> | ||
| + | |||
| + | |||
| + | *Esto está bien, y hace que sólo estén cargados los ficheros que necesitemos en un momento dado | ||
| + | Puedes comprobar los ficheros cargados en un momento dado invocando a la función '''''get_included_files()''''' que te devuelve un array con todos los ficheros cargados. | ||
| + | Este método presenta el inconveniente que o bien tienes todas las clases implementadas en un mismo directorio, o bien en la función de autocarga busca en directorios según el nombre de la clase, lo cual puede ser muy incómodo y poco productivo. | ||
| + | |||
| + | ===Complicando la estructura del directorio=== | ||
*Para este tema, supongamos la siguiente estructura de clases en nuestro proyecto | *Para este tema, supongamos la siguiente estructura de clases en nuestro proyecto | ||
[[Archivo:estructura_clases_ej2.png|400px]] | [[Archivo:estructura_clases_ej2.png|400px]] | ||
| Línea 23: | Línea 47: | ||
https://www.php.net/manual/es/language.constants.predefined.php | https://www.php.net/manual/es/language.constants.predefined.php | ||
*El objetivo es instanciar un objeto de cada clase y probarlo | *El objetivo es instanciar un objeto de cada clase y probarlo | ||
| − | *Lo hacemos con objetos ubicados en | + | Ahora para poder acceder a cada clase, necesitaríamos tener previamente cargado el fichero que contiene la implementación de la clase |
| + | *Con la función que conocemos de autoload, no podemos hacer de esta forma, podríamos hacer que cada clase tuviera un prenombre que identificara su ubicación y dentro de esta función analizáramos dicho prenombre para localizar el fichero que implementa la clase. | ||
| + | *De momento para probarlo e identificar nuevos problemas a solucionar, hacemos una carga literal de cada fichero | ||
| + | *Lo hacemos con objetos ubicados en el directorio '''''librerias''''' | ||
<source lang=php> | <source lang=php> | ||
<?php | <?php | ||
| Línea 45: | Línea 72: | ||
| − | ===Concepto de namespace | + | ===Concepto de namespace=== |
| + | ====namespace==== | ||
| + | ;Espacio de nombres | ||
| + | * https://diego.com.es/namespaces-en-php | ||
| + | * https://www.php.net/manual/es/language.namespaces.php | ||
| + | *El espacio de nombres o <span style=color:#A04000>namespace </span> es una forma de organizar las clases mejorando la estructura del proyecto y evitando conflictos (permitir dos clases diferentes con el mismo nombre). | ||
| + | *Es una forma de agrupar clases lo mismo que un directorio agrupa todo su contenido y los permite localizarlo | ||
| + | *En java podríamos asemejarlo al concepto de package | ||
| + | *En un sistema operativo tenemos un concepto muy parecido con los directorios, de esta forma no tendremos ningún problema en tener dos ficheros con el mismo nombre (en diferente directorio) | ||
| + | <source lang=php> | ||
| + | /home/profesor/dwes/notas.ods | ||
| + | /home/profesor/bd/notas.ods | ||
| + | </source> | ||
| + | {{MRM_Resumen| | ||
| + | ;Los espacios de nombres de PHP permiten agrupar | ||
| + | clases, funciones, interfaces y constantes relacionadas. | ||
| + | }} | ||
| + | ;Declarar un namespace | ||
| + | *Debe de ser la primera instrucción del fichero (Cuidado incluso con espacios en blanco) | ||
| + | <source lang=php> | ||
| + | <?php | ||
| + | namespace MiProyecto; | ||
| + | .. | ||
| + | </source> | ||
| + | *El namespace puede tener varios niveles de jerarquía que se establecen (cuidado con la barra de separación '''''\''''') | ||
| + | <source lang=php> | ||
| + | <?php | ||
| + | namespace MiProyecto\nivel1\subnivel2; | ||
| + | ... | ||
| + | </source> | ||
| + | {MRM_Resumen|Title=Algunos comentarios| | ||
| + | *Cada namespace referencia a una ubicación en un directorio | ||
| + | *No tiene por qué coincidir el namespace con el nombre de directorio, Suele coincidir, pero no hay ningún tipo de dependencia | ||
| + | } | ||
| + | *Una vez establecido un namespace en una clase, para acceder a él debemos de referenciarlo en su ubicación | ||
| + | |||
| + | *Podemos crear un alias con la palabra reservada Use | ||
| + | |||
| + | |||
| + | |||
| + | *Con ella no vamos a tener que regenerar el composer cada vez que añadamos una clase | ||
| + | *Añadimos en composer.json | ||
| + | <source lang=php> | ||
| + | { | ||
| + | "autoload":{ | ||
| + | "psr-4":{ | ||
| + | "Nombre_Espacio\\":"Dir_donde_están_las_clases" | ||
| + | } | ||
| + | } | ||
| + | } | ||
| + | |||
| + | "psr-4" | ||
| + | } | ||
| + | |||
| + | </source> | ||
| + | </div> | ||
| + | |||
===Autocarga con composer=== | ===Autocarga con composer=== | ||
Revisión de 16:06 29 abr 2020
https://medium.com/swlh/composer-everything-i-should-have-known-794225cde691
Contenido
La autocarga
- La programación actual es claramente estructurada-modular programando con el paradigma orientado a objetos (existen otros paradigmas)
- PHP es un lenguaje para programar orientado a objetos
- Las buenas prácticas de programación nos llevan a crear diferentes objetos estructurados en distintas carpetas implementadas en ficheros independientes.
- Para cargar de forma automática las clases ya hemos visto como realizar un autoload de cada clase que necesitemos.
- Para ello escribimos el código en la función anónima que recibe en callback como argumento la función
spl_autload_register. Suponiendo que las clases las tenemos en el directorio Classes del proyecto
spl_autoload_register(function ($clase)){ require("Clases/$clase.php"); }
- Esto también lo podríamos poner escrbiendo la función nominada
function autocarga($clase){ require("Clases/$clase.php"); } spl_autoload_register(autocarga);
- Esto está bien, y hace que sólo estén cargados los ficheros que necesitemos en un momento dado
Puedes comprobar los ficheros cargados en un momento dado invocando a la función get_included_files() que te devuelve un array con todos los ficheros cargados. Este método presenta el inconveniente que o bien tienes todas las clases implementadas en un mismo directorio, o bien en la función de autocarga busca en directorios según el nombre de la clase, lo cual puede ser muy incómodo y poco productivo.
Complicando la estructura del directorio
- Para este tema, supongamos la siguiente estructura de clases en nuestro proyecto
- Este ejemplo implica la siguiente estructura de directorios y las clases correspondientes
- En cada fichero vamos a escribir el método mágico __toString() para que nos diga el nombre de la clase y el directorio en el que nos encontramos
public function __toString() { // TODO: Implement __toString() method. return "<h2>Estoy en la clase " . get_class ($this) . " ubicado en " . __DIR__; }
- La función get_class($obj) retorna el nombre de la la clase de un objeto
https://www.php.net/manual/es/function.get-class.php
- La constante __DIR__ da el nombre del directorio dónde se ubica el fichero que invocamos
https://www.php.net/manual/es/language.constants.predefined.php
- El objetivo es instanciar un objeto de cada clase y probarlo
Ahora para poder acceder a cada clase, necesitaríamos tener previamente cargado el fichero que contiene la implementación de la clase
- Con la función que conocemos de autoload, no podemos hacer de esta forma, podríamos hacer que cada clase tuviera un prenombre que identificara su ubicación y dentro de esta función analizáramos dicho prenombre para localizar el fichero que implementa la clase.
- De momento para probarlo e identificar nuevos problemas a solucionar, hacemos una carga literal de cada fichero
- Lo hacemos con objetos ubicados en el directorio librerias
<?php require "./librerias/A.php"; require "./librerias/B.php"; require "./librerias/C.php"; $a = new A(); $b = new B(); $c = new C(); echo $a; echo $b; echo $c;>
- Y vemos la siguiente salida
- Con lo que hemos visto hasta ahora de autocarga estaríamos muy limitados por dos temas:
- Los ficheros diferentes estan ubicados en distintos directorios
- Hay clases con el mismo nombre y ubicadas en distinto que realizarán distintas tareas ...
- Para cubrir estas situaciones surge los namespace, si bien no nos van a facilitar la autocarga para lo cual tendremos composer
Concepto de namespace
namespace
- Espacio de nombres
- https://diego.com.es/namespaces-en-php
- https://www.php.net/manual/es/language.namespaces.php
- El espacio de nombres o namespace es una forma de organizar las clases mejorando la estructura del proyecto y evitando conflictos (permitir dos clases diferentes con el mismo nombre).
- Es una forma de agrupar clases lo mismo que un directorio agrupa todo su contenido y los permite localizarlo
- En java podríamos asemejarlo al concepto de package
- En un sistema operativo tenemos un concepto muy parecido con los directorios, de esta forma no tendremos ningún problema en tener dos ficheros con el mismo nombre (en diferente directorio)
/home/profesor/dwes/notas.ods /home/profesor/bd/notas.ods
clases, funciones, interfaces y constantes relacionadas. |
- Declarar un namespace
- Debe de ser la primera instrucción del fichero (Cuidado incluso con espacios en blanco)
<?php namespace MiProyecto; ..
- El namespace puede tener varios niveles de jerarquía que se establecen (cuidado con la barra de separación \)
<?php namespace MiProyecto\nivel1\subnivel2; ...
{MRM_Resumen|Title=Algunos comentarios|
- Cada namespace referencia a una ubicación en un directorio
- No tiene por qué coincidir el namespace con el nombre de directorio, Suele coincidir, pero no hay ningún tipo de dependencia
}
- Una vez establecido un namespace en una clase, para acceder a él debemos de referenciarlo en su ubicación
- Podemos crear un alias con la palabra reservada Use
- Con ella no vamos a tener que regenerar el composer cada vez que añadamos una clase
- Añadimos en composer.json
{ "autoload":{ "psr-4":{ "Nombre_Espacio\\":"Dir_donde_están_las_clases" } } } "psr-4" }
</div>
Autocarga con composer
clasmap
psr-4
psr-4, composer y php
|
En este apartado vamos a exponer como realizar la carga de forma automática de clases en nuestro proyecto php¡¡ |
composer.json
Ubicar las clases en nuestro proyecto
El namespace
- Los espacios de nombres realmente ayudan a organizar su código y a evitar conflictos de nombres dentro de la base de código de su proyecto.
