Что такое автозагрузка; Как вы используете spl_autoload, __autoload и spl_autoload_register?

Я изучаю передовые стандарты PHP и пытаюсь реализовать новые и полезные методы. Раньше я пользовалась __autoload просто чтобы избежать включения нескольких файлов на каждой странице, но недавно я видел совет __autoload manual

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

но я действительно не могу понять, как реализовать spl_autoload а также spl_autoload_register

4 ответа

Решение

spl_autoload_register() позволяет вам зарегистрировать несколько функций (или статических методов из вашего собственного класса автозагрузки), которые PHP будет помещать в стек / очередь и вызывать последовательно при объявлении "нового класса".

Так, например:

spl_autoload_register('myAutoloader');

function myAutoloader($className)
{
    $path = '/path/to/class';

    include $path.$className.'.php';
}

//-------------------------------------

$myClass = new MyClass();

В приведенном выше примере "MyClass" - это имя класса, который вы пытаетесь создать, PHP передает это имя в виде строки spl_autoload_register(), что позволяет подобрать переменную и использовать ее для "включения" соответствующего класса / файла. В результате вам не нужно специально включать этот класс с помощью оператора include/require...

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

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

Пример:

spl_autoload_register('MyAutoloader::ClassLoader');
spl_autoload_register('MyAutoloader::LibraryLoader');
spl_autoload_register('MyAutoloader::HelperLoader');
spl_autoload_register('MyAutoloader::DatabaseLoader');

class MyAutoloader
{
    public static function ClassLoader($className)
    {
         //your loading logic here
    }


    public static function LibraryLoader($className)
    {
         //your loading logic here
    }

Что касается spl_autoload, в руководстве говорится:

Эта функция предназначена для использования в качестве реализации по умолчанию для __autoload(), Если ничего не указано и spl_autoload_register() вызывается без каких-либо параметров, то эти функции будут использоваться для любого последующего вызова __autoload(),

С практической точки зрения, если все ваши файлы расположены в одном каталоге, а ваше приложение использует не только файлы.php, но и пользовательские файлы конфигурации, например, с расширениями.inc, то одна из стратегий, которую вы могли бы использовать, - добавить каталог, содержащий все файлы к пути включения PHP (через set_include_path()).
А так как вам требуются ваши файлы конфигурации, вы должны использовать spl_autoload_extensions() перечислить расширения, которые вы хотите, чтобы PHP искал.

Пример:

set_include_path(get_include_path().PATH_SEPARATOR.'path/to/my/directory/');
spl_autoload_extensions('.php, .inc');
spl_autoload_register();

Поскольку spl_autoload является реализацией по умолчанию __autoload() магический метод, PHP вызовет spl_autoload, когда вы попытаетесь создать новый класс.

Надеюсь это поможет...

Начиная с PHP 5.3, вы можете использовать spl_autoload_register() с пространствами имен, что означает, что вы можете организовать свой проект и автоматически загружать свои php-классы без каких-либо требований или включать и без переопределения __autoload() функция.

Чтобы продемонстрировать это поведение, просто создайте файл с именем index.php:

<?php
spl_autoload_register();
var_dump(new Main\Application);

Затем создайте папку с именем Main, расположенную прямо рядом с файлом index.php. Наконец, создайте файл Application.php, расположенный в Main, и вставьте в него следующий код:

<?php namespace Main;
class Application{}

Вот как я использую Autoload. В данном примере я хочу загрузить классы из 3 разных каталогов.

function namespaceAutoload($rawClass){

$class = str_replace('\\', DIRECTORY_SEPARATOR, $rawClass);

$possiblePaths[] = '..\sys\class\file.php';
$possiblePaths[] = '..\sys\class\lib\file.php';
$possiblePaths[] = '..\sys\class\class.file.inc.php';

foreach ($possiblePaths as $templatePath) {
    $path = str_replace(["\\", "file"], [DIRECTORY_SEPARATOR, $class], $templatePath);
    if (file_exists($path)) {
        require_once "$path";
        break;
    }
} spl_autoload_register("namespaceAutoload"); 

В данном примере PHP будет искать пространство имен \class в этих трех каталогах, используя эти три разных формата файлов.

Работа с ООП в php,spl_autoload_register()позволяет зарегистрировать несколько функций, классов, свойств и т. д. в вашем php-скрипте.

Вот пример использования/testструктура папок

      /.htaccess
/index.php
/autoload.php
/controller/test.php

Внутри файла autoload.php:

      spl_autoload_register(function ($classname) {
    include_once dirname(__FILE__) . "/" . str_replace("\\", "/", $classname) . '.php';
});

Внутри .htaccess

      DirectoryIndex index.php

# php_value auto_prepend_file 
php_value auto_prepend_file "/xampp/htdocs/test/autoload.php"

Внутри контроллера/test.php

      namespace controller;

class test {
   public static function sayHello () {
     echo "hello";
   }
}

Внутри index.php

      use controller/test;

echo test::sayHello();

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

Другие вопросы по тегам