2017-09-25 3 views
-1

De nombreux développeurs qui écrivent des applications orientées objet créent un fichier source PHP par définition de classe. L'un des plus grands ennuis est avoir à écrire une longue liste de comprend nécessaire au début de chaque script (un pour chaque classe).PHP Autoload classes sans importer les espaces de noms au-dessus de chaque script

En PHP 5, ce n'est plus nécessaire. La fonction spl_autoload_register() enregistre n'importe quel nombre d'autochargeurs, ce qui permet de charger automatiquement les classes et les interfaces si elles ne sont pas actuellement définies . Source: http://php.net/manual/en/language.oop5.autoload.php

Eh bien, je trouve que cette déclaration n'est pas vrai, parce que je finis toujours par écrire longue liste de comprend les importations dans chaque fichier simplement parce que je suis en utilisant différents sous-dossiers dans mon inclut dossier et namespaces selon la convention de codage PSR-0 de PHP-FIG.

includes/core/database/ 
includes/core/html/ 
includes/domain/ 
etc. 

spl_autoload_register() Impossible de charger automatiquement DB, HTML classes logiques de domaine, car il ne connaît pas la structure du dossier dans lequel le fichier est donc je suis en utilisant les espaces de noms à lui, mais il faut tout autant l'espace comme ayant les importations au-dessus de tous les scénario.

use MyProject\Core\Database; 
use MyProject\Core\Html; 
use MyProject\domain; 

J'utilise différentes classes par script afin que je ne peux pas simplement faire un gros fichier et include_once(), en plus de l'importation de namespaces ne fonctionne pas avec include_once().

J'instancier classe comme ceci

try { 

    $DBQuery  = new Database\DBQuery(); 
    $HtmlGenerator = new Html\HtmlGenerator(); 
    $domain  = new domain\UserRegister(); 

} catch (Error $e) { 
    echo $e->getMessage(); 
} 

Ma fonction Autoload

spl_autoload_register(function ($fullyQualifiedClassName) { 

    //change backslash in namespace name to DIRECTORY_SEPARATOR for file system 
    if (stristr($fullyQualifiedClassName, "\\")) { 
     $fullyQualifiedClassName = str_ireplace("\\", DIRECTORY_SEPARATOR, $fullyQualifiedClassName); 
    } 

    //function dirname() used because THIS file in sub folder /includes and we need to go to parent folder 
    $class_path = $lib_patch . DIRECTORY_SEPARATOR . "{$fullyQualifiedClassName}.php"; 

    if (!is_file($class_path)) { 
     throw new Error("Unable to load class with path: $class_path"); 
    } 

    require_once $class_path; 
}); 

Toute façon je peux éviter d'importer plusieurs espaces de noms à ce que je suis ouvert à arrêter en utilisant namespaces complètement, mais je voudrais conserve ma structure de sous-dossier. Est-ce que la fonction de chargement automatique permet de savoir dans quel dossier se trouvent mes fichiers sans faire de code qui fera une boucle dans chaque sous-dossier à la recherche d'un fichier, par exemple. DBQuery.php car cela aura un impact sur les performances.

+0

Bien que vous ne répondiez pas immédiatement à votre question, jetez un coup d'œil à l'utilisation de composer pour la résolution d'importation de votre projet. L'autre façon est de faire une recherche de fichier récursif pour appeler spl_autoload_register. – thepratt

Répondre

1

L'auto-chargement est vous économisant de include les fichiers, vous avez maintenant exclusivement affaire à la résolution de noms. Si vous ne voulez pas d'écrire un tas de déclaration use dans vos fichiers, vous pouvez simplement utiliser les noms qualifiés de ces classes au lieu de les aliasing:

$db = new \MyProject\Core\Database; 
$html = new \MyProject\Core\Html; 
... 

L'utilisation de use MyProject\Core\Database est qu'il vous permet de écrivez Database au lieu de \MyProject\Core\Database. Le chargement automatique du fichier sous-jacent fonctionne de la même manière.

Si vous n'aimez même pas cet aspect, alors il est difficile d'avoir votre gâteau et de le manger aussi. Vous pouvez aplatir vos espaces de noms afin de ne pas avoir autant d'espaces de noms différents à importer, mais votre organisation de projet commence alors à devenir plus encline à nommer des conflits ou à trouver des fichiers plus difficiles. C'est un compromis, quelque chose doit donner quelque part. Si vous n'êtes pas satisfait de l'utilisation des espaces de noms, vous devez trouver un nouveau middleground pour vous-même.Cela dit, dans de nombreuses langues, il est extrêmement courant d'avoir un tas d'instructions d'importation en haut de chaque fichier d'une manière ou d'une autre. Un IDE décent peut largement générer automatiquement ceux-ci pendant que vous écrivez votre code. C'est quelque chose que vous devriez plutôt vous habituer au lieu de lutter contre cela. Cela peut être ennuyeux, mais les alternatives sont plus d'affrontements de noms ou d'importations géantes. Il est pratiquement impossible de l'avoir modulaire, rapide, extensible et tous en même temps.