Лучший способ автозагрузки классов в PHP

Я работаю над проектом, в котором у меня есть следующая структура файла:

index.php
|---lib
|--|lib|type|class_name.php
|--|lib|size|example_class.php

Я хотел бы автоматически загрузить классы class_name и example_class (названные так же, как и классы PHP), чтобы в index.php классы уже были созданы, чтобы я мог сделать:

$class_name->getPrivateParam('name');

Я посмотрел в сети, но не могу найти правильный ответ - кто-нибудь может мне помочь?

РЕДАКТИРОВАТЬ

Спасибо за ответы. Позвольте мне расширить мой сценарий. Я пытаюсь написать плагин WordPress, который можно добавить в проект и добавить дополнительные функциональные возможности, поместив класс в папку "функциональные возможности", например, внутри плагина. Там никогда не будет 1000 классов, на толчок, может быть, 10?

Я мог бы написать метод для перебора структуры папок в папке 'lib', включая каждый класс, затем присвоение его переменной (имени класса), но не думал, что это очень эффективный способ сделать это, но это возможно, кажется, что это лучший способ добиться того, что мне нужно?

8 ответов

Пожалуйста, если вам нужно автозагрузить классы - используйте пространства имен и соглашения о именах классов с автозагрузкой SPL, это сэкономит ваше время на рефакторинг. И, конечно же, вам нужно создать экземпляр каждого класса как объекта. Спасибо.

Как в этой теме: автозагрузка PHP в пространствах имен

Но если вам нужен сложный обходной путь, взгляните на класс автозагрузки Symfony: https://github.com/symfony/ClassLoader/blob/master/ClassLoader.php

Или вот так (я сделал это в одном из моих проектов):

<?
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);
});
?>

и тогда вы можете создать экземпляр своего класса следующим образом:

<?
$example=new NS1\NS2\ExampleClass($exampleConstructParam);
?>

и это ваш класс (находится в /NS1/NS2/ExampleClass.class.php):

<?
namespace NS1\NS2
{
    class Symbols extends \DB\Table
    {
        public function __construct($param)
        {
            echo "hello!";
        }
    }
}
?>

Если у вас есть доступ к командной строке, вы можете попробовать это с помощью composer в разделе classMap примерно так:

{
    "autoload": {
        "classmap": ["yourpath/", "anotherpath/"]
    }
}

тогда у вас есть плагин WordPress для включения композитора в WordPress Cli: http://wordpress.org/plugins/composer/

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!");
   }
}

ОБНОВИТЬ:__autoload() устарело с версии PHP 7.2

У меня есть пример, который я использую для автозагрузки и инициализации.
По существу, лучшая версия spl_autoload_register, поскольку она пытается запросить файл класса только при инициализации класса.
Здесь он автоматически получает каждый файл в папке вашего класса, запрашивает файлы и инициализирует его. Все, что вам нужно сделать, это назвать класс так же, как файл.
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."));
    }*/
}

Вы можете легко управлять с небольшим количеством кода, требуя классов в разных папках тоже.
Надеюсь, это может быть полезным для вас.

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');
});

сделайте это в файле и назовите его как-нибудь вроде (mr_load.php), это были все ваши классы

      spl_autoload_register(function($class){ 
     $path = '\Applicaton/classes/';
    $extension = '.php';
    $fileName = $path.$class.$extension;
    include $_SERVER['DOCUMENT_ROOT'].$fileName;
})

;

  • затем создайте еще один файл и включите mr_load.php; $load_class = новая автобусная остановка(); $load_class->метод()

С помощью этого автозагрузчика можно указать удобную для пространств имен автозагрузку.

<?php
spl_autoload_register(function($className) {
    $file = __DIR__ . '\\' . $className . '.php';
    $file = str_replace('\\', DIRECTORY_SEPARATOR, $file);
    if (file_exists($file)) {
        include $file;
    }
});

Убедитесь, что вы правильно указали расположение файла класса.

Источник

      spl_autoload_register(function ($class_name) {
    $iterator = new DirectoryIterator(dirname(__FILE__));
    $files = $iterator->getPath()."/classes/".$class_name.".class.php";
    
    if (file_exists($files)) {
        include($files);
    } else {
       die("Warning:The file {$files}.class.php could not be found!");
    
    }
});
Другие вопросы по тегам