Je travaille sur un projet par lequel j'ai la structure de fichiers suivante:
index.php
|---lib
|--|lib|type|class_name.php
|--|lib|size|example_class.php
Je voudrais charger automatiquement les classes, nom_classe et classe_exemple (nommées de la même manière que les classes PHP), afin que dans index.php les classes soient déjà instanciées afin que je puisse faire:
$class_name->getPrivateParam('name');
J'ai jeté un œil sur le net mais je ne trouve pas vraiment la bonne réponse - quelqu'un peut-il m'aider?
Merci pour les réponses. Permettez-moi de développer mon scénario. J'essaie d'écrire un plugin WordPress qui peut être déposé dans un projet et des fonctionnalités supplémentaires ajoutées en déposant une classe dans un dossier "fonctionnalité" par exemple, à l'intérieur du plugin. Il n'y aura jamais 1000 classes, à un Push peut-être 10?
Je pouvais écrire une méthode pour parcourir la structure de dossiers du dossier "lib", y compris chaque classe, puis l'attribuer à une variable (du nom de la classe), mais je ne pensais pas que c'était un moyen très efficace de le faire, mais il semble peut-être que c'est la meilleure façon d'atteindre ce dont j'ai besoin?
S'il vous plaît, si vous avez besoin de charger automatiquement des classes - utilisez les espaces de noms et les conventions de noms de classe avec le chargement automatique SPL, cela vous fera gagner du temps pour la refactorisation. Et bien sûr, vous devrez instancier chaque classe en tant qu'objet. Merci.
Comme dans ce fil: chargement automatique PHP dans les espaces de noms
Mais si vous souhaitez une solution de contournement complexe, veuillez jeter un œil à la classe de chargement automatique de Symfony: https://github.com/symfony/ClassLoader/blob/master/ClassLoader.php
Ou comme ça (je l'ai fait dans l'un de mes projets):
<?
spl_autoload_register(function($className)
{
$namespace=str_replace("\\","/",__NAMESPACE__);
$className=str_replace("\\","/",$className);
$class=CORE_PATH."/classes/".(empty($namespace)?"":$namespace."/")."{$className}.class.php";
include_once($class);
});
?>
puis vous pouvez instancier votre classe comme ceci:
<?
$example=new NS1\NS2\ExampleClass($exampleConstructParam);
?>
et voici votre classe (trouvée dans /NS1/NS2/ExampleClass.class.php):
<?
namespace NS1\NS2
{
class Symbols extends \DB\Table
{
public function __construct($param)
{
echo "hello!";
}
}
}
?>
Si vous avez accès à la ligne de commande, vous pouvez l'essayer avec composer dans la section classMap avec quelque chose comme ceci:
{
"autoload": {
"classmap": ["yourpath/", "anotherpath/"]
}
}
alors vous avez un plugin wordpress pour activer composer dans le wordpress cli: http: // wordpress .org/plugins/composer /
http://php.net/manual/de/function.spl-autoload-register.php
spl_autoload_register(function ($class) {
@require_once('lib/type/' . $class . '.php');
@require_once('lib/size/' . $class . '.php');
});
function __autoload($class_name) {
$class_name = strtolower($class_name);
$path = "{$class_name}.php";
if (file_exists($path)) {
require_once($path);
} else {
die("The file {$class_name}.php could not be found!");
}
}
MISE À JOUR:__autoload()
est obsolète à partir de PHP 7.2
J'ai ici un exemple que j'utilise pour le chargement automatique et l'initialisation.
Fondamentalement, une meilleure version de spl_autoload_register car elle essaie uniquement d'exiger le fichier de classe chaque fois que vous initialisez la classe.
Ici, il récupère automatiquement chaque fichier dans votre dossier de classe, requiert les fichiers et l'initialise. Il vous suffit de nommer la classe de la même manière que le fichier.
index.php
<?php
require_once __DIR__ . '/app/autoload.php';
$loader = new Loader(false);
User::dump(['hello' => 'test']);
autoload.php
<?php
class Loader
{
public static $library;
protected static $classPath = __DIR__ . "/classes/";
protected static $interfacePath = __DIR__ . "/classes/interfaces/";
public function __construct($requireInterface = true)
{
if(!isset(static::$library)) {
// Get all files inside the class folder
foreach(array_map('basename', glob(static::$classPath . "*.php", GLOB_BRACE)) as $classExt) {
// Make sure the class is not already declared
if(!in_array($classExt, get_declared_classes())) {
// Get rid of php extension easily without pathinfo
$classNoExt = substr($classExt, 0, -4);
$file = static::$path . $classExt;
if($requireInterface) {
// Get interface file
$interface = static::$interfacePath . $classExt;
// Check if interface file exists
if(!file_exists($interface)) {
// Throw exception
die("Unable to load interface file: " . $interface);
}
// Require interface
require_once $interface;
//Check if interface is set
if(!interface_exists("Interface" . $classNoExt)) {
// Throw exception
die("Unable to find interface: " . $interface);
}
}
// Require class
require_once $file;
// Check if class file exists
if(class_exists($classNoExt)) {
// Set class // class.container.php
static::$library[$classNoExt] = new $classNoExt();
} else {
// Throw error
die("Unable to load class: " . $classNoExt);
}
}
}
}
}
/*public function get($class)
{
return (in_array($class, get_declared_classes()) ? static::$library[$class] : die("Class <b>{$class}</b> doesn't exist."));
}*/
}
Vous pouvez facilement gérer avec un peu de codage, pour exiger également des classes dans différents dossiers.
J'espère que cela peut vous être utile.
Vous pouvez spécifier un chargement automatique adapté aux espaces de noms à l'aide de ce chargeur automatique.
<?php
spl_autoload_register(function($className) {
$file = __DIR__ . '\\' . $className . '.php';
$file = str_replace('\\', DIRECTORY_SEPARATOR, $file);
if (file_exists($file)) {
include $file;
}
});
Assurez-vous que vous spécifiez correctement l'emplacement du fichier de classe.