On réalise ceci grâce la fonction __autoload, on verra ensuite tout la puissance de la chose avec les fontions spl_autoload*.
Exemple 1 :
//Test.php
class Test
{
public __construct()
{
return 'hello';
}
}//index.php
function __autoload($class)
{
require_once($class . '.php');
}
$test = new Test();
echo $test;
//hello
Que fais le script ?Au moment de new Test(), comme php ne trouve pas la classe il fera appelle a la fonction __autoload et lui donne en paramètre le non de la classe (ici : Test), la fonction fait tout simplement un require_once vers le fichier .php.
Si on fais $test2 = new Test2(); php ira bien-sur cherche le fichier Test2.php, ainsi que toutes les autres classes qui ne sont pas définie.
La limitation ici sera arborescence
_______________________________________________
Il y'a une autre astuce pour ça que l'on vois dans de nombreux frameworks c'est l'utilisation du underscore
Exemple 2 :
//My/Framework/Test.php
class My_Framwork_Test
{
public __construct()
{
return 'hello';
}
}//index.php
function __autoload($class)
{
$path = str_replace('_', DIRECTORY_SEPARATOR, $class);
require_once($path . '.php');
}
$test = new My_Framwork_Test();
echo $test;
//hello
Que fais le script ?La même chose que dans l'exemple 1, sauf qui va allé chercher le fichier dans le dossier My/Framework, on peux très bien allé chercher une classe nommée My_Framwork_Utils_Debug il ira chercher My/Framwork/Utils/Debug.php
La limitation ici c'est que ca peux vite devenir lourd avec des noms a rallonge
_______________________________________________
La puissance des namespaces :
Depuis PHP 5.3 on le droit au namespace, on se rapproche donc du java, c++, as3 (et plein d'autre).
Il y'a 2 façons (+1 variante) d'appeler une classe qui appartient a un namespace
façon 1
$test = new My\Framework\Test();+ simple d'utilisation- les noms sont vite a rallonge
- lorsque qu'on est dans un namespace toutes les classes du global changent en \Class (ex : new \DOMDocument)
façon 2
use My\Framework\Test
$test = new Test();+ pas de confusion dans les namespaces- définition des toutes les classes utilisées dans l'entête (comme en java,as3 avec import)
façon 2 (variante)
use My\Framework\Test as Test
$test = new Test();+/- au cas ou 2 class aurai le même nom (ex: My\Framework\DOMDocument as DOMDocument2), ce qui serait ridicule je recommande de ne pas nommer une classe qui appartient aussi au global (allez voir du coté de get_declared_classes, y'en pas pas tant que ca en plus (150 chez moi))Je recommande la façon 2, c'est celle qui va le plus se rapprocher d'autres langages et le script sera plus facile a maintenir (si vous changez de namespace on changera juste dans l'en-tete les use), et pas besoin de modifier les classes global (new DOMDomcument() en new \DOMDocument)
_______________________________________________
Autoload + namespace
Voyons ce que ca donne avec les namespaces
Exemple 3 :
//My/Framework/Test.php
namespace My\Framework;
class Test
{
public __construct()
{
return 'hello';
}
}//index.php
function __autoload($class)
{
$path = str_replace('\\', DIRECTORY_SEPARATOR, $class);
require_once($path . '.php');
}
$test = new My\Framwork\Test();
echo $test;
//hello
Que fais le script ?La même chose que dans l'exemple 2, sauf qu'il remplace les \ du namespace par le DIRECTORY_SEPARATOR (ce qui change rien sous windows)
On peux faire aussi
use My\Framwork\Test;
$test = new Test();
echo $test;
Limitation ici : définition de la function __autoload et toujours l'utilisation du require finalement_______________________________________________
La méthode ultime : namespace + spl_autoload (PHP 5.3.3+)
La library SPL a aussi c'est fonction d'autoload, qui fais un surcharge de la fonction __autoload par défaut en y ajoutant quelques fonctionnalités : la prise en charge des extensions, le directory separator.
Exemple 4
//My/Framework/Test.php
namespace My\Framework;
class Test
{
public __construct()
{
return 'hello';
}
}spl_autload_register();
$test = new My\Framwork\Test();
echo $test;
Que fais le script ?un simple spl_autoload_register suffira;
spl_autoload_register appelle par défaut spl_autoload
spl_autoload, va chercher dans le path donné ( peu importe le separator) les fichiers .php ou .inc qui correspondent (on peux régler les extensions : .class.php par ex)
Le seule limitation ici sera la version de PHP qui dois être PHP 5.3.3+ (du a un bug dans les autres versions de php 5.3 (ca ne marchait pas sous *nix)
_______________________________________________
l'autoload va bien-sur également chercher dans le included_path, et même dans les phars (mais attention dans les phars tout les noms de fichier doivent être en lowercase)
Exemple 6 :
avec un phar qui contient tout la lib , qui aurait juste en webPhar : spl_autload_register(); et pour couronné le tout qui sera dans le included_path
on fera juste
$test = new My\Framwork\Test();
echo $test;
//hello