Diferencia entre revisiones de «Usuario:ManuelRomero/composer»
De WikiEducator
(→Composer) |
|||
| (19 revisiones intermedias por el mismo usuario no mostrado) | |||
| Línea 1: | Línea 1: | ||
https://medium.com/swlh/composer-everything-i-should-have-known-794225cde691 | https://medium.com/swlh/composer-everything-i-should-have-known-794225cde691 | ||
| + | <div id=parrafo> | ||
| + | {{#widget:Slides}} | ||
| + | <div class="slides layout-regular template-default"> | ||
| + | |||
| + | <div class="slide"> | ||
===La autocarga=== | ===La autocarga=== | ||
*La programación actual es claramente estructurada-modular programando con el paradigma orientado a objetos (existen otros paradigmas) | *La programación actual es claramente estructurada-modular programando con el paradigma orientado a objetos (existen otros paradigmas) | ||
| Línea 5: | Línea 10: | ||
*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 cargar de forma automática las clases ya hemos visto como realizar un autoload de cada clase que necesitemos. | ||
| + | </div> | ||
| + | <div class="slide"> | ||
| + | ;La autocarga | ||
*Para ello escribimos el código en la función anónima que recibe en callback como argumento la función | *Para ello escribimos el código en la función anónima que recibe en callback como argumento la función | ||
'''''spl_autload_register'''''. | '''''spl_autload_register'''''. | ||
| − | + | ||
| + | *En esta situación hemos de saber que las clases las tenemos en el directorio '''''Clases''''' del proyecto | ||
<source lang=php> | <source lang=php> | ||
spl_autoload_register(function ($clase)){ | spl_autoload_register(function ($clase)){ | ||
| Línea 13: | Línea 22: | ||
} | } | ||
</source> | </source> | ||
| − | *Esto también lo podríamos poner | + | </div> |
| + | <div class="slide"> | ||
| + | ;La autocarga | ||
| + | *Esto también lo podríamos poner escribiendo la función nominada | ||
<source lang=php> | <source lang=php> | ||
function autocarga($clase){ | function autocarga($clase){ | ||
require("Clases/$clase.php"); | require("Clases/$clase.php"); | ||
} | } | ||
| − | |||
spl_autoload_register(autocarga); | spl_autoload_register(autocarga); | ||
</source> | </source> | ||
| − | + | </div> | |
| − | *Esto está bien, y | + | <div class="slide"> |
| − | + | ;La autocarga | |
| − | + | *Esto está bien, y previo a utilizar una clase, cargamos previamente el fichero que lo implementa. | |
| + | *Por lo tanto, solo están cargados los ficheros que necesitemos en un momento dado. | ||
| + | *Se pueden verificar 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. | ||
| + | https://www.php.net/manual/es/function.get-include-path.php | ||
| + | </div> | ||
| + | <div class="slide"> | ||
| + | ;La autocarga | ||
| + | |||
| + | *Como vemos, este método presenta el inconveniente de que 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. | ||
| + | *Para ello, de alguna forma habría que añadir un prefijo a cada nombre de fichero de cada clase que identificar la ubicación de directorio | ||
| + | </div><div class="slide"> | ||
===Complicando la estructura del directorio=== | ===Complicando la estructura del directorio=== | ||
| − | * | + | *Vamos a trabajar con una estructura compleja de directorios en un proyecto. |
| − | [[Archivo:estructura_clases_ej2.png| | + | *Supongamos la siguiente estructura de clases en nuestro proyecto como se especifica en la imagen |
| + | [[Archivo:estructura_clases_ej2.png|600px|center]] | ||
| + | </div><div class="slide"> | ||
<br /> | <br /> | ||
| + | ;Estructura de directorios ejemplo | ||
*Este ejemplo implica la siguiente estructura de directorios y las clases correspondientes | *Este ejemplo implica la siguiente estructura de directorios y las clases correspondientes | ||
| − | + | [[Archivo:implementacion_ficheros1.png|180px]] | |
| − | [[Archivo:implementacion_ficheros1.png| | + | </div><div class="slide"> |
| + | ;Estructura de directorios ejemplo | ||
*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 | *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 | ||
<source lang=php> | <source lang=php> | ||
public function __toString() | public function __toString() | ||
{ | { | ||
| − | + | return "<h2>Estoy en la clase | |
| − | return "<h2>Estoy en la clase " . get_class ($this) . " ubicado en " . __DIR__; | + | " . get_class ($this) . |
| + | " ubicado en " . __DIR__; | ||
} | } | ||
</source> | </source> | ||
| − | *La función get_class($obj) retorna el nombre de la la clase de un objeto | + | </div><div class="slide"> |
| + | ;Estructura de directorios ejemplo | ||
| + | *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 | 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 | + | *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 | 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 | ||
| − | + | </div><div class="slide"> | |
| + | |||
| + | ;Estructura de directorios ejemplo | ||
| + | *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. | *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 | + | *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''''' | *Lo hacemos con objetos ubicados en el directorio '''''librerias''''' | ||
| + | </div><div class="slide"> | ||
| + | ;Estructura de directorios ejemplo | ||
| + | |||
<source lang=php> | <source lang=php> | ||
<?php | <?php | ||
| Línea 61: | Línea 95: | ||
echo $a; | echo $a; | ||
echo $b; | echo $b; | ||
| − | echo $c; | + | echo $c; |
</source> | </source> | ||
| + | </div><div class="slide"> | ||
| + | ;Estructura de directorios ejemplo | ||
| + | |||
*Y vemos la siguiente salida | *Y vemos la siguiente salida | ||
[[Archivo:salida_ej_1.png|300px]] | [[Archivo:salida_ej_1.png|300px]] | ||
| + | </div><div class="slide"> | ||
| + | ;Estructura de directorios ejemplo | ||
| + | |||
*Con lo que hemos visto hasta ahora de autocarga estaríamos muy limitados por dos temas: | *Con lo que hemos visto hasta ahora de autocarga estaríamos muy limitados por dos temas: | ||
| − | #Los ficheros diferentes | + | #Los ficheros diferentes están ubicados en distintos directorios |
#Hay clases con el mismo nombre y ubicadas en distinto que realizarán distintas tareas ... | #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 | *Para cubrir estas situaciones surge los namespace, si bien no nos van a facilitar la autocarga para lo cual tendremos composer | ||
| − | + | </div> | |
| + | <div class="slide"> | ||
===Concepto de namespace=== | ===Concepto de namespace=== | ||
| − | |||
;Espacio de nombres | ;Espacio de nombres | ||
* https://diego.com.es/namespaces-en-php | * https://diego.com.es/namespaces-en-php | ||
| Línea 79: | Línea 119: | ||
*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). | *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 | *Es una forma de agrupar clases lo mismo que un directorio agrupa todo su contenido y los permite localizarlo | ||
| + | </div> | ||
| + | <div class="slide"> | ||
| + | ;namespace | ||
*En java podríamos asemejarlo al concepto de package | *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) | *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) | ||
| Línea 85: | Línea 128: | ||
/home/profesor/bd/notas.ods | /home/profesor/bd/notas.ods | ||
</source> | </source> | ||
| + | </div> | ||
| + | <div class="slide"> | ||
| + | ;namespace | ||
| + | |||
{{MRM_Resumen| | {{MRM_Resumen| | ||
;Los espacios de nombres de PHP permiten agrupar | ;Los espacios de nombres de PHP permiten agrupar | ||
clases, funciones, interfaces y constantes relacionadas. | clases, funciones, interfaces y constantes relacionadas. | ||
}} | }} | ||
| + | </div> | ||
| + | <div class="slide"> | ||
;Declarar un namespace | ;Declarar un namespace | ||
*Debe de ser la primera instrucción del fichero (Cuidado incluso con espacios en blanco) | *Debe de ser la primera instrucción del fichero (Cuidado incluso con espacios en blanco) | ||
| Línea 96: | Línea 145: | ||
.. | .. | ||
</source> | </source> | ||
| + | </div> | ||
| + | <div class="slide"> | ||
| + | ;namespace | ||
*El namespace puede tener varios niveles de jerarquía que se establecen (cuidado con la barra de separación '''''\''''') | *El namespace puede tener varios niveles de jerarquía que se establecen (cuidado con la barra de separación '''''\''''') | ||
<source lang=php> | <source lang=php> | ||
| Línea 102: | Línea 154: | ||
... | ... | ||
</source> | </source> | ||
| − | + | </div> | |
| − | * | + | <div class="slide"> |
| − | + | ;Volviendo a nuestro ejemplo | |
| + | *Ahora vamos a establecer un namespace en cada clase | ||
| + | </div> | ||
| + | <div class="slide"> | ||
| + | ;librerias/comunes/a.php | ||
| + | <source lang=php> | ||
| + | <?php | ||
| + | namespace Librerias\Comunes; | ||
| + | class A{ | ||
| + | public function __toString() | ||
| + | { | ||
| + | return "<h2>Estoy en la clase ".get_class($this)." ubicado en ".__DIR__; | ||
| + | } | ||
} | } | ||
| − | + | ?> | |
| − | + | </source> | |
| − | + | </div><div class="slide"> | |
| − | + | ;librerias/comunes/e.php | |
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
<source lang=php> | <source lang=php> | ||
| − | + | <?php | |
| − | + | namespace Librerias\Comunes; | |
| − | + | class E{ | |
| − | + | public function __toString() | |
| − | + | { | |
| + | return "<h2>Estoy en la clase ".get_class($this)." ubicado en ".__DIR__; | ||
} | } | ||
} | } | ||
| − | + | ?> | |
| − | " | + | </source> |
| + | </div><div class="slide"> | ||
| + | ;librerias/privadas/a.php | ||
| + | <source lang=php> | ||
| + | <?php | ||
| + | namespace Librerias\Privadas; | ||
| + | class A{ | ||
| + | public function __toString() | ||
| + | { | ||
| + | return "<h2>Estoy en la clase ".get_class($this)." ubicado en ".__DIR__; | ||
| + | } | ||
} | } | ||
| − | + | ?> | |
| + | </source> | ||
| + | </div><div class="slide"> | ||
| + | ;librerias/privadas/e.php | ||
| + | <source lang=php> | ||
| + | <?php | ||
| + | namespace Librerias\Privadas; | ||
| + | class E{ | ||
| + | public function __toString() | ||
| + | { | ||
| + | return "<h2>Estoy en la clase ".get_class($this)." ubicado en ".__DIR__; | ||
| + | } | ||
| + | } | ||
| + | ?> | ||
| + | </source> | ||
| + | </div><div class="slide"> | ||
| + | ;librerias/a.php | ||
| + | <source lang=php> | ||
| + | <?php | ||
| + | namespace Librerias; | ||
| + | class A{ | ||
| + | public function __toString() | ||
| + | { | ||
| + | return "<h2>Estoy en la clase ".get_class($this)." ubicado en ".__DIR__; | ||
| + | } | ||
| + | } | ||
| + | ?> | ||
| + | </source> | ||
| + | </div><div class="slide"> | ||
| + | ;librerias/b.php | ||
| + | <source lang=php> | ||
| + | <?php | ||
| + | namespace Librerias; | ||
| + | class B{ | ||
| + | public function __toString() | ||
| + | { | ||
| + | return "<h2>Estoy en la clase ".get_class($this)." ubicado en ".__DIR__; | ||
| + | } | ||
| + | } | ||
| + | ?> | ||
| + | </source> | ||
| + | </div><div class="slide"> | ||
| + | ;librerias/c.php | ||
| + | <source lang=php> | ||
| + | <?php | ||
| + | namespace Librerias; | ||
| + | class C{ | ||
| + | public function __toString() | ||
| + | { | ||
| + | return "<h2>Estoy en la clase ".get_class($this)." ubicado en ".__DIR__; | ||
| + | } | ||
| + | } | ||
| + | ?> | ||
| + | </source> | ||
| + | </div><div class="slide"> | ||
| + | ;controlador/comunes/ca.php | ||
| + | <source lang=php> | ||
| + | <?php | ||
| + | namespace Controlador\Comunes; | ||
| + | class CA{ | ||
| + | public function __toString() | ||
| + | { | ||
| + | return "<h2>Estoy en la clase ".get_class($this)." ubicado en ".__DIR__; | ||
| + | } | ||
| + | } | ||
| + | ?> | ||
| + | </source> | ||
| + | </div><div class="slide"> | ||
| + | ;controlador/comunes/cd.php | ||
| + | <source lang=php> | ||
| + | <?php | ||
| + | namespace Controlador\Comunes; | ||
| + | class CD{ | ||
| + | public function __toString() | ||
| + | { | ||
| + | return "<h2>Estoy en la clase ".get_class($this)." ubicado en ".__DIR__; | ||
| + | } | ||
| + | } | ||
| + | ?> | ||
| + | </source> | ||
| + | </div><div class="slide"> | ||
| + | ;controlador/c.php | ||
| + | <source lang=php> | ||
| + | <?php | ||
| + | namespace Controlador; | ||
| + | class C{ | ||
| + | public function __toString() | ||
| + | { | ||
| + | return "<h2>Estoy en la clase ".get_class($this)." ubicado en ".__DIR__; | ||
| + | } | ||
| + | } | ||
| + | ?> | ||
| + | </source> | ||
| + | </div> | ||
| + | <div class="slide"> | ||
| + | ;controlador/ca.php | ||
| + | <source lang=php> | ||
| + | <?php | ||
| + | namespace Controlador; | ||
| + | class CA{ | ||
| + | public function __toString() | ||
| + | { | ||
| + | return "<h2>Estoy en la clase ".get_class($this)." ubicado en ".__DIR__; | ||
| + | } | ||
| + | } | ||
| + | ?> | ||
| + | </source> | ||
| + | </div> | ||
| + | <div class=slide> | ||
| + | ;controlador/cb.php | ||
| + | <source lang=php> | ||
| + | <?php | ||
| + | namespace Controlador; | ||
| + | class CB{ | ||
| + | public function __toString() | ||
| + | { | ||
| + | return "<h2>Estoy en la clase ".get_class($this)." ubicado en ".__DIR__; | ||
| + | } | ||
| + | } | ||
| + | ?> | ||
| + | </source> | ||
| + | </div> | ||
| + | <div class="slide"> | ||
| + | ;Index.php | ||
| + | <source lang=php> | ||
| + | //Primero cargaremos todos los ficheros | ||
| + | <?php | ||
| + | require "./librerias/A.php"; | ||
| + | require "./librerias/B.php"; | ||
| + | require "./librerias/C.php"; | ||
| + | require "./librerias/comunes/A.php"; | ||
| + | require "./librerias/comunes/E.php"; | ||
| + | require "./librerias/privadas/A.php"; | ||
| + | require "./librerias/privadas/E.php"; | ||
| + | require "./controlador/comunes/CA.php"; | ||
| + | require "./controlador/comunes/CD.php"; | ||
| + | require "./controlador/C.php"; | ||
| + | require "./controlador/CA.php"; | ||
| + | require "./controlador/CB.php"; | ||
| + | ?> | ||
| + | </source> | ||
| + | </div><div class="slide"> | ||
| + | ;Index.php | ||
| + | <source lang=php> | ||
| + | //Ahora instanciamos los objetos | ||
| + | $a = new \Librerias\A(); | ||
| + | $b = new \Librerias\B(); | ||
| + | $c = new \Librerias\C(); | ||
| + | $a_comun = new \Librerias\Comunes\A(); | ||
| + | $e_comun = new \Librerias\Comunes\E(); | ||
| + | $a_p = new mi_A(); | ||
| + | $e_p = new \Librerias\Privadas\E(); | ||
| + | $c_c=new \Controlador\C(); | ||
| + | $c_a=new \Controlador\CA(); | ||
| + | $c_b=new \Controlador\CB(); | ||
| + | $c_a_comun=new \Controlador\Comunes\CA(); | ||
| + | $c_b_comun=new \Controlador\Comunes\CD(); | ||
| + | </source> | ||
| + | </div><div class="slide"> | ||
| + | ;Index.php | ||
| + | <source lang=php> | ||
| + | //Y procedemos a visualizarlos | ||
| + | echo $a; | ||
| + | echo $b; | ||
| + | echo $c; | ||
| + | echo $a_comun; | ||
| + | echo $e_comun; | ||
| + | echo $a_p; | ||
| + | echo $e_p; | ||
| + | echo $c_c; | ||
| + | echo $c_a; | ||
| + | echo $c_b; | ||
| + | echo $c_a_comun; | ||
| + | echo $c_b_comun; | ||
| + | </source> | ||
| + | </div> | ||
| + | <div class="slide"> | ||
| + | ;Empleo de use | ||
| + | *Vemos como hemos conseguido solventar el tema de clases con el mismo nombre | ||
| + | *Podemos evitar tener que referenciar toda la estructura de namespace al instanciar una clase | ||
| + | *Para ello usaremos la palabra reservada '''''use''''' | ||
| + | https://www.php.net/manual/es/language.namespaces.importing.php | ||
| + | </div> | ||
| + | <div class="slide"> | ||
| + | ;Empleo de use | ||
| + | *En el ejemplo anterior | ||
| + | <source lang=php> | ||
| + | <?php | ||
| + | require "./librerias/A.php"; | ||
| + | //.... | ||
| + | use Librerias\Comunes\A; | ||
| + | $a = new A(); | ||
</source> | </source> | ||
</div> | </div> | ||
| + | <div class="slide"> | ||
| + | ;Empleo de use | ||
| + | *También podríamos cambiar crear un alias | ||
| + | <source lang=php> | ||
| + | <?php | ||
| + | require "./librerias/A.php"; | ||
| + | //.... | ||
| + | use Librerias\Comunes\A as mi_A; | ||
| − | = | + | $a = new mi_A(); |
| − | + | ?> | |
| − | < | + | </source> |
| + | </div> | ||
| − | = | + | <div class="slide"> |
| − | + | {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 | ||
| + | </div> | ||
| + | <div class=slide> | ||
| + | ===Composer=== | ||
| + | *Ahora vamos a ver cómo composer puede solucionar la autocarga | ||
| + | *El objetivo será delegar en composer la carga de los ficheros que contienen las clases | ||
| + | *Vamos a ver dos técnicas, aunque hay más | ||
| + | ;classmap | ||
| + | ;psr-4 | ||
| + | </div> | ||
| + | ;composer | ||
| + | <br /> | ||
{{MRM_Previos| | {{MRM_Previos| | ||
*Tener instalado composer. | *Tener instalado composer. | ||
| + | *Visitar la página de composer | ||
| + | *Es muy fácil de instalar | ||
| + | {{MRM_Web| | ||
| + | https://getcomposer.org/ | ||
}} | }} | ||
| + | }} | ||
| + | </div> | ||
| + | |||
===composer.json=== | ===composer.json=== | ||
| + | *Para especifivar la autocarga, usaremos el | ||
===Ubicar las clases en nuestro proyecto=== | ===Ubicar las clases en nuestro proyecto=== | ||
===El namespace=== | ===El namespace=== | ||
| Línea 157: | Línea 440: | ||
===Actualizar/Instalar composer en nuestro proyecto=== | ===Actualizar/Instalar composer en nuestro proyecto=== | ||
===Usando las clases en nuestro proyecto=== | ===Usando las clases en nuestro proyecto=== | ||
| + | </div> | ||
| + | {{MRM_Web|Title=referencias| | ||
| + | https://getcomposer.org/doc/04-schema.md#psr-4 | ||
| + | https://www.php-fig.org/psr/psr-4/ | ||
| + | https://thewebtier.com/php/what-are-namespaces-in-php/ | ||
| + | https://thewebtier.com/php/psr4-autoloading-php-files-using-composer/ | ||
| + | }} | ||
| + | |||
| + | </div > | ||
Última revisión de 16:10 14 abr 2021
https://medium.com/swlh/composer-everything-i-should-have-known-794225cde691
composer.json
- Para especifivar la autocarga, usaremos el
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.
Actualizar/Instalar composer en nuestro proyecto
Usando las clases en nuestro proyecto
</div >