Spl autoload register



<?php

    /*** nullify any existing autoloads ***/
    
spl_autoload_register(nullfalse);

    /*** specify extensions that may be loaded ***/
    
spl_autoload_extensions('.php, .class.php, .lib.php');

    /*** class Loader ***/


$class) . '.class.php';
        
$file ='classes/' $filename;
        if (!
file_exists($file))
        {
            return 
false;
        }
        include 
$file;
    }


    function libLoader($class)
    {
        
$filename strtolower($class) . '.lib.php';
        
$file ='libs/' $filename;
        if (!
file_exists($file))
        {
            return 
false;
        }
        include 
$file;
    }


    /*** register the loader functions ***/
    
spl_autoload_register('classLoader');
    
spl_autoload_register('libLoader');

    /*** a new instance of norman ***/
    
$norman = new norman;

    /*** make norman do some thing ***/
    
$norman->do_something();


www.phpro.org

spl_autoload_register() allows you to register multiple functions (or static methods from your own Autoload class) that PHP will put into a stack/queue and call sequentially when a «new Class» is declared.

So for example:

spl_autoload_register('myAutoloader');  function myAutoloader($className) {  $path = '/path/to/class/';   include $path.$className.'.php'; }  //-------------------------------------  $myClass = new MyClass(); 

In the example above, «MyClass» is the name of the class that you are trying to instantiate, PHP passes this name as a string to spl_autoload_register(), which allows you to pick up the variable and use it to «include» the appropriate class/file. As a result you don’t specifically need to include that class via an include/require statement…

Just simply call the class you want to instantiate like in the example above, and since you registered a function (via spl_autoload_register()) of your own that will figure out where all your class are located, PHP will use that function.

The benefit of using spl_autoload_register() is that unlike __autoload() you don’t need to implement an autoload function in every file that you create. spl_autoload_register()


also allows you to register multiple autoload functions to speed up autoloading and make it even easier.

Example:

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  } 

With regards to spl_autoload, the manual states:

This function is intended to be used as a default implementation for __autoload(). If nothing else is specified and spl_autoload_register() is called without any parameters then this functions will be used for any later call to __autoload().

In more practical terms, if all your files are located in a single directory and your application uses not only .php files, but custom configuration files with .inc extensions for example, then one strategy you could use would be to add your directory containing all files to PHP’s include path (via set_include_path()).
And since you require your configuration files as well, you would use spl_autoload_extensions() to list the extensions that you want PHP to look for.

Example:

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

Since spl_autoload is the default implementation of the __autoload() magic method, PHP will call spl_autoload when you try and instantiate a new class.

Hope this helps…

stackoverflow.com

Содержание:

  • Предисловие
  • Средства SPL
  • Пространства имён, PSR-0 и PSR-4
  • Использование загрузчика Composer

Предисловие

Современные web-приложения, как правило, состоят из множества классов, каждый из которых решает определённую задачу.

Итак, по умолчанию, если в некотором нашем приложении нам необходимо использовать некий класс, скажем, MyClass, нам нужно удостоверится, что файл, в котором описан данный класс, был ранее подключён с помощью операторов require или include:

require_once ("path_to/myclass.php"); … $instance = new MyClass(); … 

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


Одна из проблем состоит в том, что зачастую приложения обладают отнюдь не линейной структурой и далеко не всегда мы можем знать заранее какие из множества классов (которые потенциально могут быть использованы в ходе выполнения скриптов), будут действительно задействованы, а какие — нет. Подключение заранее всех потенциально используемых классов ведёт к нерациональному использованию ресурса памяти, а «ручное» подключение нужных классов «по ходу дела» скорее всего приведёт к использованию разл. ухищрений в виде проверок условий и операторов включения, и в последствии — усложнению кода, и ухудшению его удобочитаемости.

В рамках данной статьи речь пойдёт именно об автоматической загрузке классов в PHP приложении.

Средства SPL

В PHP (начиная примерно с версии 5) появилась замечательная возможность автоматической загрузки ранее не загруженных классов. Т.е. когда PHP интерпретатор встречает в коде упоминание некоего класса, он теоретически может самостоятельно попытаться выполнить загрузку указанного класса. Однако, чтобы это стало возможным, нам всё же придётся описать некую функцию (метод), которая определяет, где именно находится описание нужного класса. Обычно она называется функция-загрузчик.

Не будем рассматривать здесь использование ф-ции __autoload(); т. к. этот путь ныне считается несколько устаревшим и практически полностью вытеснен повсеместно средствами из набора SPL.


Описать и зарегистрировать функцию-загрузчик можно несколькими способами, например так:

 ... spl_autoload_register( function($classname){ 	require_once( "/my_classes_folder/" . $classname . ".php");	 } ); ... 

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

Работает это примерно так:
Когда PHP интерпретатор встретит в коде имя незнакомого класса, он попытается его загрузить последовательно с помощью всех таких зарегистрированных автозагрузчиков. Т.е. каждой функции-загрузчику по очереди в качестве параметра (в нашем случае — $classname) будет передано полное* имя этого «незнакомого» класса, затем чтобы функция-загрузчик смогла попытаться найти соотв. файл с описанием этого класса и включить его. Если ни одна из зарегистрированных ф-ций-загрузчиков не смогла найти и подключить класс, в итоге будет выброшена ошибка о том, что такой класс не был найден.

Более подробную информацию о spl-функциях управления автозагрузкой с примерами можно найти по ссылке: http://php.net/manual/ru/ref.spl.php


В данном примере, мы приняли, что в нашем приложении файлы с описанием классов расположены в некой папке /my_classes_folder/, а ещё имя файла класса обязано совпадать с именем самого класса. Т.е. по нашему соглашению, чтобы найти и загрузить скажем, MyClass мы должны добавить к пути /my_classes_folder/ имя класса (MyClass), затем добавить к нему расширение .php и включить с его помощью require. Что, собственно, и описано в примере выше. Все проверки на существование соотв файлов и путей и прочее здесь опущены простоты ради.

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

Пространства имён, PSR-0 и PSR-4

Начиная с версии 5.3 PHP стал ещё немного ближе к другим развитым языкам программирования, и вместе с тем в нём появилась поддержка пространств имён (namespaces). В контексте нашей задачи это прежде всего означает, что для всякого класса (интерфейса, примеси) мы приобрели также возможность указывать его место в общей иерархии классов.

Подробнее о пространствах имён в PHP можно узнать из официальной документации: http://php.net/manual/ru/language.namespaces.php


Предположим, что наш класс MyClass относится к некой группе утилитарных (вспомогательных) классов, т.е входит в подгруппу Utilities, которая в свою очередь входит в общую подгруппу MyClasses:

 … namespace MyClassesUtilities;  class MyClass { … } … 

Как такие нововведения могут помочь решить некоторые из упомянутых ранее проблем?

Рассмотрим этот пример класса MyClass, в контексте с анонимной функцией-загрузчиком, описанным выше. Начнём с того, что полное имя класса в нашем теперешнем случае будет состоять из имени пространства + имени самого класса, т. е. — MyClassesUtilitiesMyClass. И именно в таком виде оно будет передано в кач-ве фактического параметра в функцию-загрузчик. То есть используя прежнюю схему без изменения мы получим по факту такой путь к файлу с описанием класса: /my_classes_folder/MyClassesUtilitiesMyСlass.php
А если заменим в этой строке все обратные слэши на обычные? Получим на вид типичный путь, состоящий из иерархии папок и файл MyClass.php в конце.

/my_classes_folder/MyClasses/Utilities/MyСlass.php

Модифицируем соотв. образом код нашей ф-ции-загрузчика:

 ... spl_autoload_register( function($classname){ 	require_once(realpath("/my_classes_root_folder/" . str_replace("\", "/", $classname) . ".php"));	 } ); ... 

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

Именно этот принцип положен в основу соглашений об именовании Классов и пространств имён а также структуре папок в приложениях, которые на сегодняшний день используют многие современные PHP фреймворки, библиотеки. Эти соглашения получили название стандартов автозагрузки PSR-0 и PSR-4. По сути PSR-4 является улучшением, базирующимся на основе того же PSR-0. Подробнее об этих стандартах можно прочесть, например, здесь.

Таким образом, мы пришли к более современному подходу к автозагрузке классов, который базируется на стандартах PSR-0 / PSR-4. Рассмотрим пример простого класса, который реализует подобный механизм автозагрузки по стандарту PSR-0.

 class Autoloader {  /**  * @var Autoloader instance  */  protected static $instance;   /**  * @var array Namespace mapping  */  protected static $ns_map = [];   /**  * Autoloader constructor.  */  protected function __construct(){  spl_autoload_register([$this, 'load']);  }   /**  * Register namespace root path  *  * @param $namespace Root namespace  * @param $root_path Namespace root path  */  public function addNamspacePath($namespace, $root_path){  self::$ns_map[$namespace] = $root_path;  }   /**  * Load class  *  * @param $classname Loader method  */  public function load($classname){  if($path = $this->getClassPath($classname) ){  require_once $path;  }  }   /**  * Get realpath to the class definition file  */  protected function getClassPath($classname){  $class_path = $classname . '.php';  if( !empty(self::$ns_map) ){  foreach(self::$ns_map as $ns => $path){  $lookup_pattern = sprintf('/^%s/', $ns);  if(preg_match($lookup_pattern, $classname)){  $class_path = preg_replace($lookup_pattern, $path, $class_path);  break;  }  }  }   return realpath(str_replace('\', '/', $class_path));  }   /**  * Get loader instance  */  public static function getInstance(){  if(null === self::$instance){  self::$instance = new self;  }   return self::$instance;  }   private function __clone(){}  private function __wakeup(){} }  return Autoloader::getInstance(); 

Ниже также приведём пример использования данного автозагрузчика в коде приложения:

 ... $loader = require_once '../classes/Autoloader.php'; $loader->addNamspacePath('MyClasses', __DIR__ . '/../vendor/dimmask/myclasses/'); ... $my = new MyClassesUtilitiesMyClass(); // Этот класс будет загружен автоматически ... 

Ниже предлагается краткий обзор назначения методов вышеописанного класса Autoloader. Класс использует паттерн «одиночка», почему именно так? Каждый раз, когда создаётся новый экземпляр класса, его метод load() будет зарегистрирован как автозагрузчик. Нам нет необходимости регистрировать одну и ту же функцию как загрузчик несколько раз, потому мы таким образом закрываем эту возможность.

Свойство / Метод Описание
 __construct Конструктор класса. Именно в нём производится регистрация метода load из этого же класса, как функции-загрузчика.
 addNamspacePath

$namespace
$rootpath

Регистрирует в маппинге корневой путь $root_path для загрузки классов пространства $namespace.
 load

$classname

Непосредственно сам метод-загрузчик, который пытается подгрузить класс по переданному в $classname полному имени.
 getClassPath

$classname

Вычисляет и возвращает полный путь к файлу, в котором согласно соглашениям PSR-0, должно находится описание класса $classname.
 getInstance Возвращает новый экземпляр класса Autoloader или уже существующий, если он уже был ранее создан.
 __clone Метод «зарублен» чтобы исключить возможность клонирования экземпляров класса Autoloader.
 __wakeup Метод «зарублен» чтобы исключить возможность клонирования экземпляров класса Autoloader при десериализации.

Использование загрузчика Composer

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

Composer — это менеджер таких пакетов. Он позволяет управлять пакетами а также их зависимостями. Кроме того, composer имеет собственные средства для автозагрузки классов, описанных в этих подключаемых библиотеках но не только. Ниже описан пример того, как можно спользовать загрузчик composer для загрузки «собственных» классов приложения.

Для реализации нашего плана, прежде всего нужно установить сам composer. Это можно сделать несколькими способами. Не буду описывать здесь весь процесс установки composer, найти эту информацию можно здесь: https://getcomposer.org/doc/00-intro.md. Итак, предположим, что композер уже установлен. Переходим в консоли в папку с проектом, где находятся наши /public и /classes. Далее — в папке выполним команду инициализации проекта composer:

$ composer init

После чего в интерактивном режиме composer запросит у нас название пакета, зависимости и прочие параметры. Опять же, не буду описывать весь этот процесс, т.к. нам интересно другое. Завершив процесс ининциации проекта (можно согласится на все предложенные варианты по умолчанию), мы увидим в корне файл — composer.json

Далее необходимо запустить команду установки пакетов. Даже если на этапе инициализации проекта вы не указали ни одной зависимости, это нужно сделать. Т.к. должен быть установлен пакет composer, который важен для нашего эксперимернта. Выполним в консоли команду:

$ composer install

В случае с composer, сделать это мы можем в нашем index.php, например так:

 ... $loader = require_once "../vendor/autoload.php"; // Регистрируем путь к пространству имён $loader->addPsr4('MyClasses\', __DIR__ . '/../classes/');  $mc = new MyClassesUtilitiesMyClass(); // И этот класс будет загружен загрузчиком composer. ... 

Как видим, пример с composer очень похож в использовании на пример из предыдущего параграфа, с той разницей, что нам не пришлось писать сам класс загрузчика.

Немного другой вариант

Есть ещё один вариант, как заставить composer загружать классы из нашего приложения. Откроем файл composer.json в корне проекта и добавим в него секцию autoload. Вот как здесь к примеру:

 {  "name": "dimmask/myproject",  "authors": [  {  "name": "dimmask",  "email": "dimmask@gmail.com"  }  ],  "autoload": {  "psr-4": {  "MyClasses\": "classes/"  }  },  "require": {} } 

Сохраняем и выполняем в консоли команду:

$ composer dump-autoload

После чего composer Добавит указанные нами пространства имён в свою карту загрузки и как результат, нам не нужно будет регистрировать их в коде вручную. Таким образом, код нашего файла index.php становится ещё немного «легче»:

 ... require_once "../vendor/autoload.php";  $mc = new MyClassesUtilitiesMyClass(); // Класс будет загружен загрузчиком composer. ... 

Вывод:
Как видим, для более-менее масштабных проектов, где есть резон использовать composer, довольно удобно пользоваться встроенным автозагрузчиком. Тем более, что это не требует написания значительного объёма кода.

dof.in.ua

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

Этот метод актуален только для объектно-ориентированного стиля программирования, и будет работать в версии PHP 5.1.2 и выше.

Давайте рассмотрим пример. Имеем два файла:

Файл example.php:

<?php  class example {   static function call() {   echo 'You call "' . __CLASS__ . '" class.';   }  }  ?>

Файл index.php:

<?php   include 'example.php';   example::call();  ?>

Оба файла находятся в одной директории. В первом файле example.php объявлен класс example. Во втором файле мы подключаем example.php и вызываем метод call класса example. Метод call является статическим, поэтому нам не обязательно создавать экземпляр класса example для его вызова.

Результатом выполнения этого скрипта будет сообщение «You call "example" class.»

Для использования класса example, нам нужно было подгрузить соответствующий файл — example.php.

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

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

Модифицируем предыдущий пример:

Файл autoload.php:

<?php  spl_autoload_register ('autoload');  function autoload ($className) {   $fileName = $className . '.php';   include $fileName;   }  ?>

Файл example.php:

<?php   class example {   static function call() {   echo 'You call "' . __CLASS__ . '" class.';   }   }  ?>

Файл index.php:

<?php   include 'autoload.php';   example::call();  ?>

Мы добавили новый файл autoload.php и подгрузили его в index.php. Обратите внимание — мы все также вызываем example::call(), и вместо «Fatal error: Class "example" not found in …» получаем прежний результат — «You call "example" class.». Даже без ручной подгрузки файла example.php, класс example нашелся и его метод вызвался. Как так получилось?

PHP позволяет задать обработчик (функцию или метод класса) который будет вызываться всякий раз при обращении к классу, который еще не определен. Аргументом функции-обработчика является имя вызываемого класса. Обработчик мы определяем с помощью функции spl_autoload_register(). Если в качестве обработчика выступает функция, то аргументом spl_autoload_register() будет являться строка с именем функции (как в примере). Если же в качестве обработчика выступает метод класса, то аргументом spl_autoload_register() будет являться массив, первый элемент которого соответствует названию класса, а второй названию метода этого класса — spl_autoload_register(array('someoneClass', 'someoneMethod')). Метод-обработчик должен быть статическим.

В нашем примере, в качестве обработчика я использовал функцию autoload(). К имени вызываемого класса она добавляет расширение «.php» и пытается подгрузить файл <class>.php, где <class> — имя вызываемого класса.

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

www.codeisart.ru

Как работает __autoload()?

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

Как я храню классы в битриксе

Основной директорией для хранения классов у меня является /local/classes.
Если класс не содержится в пространстве имен, то он лежит прям тут. Имя файла соответствует имени класса, имя класса должно начинаться с заглавной буквы, а слово должно быть написано в CamelCase нотации (например GoogleAdwords, ZhurovMe и т.д, т.е. каждое новое слово в словосочетании начинается с большой буквы, между словами нет пробелов). В каждом файле описан только один класс. Если класс использует пространство имен, то нужно транслировать пространство имен на директории внутри /local/classes
Например, есть класс MySuperPuperDuperClass.
Для такого класса создаем файл по адресу:
/local/classes/My/Super/Puper/Duper/Class.php
Наименование корневого простраства имет, как правило, соответствует имени автора этого класса (читай — вендора). В моем случае пускай это будет Zhurov. Или если вы работаете в компании с названием Boogle, то именно с этого пространства имен имеет смысл назвать свой класс. Тогда получится /local/classes/Boogle/Super/Puper/Duper/Class.php

Соблюдение подобной структуры позволяет использовать функцию __autoload() примерно следующего содержания:

Т.е. по коду мы видим, что функция принимает на вход параметр $className. Определяем, содержит ли имя класса пространства имен (по символу ‘’). Если есть — заменяем их на ‘/’ и ищем файл с названием {$className}.php в указанной директории. Если же неймспейса нет, то просто пытаемся подключить файл из этой директории.

Все так просто, что просто ужас. Это работает, и вам не нужно писать на каждый свой класс отдельный include/require

spl_autoload_register()

Ну в __autoload есть одна, и очень значительная проблема. Ее можно определить только в единственном экземпляре! Т.е. все библиотеки сторонних разработчиков, которые вы хотите использовать в своем проекте, придется либо перестраивать под ваш autoload, либо не использовать для них autoload, а это опять гора инклюдов ..
Еще круче будет, если внутри библиотеки разработчик сам определяет свою функцию __autoload() и тогда у вашего проекта будет с библиотекой конфликт.

Поэтому в php5.1 выходит специальная функция — spl_autoload_register(). Можете теперь написать сколь угодно много функций с разными именами, и зарегистрировать каждую из них в качестве автолоадера! Круто? Еще бы!
Адаптируя предыдущий пример — получим следующее:

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

Есть еще несколько функций с приставкой spl_autoload*, но их изучение предлагаю сделать вам в качетсве домашки. Особое внимание стоит обратить на spl_autoload — эта функция уже является реализацией автолоадера по умолчанию. Т.е. если у вас не определены ваши кастомные автолоадеры, то будет вызвана функция spl_autoload, которая попытается найти и подключить файл с нужным классом. А вот как она ищет класс предлагаю выяснить самостоятельно.

zhurov.me

Всем привет. В этой статье я расскажу про автоматическое подключение файлов в php с помощью spl_autoload.

На сайте уже была статья про магический метод __autoload, который делал то же самое, однако из-за своих недостатков он достаточно быстро устарел. А на смену ему пришла функция spl_autoload. Вот давайте о ней и поговорим.

Внутрь функции spl_autoload_register вы можете передать анонимную, или лямбда функцию, которая будет что-то делать, например, подключать файлы.

<?php
  spl_autoload_register(function($name) {
   require 'classes/'.$name.'.php';
  });
?>

Также, вы можете вынести эту функцию отдельно, а в spl_autoload_register передать строковое значение с названием вашей функции.

<?php
  function autoLoader($name) {
   require 'classes/'.$name.'.php';
  }

  spl_autoload_register('autoLoader');
?>

С помощью spl_autoload_extensions вы можете указать значения расширений по-умолчанию для функции spl_autoload.

spl_autoload_extensions('.php');
spl_autoload_register();

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

spl_autoload_extensions('.php, .php4, .php3, .class.php');

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

spl_autoload_register('autoLoader1');
spl_autoload_register('autoLoader2');

Если вы хотите посмотреть все зарегистрированные функции, то вы можете воспользоваться функцией spl_autoload_functions, которая возвращает массив.

print_r(spl_autoload_functions());

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

spl_autoload_unregister('autoLoader1');

Вот и все, что нужно знать об этой возможности. Используйте именно этот автозагрузчик, а не магический метод __autoload(), потому что spl_autoload более гибок и новее. Спасибо за внимание и удачного кодинга!

myrusakov.ru

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() вам не нужно реализовывать функцию автозагрузки в каждом __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, когда вы попытаетесь создать новый класс.

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

qaru.site

Editorial note: The appropriate PHP bug that requests behavior this function emulates is http://bugs.php.net/bug.php?id=42823 . This function does NOT work if there has been an array($obj, 'nonStaticMethod') registered in the autoload stack--while the autoload will be removed, it will be re-registered incorrectly.

The spl_autoload_register() method registers functions in its stack in the order that spl_autoload_register() was called, and subsequently if you want an autoload function to override previous autoload functions you will either need to unregister the previous ones or change the order of the autoload stack.

For example, say in your default implementation of an autoload function you throw an exception if the class cannot be found, or perhaps a fatal error.  Later on in your code you add a second implementation of an autoload function which will load a library that the previous method would fail on.  This will not call the second autoloader method first, but rather will continue to error out on the first method.

As previously mentioned, you can unregister the existing autoloader that errors out, or you can create a mechanism for unregistering and re-registering the autoloaders in the order you want.

Here is a sample/example of how you might consider re-registering autoloaders so that the newest autoloader is called first, and the oldest last:

<?php

// Editorial notes: Small bug and compatibility fixes
// added to the function

function spl_autoload_preregister( $autoload ) {
   
// No functions currently in the stack.
   
if ( ($funcs = spl_autoload_functions()) === false ) {
       
spl_autoload_register($autoload);
    } else {
       
// Unregister existing autoloaders...
       
$compat =
           
version_compare(PHP_VERSION, '5.1.2', '<=') &&
           
version_compare(PHP_VERSION, '5.1.0', '>=');
        foreach (
$funcs as $func) {
            if (
is_array($func)) {
               
// :TRICKY: There are some compatibility issues and some
                // places where we need to error out
               
$reflector = new ReflectionMethod($func[0], $func[1]);
                if (!
$reflector->isStatic()) {
                    throw new
Exception('
                        This function is not compatible
                        with non-static object methods due to PHP Bug #44144.
                    '
);
                }
               
// Suprisingly, spl_autoload_register supports the
                // Class::staticMethod callback format, although call_user_func doesn't
               
if ($compat) $func = implode('::', $func);
            }
           
spl_autoload_unregister($func);
        }
       
       
// Register the new one, thus putting it at the front of the stack...
       
spl_autoload_register($autoload);
       
       
// Now, go back and re-register all of our old ones.
       
foreach ($funcs as $func) {
           
spl_autoload_register($func);
        }
    }
}

?>

Note: I have not tested this for overhead, so I am not 100% sure what the performance implication of the above example are.

php.net


You May Also Like

About the Author: admind

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *

Этот сайт использует Akismet для борьбы со спамом. Узнайте как обрабатываются ваши данные комментариев.