jairogarcíarincón
Es bastante frecuente, a partir de proyectos de medio tamaño, encontrarnos clases que, aunque estén en distintos directorios, tienen el mismo nombre. Por otra parte, es posible que queramos utilizar librerías de terceros que, es posible, incluyan nombres de clases que ya estamos utilizando.
Por todo ello, necesitamos una manera de identificar cada clase con algo más que su nombre, esto es de encapsularla en nuestro proyecto. para ello, PHP, al igual que muchos otros lenguajes, permite el uso de espacios de nombre o Namespaces, cuya finalidad es precisamente esa: solucionar el conflicto entre nombres de clases, y además proveernos de una forma de abreviar o "apodar" a nuestras clases en un determinado momento para no usar nombres demasiado largos.
Como en apartados anteriores, vamos a ver cómo podríamos adaptar nuestro proyecto a estos dos requisitos:
- A cada clase debemos añadir su namespace correspondiente en la primera línea del script
- A CocheController debemos indicarle que vamos a usar la clase Coche mediante la directiva use seguida del namespace de la clase que queramos usar.
- El archivo raíz index.php llevará el namespace App, tendrá que utilizar la clase CocheController y habrá que modifcar su función autoload para adaptarse al uso de namespaces (básicamente, habrá que quitar los namespaces al hacer la búsqueda de clases dentro de los directorios)
- También habrá que modificar la variable $home del archivo raíz index.php para adaptarla a nuestro ejemplo.
A continuación se detallan las modificaciones realizadas en los archivos.
Añadido al inicio de controller/CocheController.php:
namespace App\Controller;
use App\Model\Coche;
Añadido al inicio de model/Coche.php:
namespace App\Model;
Archivo raíz index.php:
<?php
namespace App;
use App\Controller\CocheController;
//Defino la función que atocargará la clase cuando se instancie
spl_autoload_register('App\autoload');
function autoload($clase,$dir=null){
//Directorio raíz de mi proyecto (ruta absoluta)
if (is_null($dir)){
$dir = realpath(dirname(__FILE__));
}
//Escaneo en busca de clases de forma recursiva
foreach (scandir($dir) as $file){
//Si es un directorio (y no es de sistema) busco la clase dentro de él
if (is_dir($dir."/".$file) AND substr($file, 0, 1) != "."){
autoload($clase, $dir."/".$file);
}
//Si es archivo y el nombre coincide con la clase que quiero instanciar (quitando el namespace)
else if (is_file($dir."/".$file) AND $file == substr(strrchr($clase, "\\"), 1).".php"){
require($dir."/".$file);
}
}
}
//Instancio el controlador
$controller = new CocheController;
//Ruta de la home
$home = "/formacion/poo/ejemplo8/index.php/";
//Quito la home de la ruta de la barra de direcciones
$ruta = str_replace($home, "", $_SERVER["REQUEST_URI"]);
//Creo el array de ruta (filtrando los vacíos)
$array_ruta = array_filter(explode("/", $ruta));
//Decido la ruta en función de los elementos del array
if (isset($array_ruta[0]) && $array_ruta[0] == "ver" && is_numeric($array_ruta[1])){
//Llamo al método ver pasándole la clave que me están pidiendo
$controller->ver($array_ruta[1]);
}
else{
//Llamo al método por defecto del controlador
$controller->index();
}
Ejercicio propuesto 8
- Modifica el Ejercicio 7 para adaptarlo al uso de Namespaces.
Publicado el 21 de Noviembre de 2024