Search
Write a publication
Pull to refresh

Comments 20

А зачем это нужно? Вы что, не знаете, где лежат ваши файлы? В исходниках порядок должен быть, все файлы на своих местах. К тому же при использовании подобных методов наверняка снижается производительность. А для поиска файлов есть куча стандартных инструментов.
я знаю где лежат мои файлы, но, когда файлов очень много, делать десяток два requre_once() в заголовке каждого файла излишне, проще один раз подключить файл с автозагрузчиком, тем более, что он, в случае правильного указания директории с классами сделает это очень быстро, за одну-две итерации.
Думаю, Riateche не предлагал использовать requre_once() везде. Если знаем где файлы, не нужно их искать. При первом обращении к классу автоматом грузим автоматом.
Просто из за прироста скорости, __autoload + require сильно быстрее require_once
ох щи,
во первых, spl_autoload_register
во вторых я сначала подумал что автор реализовывает обычный автолоадер. А тут рекурсивный поиск (!)
Чото да, теперь и мне не понятно зачем это.
ничем, вы что-то не так поняли в моем комментарии
Наоборот, он хорош и лучше чем куча 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);
    }
}
Да, примерно такой же Autoloader у меня, коротко и понятно.
Аналогичная схема используется в 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
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, например) — положить их рядом с файлами классов недостаточно. Я, конечно, понимаю, что тут люди знающие, но на всякий пожарный лучше все-таки предотвратить безуспешные попытки сотворить магию (^_^) Новички ведь тоже сюда ходят, так же, как и мы когда-то, учатся и так же делают глупые (для нас, но не для них) ошибки.
UFO landed and left these words here
UFO landed and left these words here
Sign up to leave a comment.

Articles