Comments 20
А зачем это нужно? Вы что, не знаете, где лежат ваши файлы? В исходниках порядок должен быть, все файлы на своих местах. К тому же при использовании подобных методов наверняка снижается производительность. А для поиска файлов есть куча стандартных инструментов.
я знаю где лежат мои файлы, но, когда файлов очень много, делать десяток два requre_once() в заголовке каждого файла излишне, проще один раз подключить файл с автозагрузчиком, тем более, что он, в случае правильного указания директории с классами сделает это очень быстро, за одну-две итерации.
Просто из за прироста скорости, __autoload + require сильно быстрее require_once
Использую принцип DDD, название класса соответствует его расположению относительно директории классов, к примеру класс Sega_Mega_Drive лежит в Sega/Mega/Drive.php, все четко и понятно, ничего не надо искать. В случае, если класс не найден по такому адресу, ищется в include_path.
Именно!
<?php
class Vp_Autoloader
{
public static $loader;
public static function init()
{
if (self::$loader == NULL)
self::$loader = new self();
return self::$loader;
}
public function __construct()
{
spl_autoload_register(array($this, 'controller'));
}
public function controller($className)
{
$className = preg_replace('#_#', '\\', $className);
set_include_path(PROJECT_ROOT);
spl_autoload_extensions('.php');
spl_autoload($className);
}
}
Аналогичная схема используется в Zend Framework.
Стоит, наверное, заметить, что file_exists довольно-таки дорогая операция; как, впрочем, и другие файловые операции. Если у вас есть достаточно сложный проект с этим автолоадером, попробуйте посмотреть отчёт профайлера. Особенно заметны потери становятся при использовании акселератора (кеша байткода), например APC.
С целью оптимизации, если логика загрузки классов сложная, на этапе запуска проекта создается карта классов (ассоциативный массив вида «класс => имя файла»), которая подгружается в и используется автолоадере, вместо сложной логики, основанной на фалйовой системе. Она полностью кешируется акселератором и исключает поиск на диске во время работы проекта.
С целью оптимизации, если логика загрузки классов сложная, на этапе запуска проекта создается карта классов (ассоциативный массив вида «класс => имя файла»), которая подгружается в и используется автолоадере, вместо сложной логики, основанной на фалйовой системе. Она полностью кешируется акселератором и исключает поиск на диске во время работы проекта.
function __autoload($classname){
include_once ('include/classes/'.$classname.'.php');
}
Этого достаточно
товарищи говнокодеры, есть стандарт названия классов, где namespace совпадает с путем к файлу, а подчеркивания — заменяются на спуск на одну папку вниз.
он описан тут:
github.com/php-fig/fig-standards/blob/master/accepted/PSR-0.md
автолоадер состоят из 15 строк. более сложный вариант тут:
github.com/symfony/ClassLoader
он описан тут:
github.com/php-fig/fig-standards/blob/master/accepted/PSR-0.md
автолоадер состоят из 15 строк. более сложный вариант тут:
github.com/symfony/ClassLoader
spl_autoload_register(create_function('$class', '
$path = \'' . dirname(__FILE__) . '/../\' . strtr($class, "_", "/") . ".php";
is_file($path) && require_once $path;
'));
Вот такая вот поделка в файле "_autoload.php", который валяется в той же директории, в которой находится иерархия классов a-la Zend, но без префикса (т.е. для файла "/classes/_autoload.php" и класса Some_Foobar_Class оно попытается подключить "/classes/Some/Foobar/Class.php").
Есть вариант посложнее:
class Framework_Autoloader
{
static function autoload($className)
{
$length = strrpos(__CLASS__, '_');
if (!strncasecmp(__CLASS__, $className, $length + 1)) {
$classFile = dirname(__FILE__) . strtr(substr($className, $length), '_', '/') . '.php';
if (is_file($classFile)) {
require_once $classFile;
return;
}
}
}
}
spl_autoload_register(array('Framework_Autoloader', 'autoload'));
Оно считает, что все классы с некоторым префиксом (в данном случае «Framework_»; например, если класс автозагрузчика называется «Some_Class_Autoloader», то префикс будет «Some_Class_» — правда, нет случая «без префикса») расположены по тем же правилам Zend (звиняйте, точно не знаю, откуда пошла такая мода — заменять подчеркивания на слешы, мб и PEAR постарался) в директории, в которой находится, собссно, класс автозагрузчика. Пример: есть файл "/classes/mylib/Autoloader.php", в котором объявлен данный автозагрузчик. При его подключении файл класса «Some_Strange_Class» загружен не будет, ибо префикса «Framework_» у него нет, а файл класса «Framework_Request_File» будет искаться по пути "/classes/mylib/Request/File.php".
На каждую задачу обычно свой автозагрузчик пишется (^_^)' Последнее время колдовал над системой a-la Bundle у Symfony 2, и там, есессено, все было по-другому и гораздо сложнее. Система, кстати, не прижилась — уж шибко много и сложно писать приходилось, хоть и правильно с технической точки зрения.
P.S. Дабы избежать недоразумений — все файлы, в которых объявлены автозагрузчики, нужно подключать вручную (через require_once, например) — положить их рядом с файлами классов недостаточно. Я, конечно, понимаю, что тут люди знающие, но на всякий пожарный лучше все-таки предотвратить безуспешные попытки сотворить магию (^_^) Новички ведь тоже сюда ходят, так же, как и мы когда-то, учатся и так же делают глупые (для нас, но не для них) ошибки.
Sign up to leave a comment.
Универсальный класс автозагрузки