Прежде чем начать, пожалуйста, обратите внимание на мой собственный блог: www.leoyang90.cn
Эта статья представляет собой краткое описание функции автоматической загрузки PHP, включая функцию автоматической загрузки PHP, пространство имен PHP, стандарты PHP PSR0 и PSR4 и т.д.
Происхождение функции автоматической загрузки PHP
В разработке PHP, если вы хотите ввести класс извне, вы обычно используете методы include и require для включения файлов, определяющих класс. Это не большая проблема в маломасштабном развитии. Но в крупномасштабных проектах разработки использование этого подхода может привести к некоторым скрытым проблемам: если файл PHP должен использовать много других классов, то ему требуется множество инструкций require/include, которые могут привести к пропускам или включать ненужные файлы классов. Если большому количеству файлов необходимо использовать другие классы, должно быть кошмаром убедиться, что каждый файл содержит правильные файлы классов, а require_once стоит дорого.
PHP5 предоставляет решение этой проблемы, которое представляет собой механизм автоматической загрузки класса. Механизм автоматической загрузки позволяет программам PHP автоматически включать файлы классов при использовании классов вместо включения всех файлов классов с самого начала. Этот механизм также называется ленивой загрузкой.
Таким образом, функция автоматической загрузки дает несколько преимуществ:
Нет необходимости включать или требовать перед использованием классов
Файлы Require/include используются только при использовании классов, что обеспечивает замедленную загрузку и позволяет избежать необходимости/включения избыточных файлов.
Без учета фактического адреса диска введенного класса реализовано разделение логических и сущностных файлов.
Если вы хотите узнать больше о функции автоматической загрузки, вы можете ознакомиться с информацией: Реализация механизма автоматической загрузки класса PHP и анализ механизма автоматической загрузки в PHP
Функция автоматической загрузки PHP _autoload()
Обычно, когда PHP5 использует класс, если обнаруживается, что класс не загружен, он автоматически запускает функцию _autoload (), которая настроена в нашей программе, в которой мы можем загружать классы, которые нам нужны для использования. Вот простой пример:
function __autoload($classname) { require_once ($classname . "class.php"); }
В нашем простом примере мы просто добавляем имя класса с расширением “. class. php” , чтобы сформировать имя файла класса, а затем использовать require_once для его загрузки. Из этого примера мы видим, что для автоматической загрузки необходимо выполнить по крайней мере три задачи:
Имя файла класса определяется в соответствии с именем класса.
Определите путь к диску, на котором расположены файлы классов (в нашем простейшем случае классы находятся в той же папке, что и программные файлы PHP, которые их вызывают).;
Загружайте классы из файлов на диске в систему.
Третий шаг самый простой, просто используйте include/require. Чтобы выполнить первый и второй шаги, мы должны согласовать метод сопоставления имени класса и файла на диске во время разработки. Только таким образом мы сможем найти соответствующий файл на диске в соответствии с именем класса.
Когда требуется включить большое количество файлов классов, мы можем добиться отложенной загрузки только путем определения соответствующих правил, а затем в функции _autoload() сопоставить имя класса с фактическим файлом на диске. Из этого мы также можем видеть, что наиболее важной реализацией функции _autoload() является реализация правил сопоставления имен классов и фактических файлов на диске.
_ проблемы в функции автоматической загрузки ()
Если при реализации системы требуется много других библиотек классов, они могут быть написаны разными разработчиками, имена классов которых отличаются от фактических правил сопоставления файлов на диске. В настоящее время, если мы хотим реализовать автоматическую загрузку файлов библиотеки классов, мы должны реализовать все правила сопоставления в функции _autoload (), чтобы функция autoload () могла быть очень сложной или даже невозможной для реализации. В конечном итоге функция автоматической загрузки () может стать очень громоздкой, и даже если ее удастся реализовать в настоящее время, это окажет большое негативное влияние на будущее техническое обслуживание и эффективность системы.
Так в чем же возникает проблема? Проблема в том, что _autoload () – это глобальная функция, которая может быть определена только один раз и недостаточно гибка, поэтому все логические правила, соответствующие именам классов и имен файлов, должны быть реализованы в одной функции, что приводит к раздутым функциям. Так как же решить эту проблему? Ответ состоит в том, чтобы использовать стек вызовов _autoload, записать различные отношения сопоставления в различные функции _autoload, а затем унифицировать регистрацию и единое управление, что является автоматической загрузкой SPL, введенной PHP5.
Автоматическая загрузка SPL
SPL-это аббревиатура стандартной библиотеки PHP. Это библиотека расширений, представленная PHP 5. Его основные функции включают реализацию механизма автоматической загрузки и различные интерфейсы или классы итераторов. Автоматическая загрузка SPL имеет несколько функций:
Spl_autoload_регистр: Зарегистрируйте функцию _autoload()
Spl_autoload_unregister: Отзыв зарегистрированных функций
Spl_autoload_functions: Возвращает все зарегистрированные функции
Spl_autoload_call: Попробуйте все зарегистрированные функции для загрузки классов
Реализация spl_autoload по умолчанию:_autoload()
Spl_autoload_extensions: Зарегистрируйте и верните расширение файла по умолчанию, используемое функцией spl_autoload.
Подробное использование этих функций можно подробно увидеть в spl_autoload в PHP
Проще говоря, spl_autoload-это собственное определение функции _autoload() SPL, которое очень просто, то есть нужно перейти в зарегистрированный каталог (настройки set_include_path), чтобы найти то же имя, что и $classname. php/. Файл Inc. Конечно, вы также можете указать конкретные типы файлов, зарегистрировав расширения (spl_autoload_extensions).
И spl_autoload_register () – это стек вызовов автоматической загрузки, о котором мы упоминали выше. Мы можем зарегистрировать многие из наших собственных функций _autoload() в этой функции. Когда PHP не может найти имя класса, PHP вызовет этот стек, один за другим, чтобы вызвать пользовательскую функцию _autoload() для реализации функции автоматической загрузки. Если мы не вводим никаких параметров в эту функцию, мы регистрируем функцию spl_autoload ().
Ну, это нижний уровень автоматической загрузки PHP. Механизм регистрации уже очень гибкий, но чего не хватает? Как мы уже говорили выше, ключом к автоматической загрузке является сопоставление имен классов и файлов. Разные фреймворки имеют разные методы отображения, которые очень гибки, но слишком гибкая будет сбивать с толку. PHP имеет специальную спецификацию для этого отношения сопоставления, то есть PSR 0 и PSR 4 в стандарте PSR.
Но прежде чем мы поговорим о PSR0 и PSR4, нам нужно понять проблему пространств имен в PHP, потому что эти два стандарта на самом деле направлены не на сопоставление имен классов с файлами каталогов, а на сопоставление пространств имен с файлами. Почему? В моем понимании, стандартная объектно-ориентированная идея PHP, пространство имен в некоторой степени является псевдонимом для имен классов, так зачем вводить пространства имен, в чем преимущества пространств имен?
Чтобы понять пространства имен, сначала посмотрите на введение пространств имен в официальные документы:
Что такое пространство имен? В широком смысле пространства имен-это способ инкапсуляции вещей. Это абстрактное понятие можно увидеть во многих местах. Например, в операционной системе каталог используется для группировки связанных файлов. Для файлов в каталоге он действует как пространство имен. Например, файл foo. TXT может существовать в каталогах/home/Greg и/home/other одновременно, но два foo. файлы txt не могут существовать в одном каталоге. Кроме того, при доступе к foo. файлы txt вне каталога/home/greg, мы должны поставить имя каталога и разделитель каталогов перед именем файла, чтобы получить/home/Greg/foo. txt. Применение этого принципа к области программирования – концепция пространств имен. В PHP пространства имен используются для решения двух типов проблем, возникающих при создании повторно используемого кода, такого как классы или функции, при написании библиотек классов или приложений: 1 Конфликты имен между написанным пользователем кодом и классами/функциями/константами или сторонними классами/функциями/
Проще говоря, PHP не допускает в программе два класса, функции или имена переменных с одинаковыми именами, поэтому некоторые люди очень смущены. Почему бы не иметь такое же имя? На самом деле, многие крупные программы полагаются на множество сторонних библиотек, конфликты имен не слишком распространены, это первая проблема на официальном сайте. Так как же решить эту проблему? В отсутствие пространств имен бедные программисты могут называть классы только a_b_c_d_e_f, где a/b/c/d/e/f обычно имеет конкретное значение, так что в целом конфликта нет, но такие длинные имена классов трудно писать и еще более болезненно читать. Поэтому PHP 5 ввел пространство имен, имя класса-это имя класса, пространство имен-это пространство имен, программа для записи/чтения напрямую с именем класса, запущенная машина для просмотра пространства имен, которая решила проблему.
Кроме того, пространства имен предоставляют способ объединения связанных классов, функций и констант. Это также отличное использование пространств имен объектно-ориентированных языков, которые инкапсулируют классы, переменные и функции, необходимые для определенных целей в пространстве имен.
Решив проблему имен классов, мы можем, наконец, вернуться к стандарту PSR. Как PSR 0 и PSR 4 регулируют взаимосвязь отображения между файлами и пространствами имен? Ответ заключается в том, что именование пространств имен, расположение каталогов файлов классов и взаимосвязь отображения между ними являются основой стандарта. Более полное описание новых возможностей современного PHP (1) – Пространства имен
Прежде чем мы поговорим о PSR 0 и PSR 4, мы сначала представим стандарт PSR. Изобретателем и регулятором стандарта PSR является PHP-FID, веб-сайт которого www.php-fig.org. Именно этот альянс изобрел и создал спецификацию PSR. FIG-это аббревиатура группы совместимости фреймворков (Framework Interoperability Group). Она была основана в 2009 году несколькими разработчиками фреймворков с открытым исходным кодом. С тех пор было отобрано много других членов. Хотя это не “официальная” организация, она также представляет небольшую часть сообщества. Цель организации состоит в том, чтобы унифицировать спецификации кодирования каждого проекта с наименьшими ограничениями и избежать трудностей развития программистов, которым мешает их собственный стиль разработки. Поэтому все придумали и обобщили PSR, что является аббревиатурой Предложения Рекомендации по стандартам.
Подробные спецификации можно просмотреть в спецификации PSR на PHP
Стандарт PSR 0
Спецификация PRS-0 является их первым набором спецификаций, в основном формулирующих некоторые обязательные требования PSR-0 стандарта автоматической загрузки.
1. Полное пространство имен и класс должны соответствовать следующей структуре: “<Имя поставщика>(<Пространство имен>)*<Имя класса>” 2. Каждое пространство имен должно иметь пространство имен верхнего уровня (имя поставщика”Имя поставщика”) 3. Каждое пространство имен может иметь несколько подпространств 4. При загрузке из файловой системы разделитель (/) каждого пространства имен преобразуется в DIRECTORY_SEPARATOR (разделитель путей операционной системы) 5. В имени класса каждый символ подчеркивания () преобразуется в DIRECTORY_SEPARATOR (разделитель путей операционной системы). В пространстве имен символ подчеркивания _symbol не имеет (специального) значения. 6. При загрузке из файловой системы определенные пространства имен и классы должны заканчиваться на.Php 7. Имя поставщика, пространства имен, имя класса могут состоять из прописных и строчных букв (с учетом регистра)
Конкретные правила могут быть немного головокружительными, давайте начнем с нуля. Давайте сначала рассмотрим общее содержание стандарта PSR 0. Статьи 1, 2, 3 и 7 ограничивают имена пространств имен. Статьи 4 и 5 ограничивают взаимосвязь сопоставления между пространствами имен и каталогами файлов. Статья 6 ограничивает суффиксные имена файлов. Как мы уже говорили ранее, как стандарт PSR регулирует сопоставление между пространствами имен и каталогами файлов, в которых они расположены? Ограничивая имя пространства имен, расположение каталога файлов и взаимосвязь сопоставления между ними. Так что, может быть, нам нужно спросить, где ограничено расположение файлов в каталоге? На самом деле, ответ таков:
Имя ограниченного пространства имен + Сопоставление имени ограниченного пространства имен с каталогом файлов
Что ж, давайте сначала подумаем об этом. Какие изменения необходимо внести в конкретную программу, если она хочет поддерживать стандарт PSR 0?
Во-первых, программа должна определить функцию сопоставления, соответствующую стандартным пунктам 4 и 5 PSR 0, а затем зарегистрировать функцию в spl_register().
Во-вторых, при определении нового пространства имен имя пространства имен и расположение файла в каталоге должны соответствовать статьям 1, 2, 3 и 7.
Как правило, для удобства обслуживания кода мы определяем в файле только одно пространство имен. Хорошо, у нас есть имя пространства имен, которое соответствует стандарту PSR 0. Сопоставляя отношения, соответствующие стандарту PSR 0, мы можем получить адрес каталога файла, соответствующего стандарту PSR 0. Если мы правильно храним файл в соответствии со стандартом PSR 0, мы можем легко запросить файл. Мы можем использовать пространство имен. Разве это не удивительно? Далее давайте подробно рассмотрим, что на самом деле регулирует стандарт PSR 0. Давайте возьмем в качестве примера одно из пространств имен/Symfony/Core/Request в Symfony, сторонней библиотеке в laravel , и поговорим о стандарте PSR0 выше.
Полное пространство имен и класс должны соответствовать следующей структуре: “<Имя поставщика>(<Пространство имен>)*<Имя класса>”
Как показано выше,/Symfony-это имя поставщика, которое является именем сторонней библиотеки,/Core-это имя пространства имен, и, как правило, это некоторая атрибутивная информация нашего пространства имен (например, запрос является основной функцией Symfony). Наконец, запрос-это имя нашего пространства имен. Эта стандартная спецификация предназначена для того, чтобы люди могли видеть источник и функцию пространства имен очень четко, что полезно. Ведение кода.
2. Каждое пространство имен должно иметь пространство имен верхнего уровня (имя поставщика” Имя поставщика”).
То есть, каждое пространство имен должно иметь пространство имен верхнего уровня, аналогичное/Symfony. Почему у нас такое правило? Поскольку стандарт PSR0 отвечает только за сопоставление отношений после пространства имен верхнего уровня, то есть/Symfony/Core/Request, с которым должен быть связан каталог/Symfony, определяется пользователем или самой платформой. Так называемое пространство имен верхнего уровня-это пространство имен, которое настраивает отношения сопоставления, обычно имя поставщика (имя сторонней библиотеки). Другими словами, пространства имен верхнего уровня являются основой для автоматической загрузки. Почему стандартный набор такой? Причина проста: если существует пространство имен/Symfony/Core/Transport/Request и пространство имен/Symfony/Core/Transport/Request1, если нет пространства имен верхнего уровня, мы должны написать два пути, соответствующие двум пространствам имен. Если есть еще один Запрос2, Запрос3. С пространством имен верхнего уровня/Symfony нам просто нужно соответствие каталога, и
3. Каждое пространство имен может иметь несколько подпространств имен
Это очень просто. Запрос может быть определен как/Symfony/Core/Запрос или/Symfony/Core/Транспорт/Запрос. В пространстве имен/Core существует множество подпространств. Сколько уровней пространств имен определяются сами по себе.
4. При загрузке из файловой системы разделитель (/) каждого пространства имен преобразуется в DIRECTORY_SEPARATOR (разделитель путей операционной системы).
Теперь мы, наконец, подошли к спецификации отображения. Пространства имен/символы преобразуются в разделители путей, то есть/Symfony/Core/Request преобразуется в структуру каталогов, подобную запросу ядра Symfony.
5. В имени класса каждый символ подчеркивания _symbol преобразуется в РАЗДЕЛИТЕЛЬ КАТАЛОГОВ (разделитель путей операционной системы). В пространстве имен подчеркивания не имеют (специального) значения.
Это означает, что если наше пространство имен/Symfony/Core/Request_a, то мы должны сопоставить его с каталогом, таким как Symfony Core Request. Почему существует такое правило? Это связано с тем, что до PHP5 не существовало пространства имен, и программисты могли называть его только Symfony_Core_Request_a. Это правило PSR 0 должно быть совместимо с данной ситуацией. Два других очень просты. С помощью таких правил именования пространств имен и критериев сопоставления мы можем определить, куда следует поместить файл, в котором находится пространство имен. Все еще возьмите Symfony/Core/Request в качестве примера. Его каталог находится/path/to/project/vendor/Symfony/Core/Request.php, где/путь/к/проекту-это расположение вашего проекта на диске, а/путь/к/проекту/поставщику-это каталог всех сторонних библиотек, используемых проектом./Путь/к/проекту/поставщику/Symfony-это каталог, соответствующий пространству имен верхнего уровня/Symfony, а каталог файлов ниже установлен в соответствии со стандартом PSR0:
/Symfony/Ядро/Запрос =>/Symfony/Core/Request.php
Все уже сделано, не так ли? Нет, все еще есть некоторые недостатки:
Должны ли мы по-прежнему быть совместимы без пространств имен?
Согласно стандарту PSR 0, пространство имен/A/B/C/D/E/F должно соответствовать структуре каталогов/A/B/C/D/E/F. Не слишком ли глубока эта структура каталогов?
Стандарт PSR 4
В конце 2013 года была представлена пятая новая спецификация PSR-4.
PSR-4 указывает, как указать пути к файлам для автоматической загрузки определений классов, а также указывает расположение автоматически загружаемых файлов. На первый взгляд, это повторяется с PSR-0. На самом деле, у него действительно есть некоторое функциональное дублирование. Разница в том, что спецификация PSR-4 более чистая, удаляет контент, совместимый с предыдущими версиями PHP 5.3, и имеет небольшое представление об обновлении PSR-0. Конечно, PSR-4 не предназначен для полной замены PSR-0, но для дополнения PSR-0 при необходимости – конечно, PSR-4 также может заменить PSR-0, если хотите. PSR-4 может использоваться в сочетании с другими автоматическими механизмами загрузки, включая PSR-0. Разница между стандартом PSR 4 и стандартом PSR 0:
В использовании знаков подчеркивания в именах классов нет особого смысла.
Был скорректирован метод сопоставления пространства имен и каталога файлов.
Для второго пункта давайте подробно объясним (принцип автоматической загрузки композитора): Если у нас есть пространство имен: Foo/class, Foo-это пространство имен верхнего уровня, и существует определенная пользователем связь сопоставления с каталогом:
"Foo/" => "src/"
В соответствии со стандартом PSR 0 сопоставленный каталог файлов является src/Foo/class.php, но в соответствии со стандартом PSR 4 сопоставленный каталог файлов будет src/class.php. Почему ты так все меняешь? Причина в том, что пространство имен слишком длинное, а уровень каталога слишком глубокий, что делает взаимосвязь отображения между пространством имен и каталогом файлов более гибкой.
Другим примером является источник PSR-4, свежая спецификация PHP: стиль PSR-0
vendor/ vendor_name/ package_name/ src/ Vendor_Name/ Package_Name/ ClassName.php # Vendor_Name\Package_Name\ClassName tests/ Vendor_Name/ Package_Name/ ClassNameTest.php # Vendor_Name\Package_Name\ClassName
Стиль PSR-4
vendor/ vendor_name/ package_name/ src/ ClassName.php # Vendor_Name\Package_Name\ClassName tests/ ClassNameTest.php # Vendor_Name\Package_Name\ClassNameTest
Сравнивая две вышеперечисленные структуры, мы можем ясно видеть, что PSR-4 обеспечивает более лаконичную файловую структуру.
Написано с помощью StackEdit.