Diferencia entre revisiones de «Usuario:ManuelRomero/composer»

De WikiEducator
Saltar a: navegación, buscar
(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'''''.
Suponiendo que las clases las tenemos en el directorio '''''Classes''''' del proyecto
+
 
 +
*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 escrbiendo la función nominada
+
</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 hace que sólo estén cargados los ficheros que necesitemos en un momento dado
+
<div class="slide">
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.
+
;La autocarga
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.
+
*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===
*Para  este tema, supongamos la siguiente estructura de clases en nuestro proyecto
+
*Vamos a trabajar con una estructura compleja de directorios en un proyecto.
[[Archivo:estructura_clases_ej2.png|400px]]
+
*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|center]]
+
</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()
 
     {
 
     {
        // TODO: Implement __toString() method.
+
         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
Ahora para poder acceder a cada clase, necesitaríamos tener previamente cargado el fichero que contiene la implementación de la clase
+
</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 estan ubicados en distintos directorios
+
#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===
====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>
{MRM_Resumen|Title=Algunos comentarios|
+
</div>
*Cada namespace referencia a una ubicación en un directorio
+
<div class="slide">
*No tiene por qué coincidir el namespace con el nombre de directorio, Suele coincidir, pero no hay ningún tipo de dependencia
+
;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__;
 +
    }
 
}
 
}
*Una vez establecido un namespace en una clase, para acceder a él debemos de referenciarlo en su ubicación
+
?>
 
+
</source>
*Podemos crear un alias con la palabra reservada Use
+
</div><div class="slide">
 
+
;librerias/comunes/e.php
 
+
 
+
*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>
 
<source lang=php>
{
+
<?php
"autoload":{
+
namespace Librerias\Comunes;
     "psr-4":{
+
class E{
        "Nombre_Espacio\\":"Dir_donde_están_las_clases"
+
     public function __toString()
      }
+
    {      
 +
        return "<h2>Estoy en la clase ".get_class($this)." ubicado en ".__DIR__;
 
     }
 
     }
 
}
 
}
 
+
?>
"psr-4"
+
</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;
  
===Autocarga con composer===
+
$a = new mi_A();
====clasmap====
+
?>
<br />
+
</source>
 +
</div>
  
====psr-4====
+
<div class="slide">
<br />
+
{MRM_Resumen|Title=Algunos comentarios|
 
+
*Cada namespace referencia a una ubicación en un directorio
{{MRM_Web|Title=referencias|
+
*No tiene por qué coincidir el namespace con el nombre de directorio, Suele coincidir, pero no hay ningún tipo de dependencia
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/
+
}}
+
 
+
===psr-4, composer y php===
+
{{MRM_Objetivo|Title=autoload con composer|
+
''En este apartado vamos a exponer como realizar la carga de forma automática de clases en nuestro proyecto '''php'''''¡¡
+
 
}}
 
}}
 +
*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 04:10 15 abr 2021

https://medium.com/swlh/composer-everything-i-should-have-known-794225cde691

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.
La autocarga
  • Para ello escribimos el código en la función anónima que recibe en callback como argumento la función

spl_autload_register.

  • En esta situación hemos de saber que las clases las tenemos en el directorio Clases del proyecto
spl_autoload_register(function ($clase)){
  require("Clases/$clase.php");
}
La autocarga
  • Esto también lo podríamos poner escribiendo la función nominada
function autocarga($clase){
  require("Clases/$clase.php");
}
spl_autoload_register(autocarga);
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
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

Complicando la estructura del directorio

  • Vamos a trabajar con una estructura compleja de directorios en un proyecto.
  • Supongamos la siguiente estructura de clases en nuestro proyecto como se especifica en la imagen
Estructura clases ej2.png


Estructura de directorios ejemplo
  • Este ejemplo implica la siguiente estructura de directorios y las clases correspondientes

Implementacion ficheros1.png

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
    public function __toString()
    {
        return "<h2>Estoy en la clase 
               " . get_class ($this) .
               " ubicado en " . __DIR__;
    }
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
  • 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
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.
  • 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
Estructura de directorios ejemplo
<?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;
Estructura de directorios ejemplo
  • Y vemos la siguiente salida

Salida ej 1.png

Estructura de directorios ejemplo
  • Con lo que hemos visto hasta ahora de autocarga estaríamos muy limitados por dos temas:
  1. Los ficheros diferentes están ubicados en distintos directorios
  2. 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

Espacio de nombres
namespace
  • 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
namespace



Icon summary.gif
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)
<?php
namespace MiProyecto;
..
namespace
  • El namespace puede tener varios niveles de jerarquía que se establecen (cuidado con la barra de separación \)
<?php
namespace MiProyecto\nivel1\subnivel2;
...
Volviendo a nuestro ejemplo
  • Ahora vamos a establecer un namespace en cada clase
librerias/comunes/a.php
<?php
namespace Librerias\Comunes;
class A{
    public function __toString()
    {        
        return "<h2>Estoy en la clase ".get_class($this)." ubicado en ".__DIR__;
    }
}
?>
librerias/comunes/e.php
<?php
namespace Librerias\Comunes;
class E{
    public function __toString()
    {        
        return "<h2>Estoy en la clase ".get_class($this)." ubicado en ".__DIR__;
    }
}
?>
librerias/privadas/a.php
<?php
namespace Librerias\Privadas;
class A{
    public function __toString()
    {        
        return "<h2>Estoy en la clase ".get_class($this)." ubicado en ".__DIR__;
    }
}
?>
librerias/privadas/e.php
<?php
namespace Librerias\Privadas;
class E{
    public function __toString()
    {        
        return "<h2>Estoy en la clase ".get_class($this)." ubicado en ".__DIR__;
    }
}
?>
librerias/a.php
<?php
namespace Librerias;
class A{
    public function __toString()
    {        
        return "<h2>Estoy en la clase ".get_class($this)." ubicado en ".__DIR__;
    }
}
?>
librerias/b.php
<?php
namespace Librerias;
class B{
    public function __toString()
    {        
        return "<h2>Estoy en la clase ".get_class($this)." ubicado en ".__DIR__;
    }
}
?>
librerias/c.php
<?php
namespace Librerias;
class C{
    public function __toString()
    {        
        return "<h2>Estoy en la clase ".get_class($this)." ubicado en ".__DIR__;
    }
}
?>
controlador/comunes/ca.php
<?php
namespace Controlador\Comunes;
class CA{
    public function __toString()
    {        
        return "<h2>Estoy en la clase ".get_class($this)." ubicado en ".__DIR__;
    }
}
?>
controlador/comunes/cd.php
<?php
namespace Controlador\Comunes;
class CD{
    public function __toString()
    {        
        return "<h2>Estoy en la clase ".get_class($this)." ubicado en ".__DIR__;
    }
}
?>
controlador/c.php
<?php
namespace Controlador;
class C{
    public function __toString()
    {        
        return "<h2>Estoy en la clase ".get_class($this)." ubicado en ".__DIR__;
    }
}
?>
controlador/ca.php
<?php
namespace Controlador;
class CA{
    public function __toString()
    {        
        return "<h2>Estoy en la clase ".get_class($this)." ubicado en ".__DIR__;
    }
}
?>
controlador/cb.php
<?php
namespace Controlador;
class CB{
    public function __toString()
    {        
        return "<h2>Estoy en la clase ".get_class($this)." ubicado en ".__DIR__;
    }
}
?>
Index.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";
?>
Index.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();
Index.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;
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
Empleo de use
  • En el ejemplo anterior
<?php
require "./librerias/A.php";
//....
use Librerias\Comunes\A;
$a = new A();
Empleo de use
  • También podríamos cambiar crear un alias
<?php
require "./librerias/A.php";
//....
use Librerias\Comunes\A as mi_A;
 
$a = new mi_A();
?>

{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

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
composer


Plantilla:MRM Previos

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 >