• База знаний
  • /
  • Блог
  • /
+380 (44) 364 05 71

Давайте поговорим про автоматическую загрузку классов в PHP. Многие не знают о том что она вообще есть, хотя появилась такая возможность еще в первых версиях php 5 и называется она __autoload().

Этот магическая функция предназначена для того чтоб избавить нас от бесконечных include и require в коде сайта. Функция вызывается каждый раз, во время создания объекта или обращения к экземпляру класса. Но данный метод имеет ряд недостатков, а именно:
- после объявления этой функции нет возможности ее деактивировать или видоизменить
- нельзя объявить несколько разных загрузчиков

Для решения этих проблем в PHP 5.1.2 появился ряд SPL функций.

  • spl_autoload_call — принудительно загружает класс по его имени, используя все доступные в системе автозагрузчики;
  • spl_autoload_extensions — возвращает/модифицирует расширения файлов, из которых происходит загрузка неинициализированных классов;
  • spl_autoload_functions — возвращает список всех зарегистрированных автозагрузчиков в системе;
  • spl_autoload_register — регистрация собственного автозагрузчика в стеке автозагрузки;
  • spl_autoload_unregister — удаление автозагрузчика из стека автозагрузки;
  • spl_autoload — основная функция автоматической загрузки классов. Именно она вызывается при обращении к классу, который еще не инициализирован. Данная функция активирует все автоматические загрузчики из стека в порядке их добавления.

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

Объявить автозагрузчик можно следующим образом:

function autoloader($class){
     require_once 'classes/' . $class . '.php';
}
spl_autoload_register('autoloader');

Либо, начиная с php 5.3.0 с использованием безымянных функций
spl_autoload_register(function ($class) {
     require_once 'classes/' . $class . '.php';
});

К примеру, если будет зарегистрировано два автозагрузчика:
spl_autoload_register('autoloader1');
spl_autoload_register('autoloader2');

Последовательность обращения к ним во время вызова класса будет следующая:
autoloader1($class)
autoloader2($class)

В PHP 5.3.0 добавлено несколько очень полезных возможностей для работы с автозагрузчиками
1. Третий параметр функции spl_autoload_register() - $prepend. Он позволяет переместить ново-добавленный автозагрузчик в начало стека загрузки. То есть:

spl_autoload_register('autoloader1');
spl_autoload_register('autoloader2',true,true);

Приведет к тому что будет изменен порядок вызова автозагрузчиков на следующий:
autoloader2($class)
autoloader1($class)

2. Работа с namespace в качестве путей для расположения класса. К примеру:

function autoloader1($class){
     include_once $class.”.php”;
}
spl_autoload_register('autoloader1');
use test\systems\user as user;
$usr = new
user();

Приведет к попытке подключения класса, расположенного по пути test/systems/users.php

Но будьте внимательны, при использовании такой методики подключения классов. По неизвестной причине, при преобразовании namespace в адрес расположения нужного Вам класса, путь приводится к нижнему регистру. В результате test\Systems\User будет преобразовано в test/systems/user. Если расположение на файловой системе файла у Вас выглядит как test/Systems/User, ОС не найдет нужный файл, поскольку *NIX чувствительна к регистру в файловой системе.

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

Например:
$classMap=array(
     “class1”=>”system/site/”,
     “classs2”=>”user/lib/”,
);

Для гибкости целесообразно выносить карту классов в отдельный файл. Это даст возможность генерировать ее при помощи дополнительного ПО, либо заметить, на этапе тестирования. Сделать это можно к примеру так:

function autoloader1($class){
     include_once “classMap.php”;
     include_once $classMap[$class].$class.”.php”;
}

Дата: 14.10.2013
Автор: Евгений Шерман
Голосование

Авторам статьи важно Ваше мнение. Будем рады его обсудить с Вами:

comments powered by Disqus
Спасибо, что выбираете FREEhost.UA