Что такое автозагрузка; Как вы используете 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 по имени пути.