Skip to content

Conversation

AlexeyDsov
Copy link
Member

Взялся немножко исправить автолоадер и в итоге захотел переписать больше чем изначально планировал.

Список изменений примерно таков:

  1. Автолоадеры разделены на отдельные классы. Теперь они не статические и создаются через new или статический вызов create. Не кеширующий автолоадер называется AutoloaderNoCache, кэширующий пути к классам AutoloaderClassPathCache, полностью кэширующий все классы в один файл был удален, т.к. в случае неймспейсов в таком виде его использовать нельзя + подозреваю что его никто действительно не использовал.
  2. Автолоадеры теперь не используют (get|set)_include_path. Вместо этого каждому автолоадеру сетиться набор директорий в которых нужно искать классы.
  3. В случае вызова методов class_exists, interface_exists, trait_exists теперь не выкидывается ошибка ClassNotFoundException. Взамен этого они корректно возвращают true/false. Реализовано эта фича за счет специально AutoloaderClassNotFound оказывающегося в конец стэка spl_autoloader'ов и бросающим/небросающим ошибку в зависимости а trace'а.
  4. Что бы корректно включить какой-либо автолоадер в стэк spl_autoloader'ов необходимо вызвать у него метод register.
  5. В случае подключения внешних автолоадеров желательно затем AutoloaderClassNotFound::me()->register(); Это перенесет его вызов AutoloaderClassNotFound в самый конец стэка spl_autoloader'ов.
  6. AutoloaderNoCache и AutoloaderClassPathCache используют (необходимо им засетить) классы NamespaceResolver(OnPHP|PSR0). Это что-то вроде задела на будуйщее и для тех кто вдруг уже захотел использовать неймспейсы в каком-то виде в своем проекте.
    • NamespaceResolverOnPHP не используют никак иерархию папок, каждый директория задается ему отдельно вместе с неймспейсом для нее
    • NamespaceResolverPSR0 ведет себя похоже на PSR-0 за исключением:
      1. По умолчанию постфиксом файла класса считается .class.php вместо .php, но его можно переназначать на любой желаемый.
    • В случае использования AutoloaderClassPathCache и кэширования путей до классов разницы в производительности между двумя NamespaceResolver'ами впринципе нету. В обоих случаях они один раз возвращают путь до файлов, он кэшируется и больше их не спрашивают ни о чем, пока не встретиться незнакомый класс.
  7. В ходе экспериментов получилось что удобно сделать статический класс для хранения onPHP автолоадеров - AutoloaderPool с методами set, get, drop. Дефолтный автолоадер используемый в onPHP достается через него так: AutoloaderPool::get('onPHP')
  8. Так же в AutoloaderPool был добавлен дополнительный функционал, для регистрации автолоадеров со способностью кэширования для вызова их со сбрасыванием кэша.

Что ломается/нужно переделывать в своих проектах:

  1. Если кто-то оборачивал class_exists, inteface_exists, trait_exists try/catch/ClassNotFoundException - теперь такой ошибки бросаться не будет.
  2. Если кто-то использовать Assert::classExists, то сейчас он бросает WrongArgumentException вместо ClassNotFoundException. Тут можно оставить что б бросался ClassNotFoundException. Не могу сказать как оно должно быть правильней.
  3. Заменить set_include_path конструкцию на AutoloaderPool::get('onPHP')->addPaths(array(..., ...)); либо на использование своего автолоадера.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

и нормально берется константа из интерфейса? не знал ....

@AlexeyDsov
Copy link
Member Author

Добавил коммит по комментариям выше.

@AlexeyDsov
Copy link
Member Author

Ну что же устраивают всех эти изменения или есть еще какие-то корректировки?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Хоть оно в coding style и не вынесено, но по остальному коду перенос в цепочке вызовов оформляется по другому

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ближе к вечеру поправлю

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Готово

@crazedr0m
Copy link
Contributor

в п. 2, который "Взамен этому каждому автолоадеру можно засетить набор директорий в которых нужно искать классы."
можно засетить или нужно ?

@AlexeyDsov
Copy link
Member Author

@crazedr0m

Вместо этого каждому автолоадеру сетиться набор директорий в которых нужно искать классы.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

coding style

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fix

@crazedr0m
Copy link
Contributor

а каким образом это можно вмерждить себе локально чтобы "пощупать" ?

@AlexeyDsov
Copy link
Member Author

cd /blah/blah/.../blah/onPHP
git remote add alexeydsov git://github.com/AlexeyDsov/onphp-framework.git
git remote update
git checkout -b autoloaderExp -t alexeydsov/autoloaderExp

@crazedr0m
Copy link
Contributor

ну да, вариант ) спасибо.

@crazedr0m
Copy link
Contributor

ну в общем

sh test/runme.sh
Trying to load onPHP extension.. failed.
PHP Fatal error: Can't inherit abstract function Autoloader::autoload() (previously declared abstract in AutoloaderRecachable) in /home/giv/www/onphp-giv/main/Autoloader/AutoloaderRecachable.class.php on line 13

php -v
PHP 5.3.5-1ubuntu7.10 with Suhosin-Patch (cli) (built: Jun 19 2012 00:54:05)
Copyright (c) 1997-2009 The PHP Group
Zend Engine v2.3.0, Copyright (c) 1998-2010 Zend Technologies
with Xdebug v2.1.0, Copyright (c) 2002-2010, by Derick Rethans

Похоже из-за того что в AutoloaderRecachable::autoload() добавляется параметр, которого нет в родителе

@AlexeyDsov
Copy link
Member Author

В интерфейсе Autoloader метод объявлен как

public function autoload($className);

А в интерфейсе AutoloaderRecachable extends Autoloader объявлен как

public function autoload($className, $recache = false);

5.4 видно считает что все впорядке вещей, а 5.3 с таким обращением с интерфейсами не согласен.

надо будет значит по другому как-то переписать

@crazedr0m
Copy link
Contributor

вот и я про то же. ждем.

@AlexeyDsov
Copy link
Member Author

Фикс прибыл, пробуйте.

@crazedr0m
Copy link
Contributor

c 5.3 заработало. На дальнейшее тестирование пока не было времени (

@AlexeyDsov
Copy link
Member Author

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

@ghost ghost assigned AlexeyDsov Oct 24, 2012
AlexeyDsov added a commit that referenced this pull request Oct 24, 2012
New Autoloader which work without include_paths and with optional namespace support
@AlexeyDsov AlexeyDsov merged commit c4a49e4 into onPHP:master Oct 24, 2012
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants