Эффективные стратегии автоматической загрузки PHP и присвоения имен

StackOverflow https://stackoverflow.com/questions/791899

Вопрос

Как и большинство веб-разработчиков в наши дни, я полностью наслаждаюсь преимуществами надежной архитектуры MVC для веб-приложений и сайтов.При выполнении MVC с PHP автозагрузка, очевидно, чрезвычайно удобна.

Я стал поклонником spl_autoload_register над простым определением единого __autoload() функции, поскольку это, очевидно, более гибко, если вы включаете разные базовые модули, каждый из которых использует свою собственную автозагрузку.Однако мне никогда не нравились функции загрузки, которые я пишу.Они включают в себя большую проверку строк и сканирование каталогов, чтобы искать возможные классы для загрузки.

Например, допустим, у меня есть приложение, базовый путь к которому определен как PATH_APP, и простая структура с каталогами по имени models, views и controllers.Я часто использую структуру именования, в соответствии с которой файлам присваиваются имена IndexView.php и IndexController.php внутри соответствующего каталога, и модели обычно не имеют определенной схемы по умолчанию.У меня могла бы быть функция загрузки для этой структуры, подобная этой, которая регистрируется с spl_autoload_register:

public function MVCLoader($class)
{
    if (file_exists(PATH_APP.'/models/'.$class.'.php')) {
        require_once(PATH_APP.'/models/'.$class.'.php');
        return true;
    }
    else if (strpos($class,'View') !== false) {
        if (file_exists(PATH_APP.'/views/'.$class.'.php')) {
            require_once(PATH_APP.'/views/'.$class.'.php');
            return true;
        }
    }
    else if (strpos($class,'Controller') !== false) {
        if (file_exists(PATH_APP.'/controllers/'.$class.'.php')) {
            require_once(PATH_APP.'/controllers/'.$class.'.php');
            return true;
        }
    }
    return false;
}

Если после этого он не будет найден, у меня может быть другая функция для сканирования подкаталогов в каталоге моделей.Однако все операции if / else, проверка строк и сканирование каталогов кажутся мне неэффективными, и я хотел бы это улучшить.

Мне очень любопытно, какие стратегии именования файлов и автозагрузки могли бы использовать другие разработчики.Я специально ищу хорошие методы для эффективной автозагрузки, а не альтернативы автозагрузке.

Это было полезно?

Решение

Это то, что я использовал во всех своих проектах (взято прямо из исходного кода последнего).:

public static function loadClass($class)
{
    $files = array(
        $class . '.php',
        str_replace('_', '/', $class) . '.php',
    );
    foreach (explode(PATH_SEPARATOR, ini_get('include_path')) as $base_path)
    {
        foreach ($files as $file)
        {
            $path = "$base_path/$file";
            if (file_exists($path) && is_readable($path))
            {
                include_once $path;
                return;
            }
        }
    }
}

Если я поищу SomeClass_SeperatedWith_Underscores, он будет искать SomeClass_SeperatedWith_Underscores.php за которым следует SomeClass/SeperatedWith/Underscores.php root в каждом каталоге текущего включаемого пути.

Редактировать: Я просто хотел подчеркнуть, что использую это для повышения эффективности разработки и не обязательно для увеличения времени обработки.Если у вас есть PEAR на вашем path, то с помощью этого вы можете просто использовать классы и вам не нужно включать их, когда они вам нужны.

Я склонен хранить свои классы в иерархии каталогов, где подчеркивания разбивают пространства имен...Этот код позволяет мне сохранить структуру файла красивой и аккуратной, если я хочу, или быстро внедрить файл класса без вложенных каталогов, если я хочу (для добавления одного или двух классов в библиотеку, в которой он находится, но не является частью проекта, над которым я сейчас работаю).

Другие советы

Я остановился на этом решении:

Я создал единственный скрипт, который просматривает мою папку библиотеки классов (которая содержит вложенные папки для отдельных модулей / систем) и анализирует содержимое файла в поисках определений классов.Если он находит определение класса в файле php (довольно простой шаблон регулярного выражения), он создает символическую ссылку:

class_name.php -> actual/source/file.php

Это позволяет мне использовать единственную простую функцию автозапуска, которой требуется только имя класса и путь к основной папке символических ссылок, и не нужно выполнять никаких манипуляций с путем / строкой.

Самое приятное то, что я могу полностью изменить свой исходный код или добавить новую подсистему и просто запустить скрипт генерации ссылок, чтобы все было загружено автоматически.

Если вы хотите повысить эффективность, то вам вообще не следует использовать функцию автозапуска.Функция автоматической загрузки предназначена для того, чтобы быть ленивым.Вы должны указывать явный путь к вашим включаемым файлам, когда вы их включаете.Если ваша функция автозагрузки может найти эти файлы, то вы могли бы закодировать их для явного поиска.Когда вы работаете над частью кода view и собираетесь загрузить новый класс view, позволяя функции автозапуска обрабатывать его, сначала предполагается, что ваш класс является классом модели?Это неэффективно.Вместо этого ваш код должен быть просто:

include_once $this->views_path . $class . '.php';

Если вам нужно несколько путей "просмотра", создайте функцию, которая загружает представления:

public function load_view($class) {
    // perhaps there's a mapping here instead....
    foreach ($this->views_paths as $path) {
        $filename = $path . $class . '.php';
        if (file_exists($filename)) {
            include_once $filename;
        }
    }
    throw ....
}

В любом случае, в момент, когда происходит включение, у вас есть самая большая / наиболее точная информация о классе, который вы хотите загрузить.Использование этой информации для полной загрузки класса - единственная эффективная стратегия загрузки класса.Да, в конечном итоге вы можете получить больше переменных класса или (не дай бог) несколько глобальных переменных.Но это лучший компромисс, чем просто лениться и сканировать части файловой системы для вашего класса.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top