Подтвердить что ты не робот

Лучший способ для автозагрузки классов в 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", включая каждый класс, который затем присваивал его переменной (имени класса), но не думал, что это очень эффективный способ сделать но, может быть, это лучший способ добиться того, что мне нужно?

4b9b3361

Ответ 1

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

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

Но если вы хотите сложное обходное решение, ознакомьтесь с классом autoload 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);
?>

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

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

Ответ 2

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

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

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

Ответ 4

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

UPDATE: __autoload() устарел от PHP 7.2

Ответ 5

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

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