Backend

Cтандартs PSR-0, PSR-1, PSR-2 (PSR-12), PSR-3, PSR-4

PSR - PHP Standart Recommendation. Рекомендации по чистому коду на PHP. На текущий момент существует около 20 таких стандартов. Полный список на wiki или на официальном сайте.

Linter для проверки написанного кода на соответствие стандартам.

Оглавление

PSR-0 – Стандарт автозагрузки (устаревший см. PSR-4)

Требования, обязательные к исполнению для обеспечения совместимости механизмов автозагрузки.

  • Полностью определённое пространство имён и имя класса должны иметь следующую структуру: <Vendor Name>\(<Namespace>\)*<Class Name>.
  • Каждое пространство имён должно начинаться с пространства имён высшего уровня, указывающего на разработчика кода («имя производителя»).
  • Каждое пространство имён может включать в себя неограниченное количество вложенных подпространств имён.
  • Каждый разделитель пространства имён при обращении к файловой системе преобразуется в РАЗДЕЛИТЕЛЬ_ИМЁН_КАТАЛОГОВ.
  • Каждый символ _ («знак подчёркивания») в ИМЕНИ_КЛАССА преобразуется в РАЗДЕЛИТЕЛЬ_ИМЁН_КАТАЛОГОВ. При этом символ _ («знак подчёркивания») не обладает никаким особенным значением в имени пространства имён (и не претерпевает преобразований).
  • При обращении к файловой системе полностью определённое пространство имён и имя класса дополняются суффиксом .php.
  • В имени производителя, имени пространства имён и имени класса допускается использование буквенных символов в любых комбинациях нижнего и верхнего регистров.

Примеры:

  • \Doctrine\Common\IsolatedClassLoader => /path/to/project/lib/vendor/Doctrine/Common/IsolatedClassLoader.php
  • \Symfony\Core\Request => /path/to/project/lib/vendor/Symfony/Core/Request.php
  • \Zend\Acl => /path/to/project/lib/vendor/Zend/Acl.php
  • \Zend\Mail\Message => /path/to/project/lib/vendor/Zend/Mail/Message.php

Знак подчёркивания в именах пространств имён и классов:

  • \namespace\package\Class_Name => /path/to/project/lib/vendor/namespace/package/Class/Name.php
  • \namespace\package_name\Class_Name => /path/to/project/lib/vendor/namespace/package_name/Class/Name.php

Представленные здесь стандарты должны восприниматься как минимально необходимый набор правил для обеспечения совместимости автозагрузчиков. Вы можете проверить, насколько вы следуете указанным правилам, воспользовавшись следующим примером реализации SplClassLoader (ориентирован на загрузку классов PHP 5.3).

Пример реализации

Ниже представлен пример функции, иллюстрирующей, как описанные выше требования влияют на процесс автозагрузки:

  1. <?php
  2. function autoload($className)
  3. {
  4. $className = ltrim($className, '\\');
  5. $fileName = '';
  6. $namespace = '';
  7. if ($lastNsPos = strrpos($className, '\\')) {
  8. $namespace = substr($className, 0, $lastNsPos);
  9. $className = substr($className, $lastNsPos + 1);
  10. $fileName = str_replace('\\', DIRECTORY_SEPARATOR, $namespace) . DIRECTORY_SEPARATOR;
  11. }
  12. $fileName .= str_replace('_', DIRECTORY_SEPARATOR, $className) . '.php';
  13.  
  14. require $fileName;
  15. }

Реализация SplClassLoader

Ниже представлен пример реализации SplClassLoader, способного выполнять автозагрузку ваших классов при условии, что вы следуете описанным выше требованиям. В настоящий момент такой подход является рекомендуемым для загрузки классов PHP 5.3 при условии соблюдения данного стандарта:

  1. <?php
  2.  
  3. /*
  4.  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  5.  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  6.  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  7.  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  8.  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  9.  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  10.  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  11.  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  12.  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  13.  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  14.  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  15.  *
  16.  * This software consists of voluntary contributions made by many individuals
  17.  * and is licensed under the MIT license. For more information, see
  18.  * <https://www.doctrine-project.org>.
  19.  */
  20.  
  21. /**
  22.  * SplClassLoader implementation that implements the technical interoperability
  23.  * standards for PHP 5.3 namespaces and class names.
  24.  *
  25.  * https://groups.google.com/group/php-standards/web/psr-0-final-proposal?pli=1
  26.  *
  27.  * // Example which loads classes for the Doctrine Common package in the
  28.  * // Doctrine\Common namespace.
  29.  * $classLoader = new SplClassLoader('Doctrine\Common', '/path/to/doctrine');
  30.  * $classLoader->register();
  31.  *
  32.  * @license https://www.opensource.org/licenses/mit-license.html MIT License
  33.  * @author Jonathan H. Wage <jonwage@gmail.com>
  34.  * @author Roman S. Borschel <roman@code-factory.org>
  35.  * @author Matthew Weier O'Phinney <matthew@zend.com>
  36.  * @author Kris Wallsmith <kris.wallsmith@gmail.com>
  37.  * @author Fabien Potencier <fabien.potencier@symfony-project.org>
  38.  */
  39. class SplClassLoader
  40. {
  41. private $_fileExtension = '.php';
  42. private $_namespace;
  43. private $_includePath;
  44. private $_namespaceSeparator = '\\';
  45.  
  46. /**
  47.   * Creates a new <tt>SplClassLoader</tt> that loads classes of the
  48.   * specified namespace.
  49.   *
  50.   * @param string $ns The namespace to use.
  51.   */
  52. public function __construct($ns = null, $includePath = null)
  53. {
  54. $this->_namespace = $ns;
  55. $this->_includePath = $includePath;
  56. }
  57.  
  58. /**
  59.   * Sets the namespace separator used by classes in the namespace of this class loader.
  60.   *
  61.   * @param string $sep The separator to use.
  62.   */
  63. public function setNamespaceSeparator($sep)
  64. {
  65. $this->_namespaceSeparator = $sep;
  66. }
  67.  
  68. /**
  69.   * Gets the namespace seperator used by classes in the namespace of this class loader.
  70.   *
  71.   * @return void
  72.   */
  73. public function getNamespaceSeparator()
  74. {
  75. return $this->_namespaceSeparator;
  76. }
  77.  
  78. /**
  79.   * Sets the base include path for all class files in the namespace of this class loader.
  80.   *
  81.   * @param string $includePath
  82.   */
  83. public function setIncludePath($includePath)
  84. {
  85. $this->_includePath = $includePath;
  86. }
  87.  
  88. /**
  89.   * Gets the base include path for all class files in the namespace of this class loader.
  90.   *
  91.   * @return string $includePath
  92.   */
  93. public function getIncludePath()
  94. {
  95. return $this->_includePath;
  96. }
  97.  
  98. /**
  99.   * Sets the file extension of class files in the namespace of this class loader.
  100.   *
  101.   * @param string $fileExtension
  102.   */
  103. public function setFileExtension($fileExtension)
  104. {
  105. $this->_fileExtension = $fileExtension;
  106. }
  107.  
  108. /**
  109.   * Gets the file extension of class files in the namespace of this class loader.
  110.   *
  111.   * @return string $fileExtension
  112.   */
  113. public function getFileExtension()
  114. {
  115. return $this->_fileExtension;
  116. }
  117.  
  118. /**
  119.   * Installs this class loader on the SPL autoload stack.
  120.   */
  121. public function register()
  122. {
  123. spl_autoload_register(array($this, 'loadClass'));
  124. }
  125.  
  126. /**
  127.   * Uninstalls this class loader from the SPL autoloader stack.
  128.   */
  129. public function unregister()
  130. {
  131. spl_autoload_unregister(array($this, 'loadClass'));
  132. }
  133.  
  134. /**
  135.   * Loads the given class or interface.
  136.   *
  137.   * @param string $className The name of the class to load.
  138.   * @return void
  139.   */
  140. public function loadClass($className)
  141. {
  142. if (null === $this->_namespace || $this->_namespace.$this->_namespaceSeparator === substr($className, 0, strlen($this->_namespace.$this->_namespaceSeparator))) {
  143. $fileName = '';
  144. $namespace = '';
  145. if (false !== ($lastNsPos = strripos($className, $this->_namespaceSeparator))) {
  146. $namespace = substr($className, 0, $lastNsPos);
  147. $className = substr($className, $lastNsPos + 1);
  148. $fileName = str_replace($this->_namespaceSeparator, DIRECTORY_SEPARATOR, $namespace) . DIRECTORY_SEPARATOR;
  149. }
  150. $fileName .= str_replace('_', DIRECTORY_SEPARATOR, $className) . $this->_fileExtension;
  151.  
  152. require ($this->_includePath !== null ? $this->_includePath . DIRECTORY_SEPARATOR : '') . $fileName;
  153. }
  154. }
  155. }

PSR-1 – Базовый стандарт оформления кода

PSR-1: Basic Coding Standard (Базовый стандарт написания кода). Это набор правил, определяющих, как следует оформлять программный код: как писать теги PHP, по каким правилам именовать классы, методы и константы классов. Он также затрагивает вопросы кодировки, автозагрузки, пространства имён и разделения ответственности между файлами. Это базовые правила, стандарт PSR-12 их расширяет.

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

Слова «НЕОБХОДИМО» / «ДОЛЖНО» («MUST»), «НЕДОПУСТИМО» («MUST NOT»), «ТРЕБУЕТСЯ» («REQUIRED»), «НУЖНО» («SHALL»), «НЕ ПОЗВОЛЯЕТСЯ» («SHALL NOT»), «СЛЕДУЕТ» («SHOULD»), «НЕ СЛЕДУЕТ» («SHOULD NOT»), «РЕКОМЕНДУЕТСЯ» («RECOMMENDED»), «МОЖЕТ» / «ВОЗМОЖНО» («MAY») и «НЕОБЯЗАТЕЛЬНО» («OPTIONAL») в этом документе следует понимать так, как это описано в RFC 2119 (и его переводе).

1. Общие положения

  • В файлах НЕОБХОДИМО использовать только теги <?php и <?=.
  • Файлы НЕОБХОДИМО представлять только в кодировке UTF-8 без BOM-байта.
  • В файлах СЛЕДУЕТ либо объявлять структуры (классы, функции, константы и т.п.), либо генерировать побочные эффекты (выполнять действия) (например: передавать данные в выходной поток, модифицировать настройки и т.п.), но НЕ СЛЕДУЕТ делать одновременно и то, и другое.
  • Имена пространств имён и имена классов ДОЛЖНЫ следовать стандарту PSR-0.
  • Имена классов ДОЛЖНЫ быть объявлены с использованием т.н. «StudlyCaps» (каждое слово начинается с большой буквы, между словами нет разделителей).
  • Константы классов ДОЛЖНЫ быть объявлены исключительно в верхнем регистре с использованием символа подчёркивания для разделения слов.
  • Имена методов ДОЛЖНЫ быть объявлены с использованием т.н. «camelCase» (первое слово пишется в нижнем регистре, далее каждое слово начинается с большой буквы, а между словами нет разделителей).

2. Файлы

2.1. PHP-теги

PHP-код ОБЯЗАТЕЛЬНО следует заключать в полную версию (<?php ?>) тегов или сокращённую версию (<?= ?>) тегов и НЕДОПУСТИМО заключать ни в какие иные разновидности тегов.

2.2. Кодировка символов

PHP-код ДОЛЖЕН быть представлен только в кодировке UTF-8 без BOM-байта.

2.3. Побочные эффекты

В файлах СЛЕДУЕТ либо объявлять структуры (классы, функции, константы и т.п.) и не создавать побочных эффектов (например: передавать данные в выходной поток, модифицировать настройки и т.п.), либо реализовывать логику, порождающую побочные эффекты, но НЕ СЛЕДУЕТ делать одновременно и то, и другое.

Под «побочными эффектами» понимается реализация логики, не связанной с объявлением классов, функций, констант и т.п. – даже подключение внешнего файла уже является «побочным эффектом».

«Побочные эффекты» включают (но не ограничиваются этим перечнем): передачу данных в выходной поток, явное использование require или include, изменение настроек, генерирование ошибочных ситуаций или порождение исключений, изменение глобальных или локальных переменных, чтение из файла или запись в файл и т.п.

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

  1. <?php
  2. // побочный эффект: изменение настроек
  3. ini_set('error_reporting', E_ALL);
  4.  
  5. // побочный эффект: подключение файла
  6. include "file.php";
  7.  
  8. // побочный эффект: передача данных в выходной поток
  9. echo "\n";
  10.  
  11. // объявление
  12. function foo()
  13. {
  14. // тело функции
  15. }

Следующий пример демонстрирует файл с объявлениями без побочных эффектов – т.е. образец рекомендуемой реализации:

  1. <?php
  2. // объявление
  3. function foo()
  4. {
  5. // тело функции
  6. }
  7.  
  8. // условное объявление -- это НЕ побочный эффект
  9. if (! function_exists('bar')) {
  10. function bar()
  11. {
  12. // тело функции
  13. }
  14. }

3. Имена пространств имён и имена классов

Имена пространств имён и имена классов ДОЛЖНЫ следовать стандарту PSR-0. В конечном итоге это означает, что каждый класс должен располагаться в отдельном файле и в пространстве имён с хотя бы одним верхним уровнем (именем производителя).

Имена классов ДОЛЖНЫ быть объявлены с использованием т.н. «StudlyCaps» (каждое слово начинается с большой буквы, между словами нет разделителей).

Код, написанный для PHP 5.3 и более новых версий, ДОЛЖЕН использовать формальные пространства имён, например:

  1. <?php
  2.  
  3. // PHP 5.3 и новее:
  4. namespace Vendor\Model;
  5.  
  6. class Foo
  7. {
  8. }

В коде, написанном для PHP 5.2.x и ниже, СЛЕДУЕТ при именовании классов соблюдать соглашение о псевдопространствах имён с префиксом в виде имени производителя (Vendor_):

  1. <?php
  2.  
  3. // PHP 5.2.x и ранее:
  4. class Vendor_Model_Foo
  5. {
  6. }

4. Константы, свойства и методы классов

Здесь под «классом» следует понимать также интерфейсы (interface) и примеси (trait).

4.1. Константы

Константы классов ДОЛЖНЫ быть объявлены в верхнем регистре с использованием символа подчёркивания в качестве разделителя слов, например:

  1. <?php
  2.  
  3. namespace Vendor\Model;
  4.  
  5. class Foo
  6. {
  7. const VERSION = '1.0';
  8. const DATE_APPROVED = '2012-06-01';
  9. }

4.2. Свойства

В данном руководстве намеренно не приводится никаких рекомендаций относительно использования $StudlyCaps, $camelCase или $under_score вариантов именования свойств.

Какой бы вариант именования ни был выбран, СЛЕДУЕТ сохранять его неизменным в рамках некоторого разумного объёма кода (например, на уровне производителя, пакета, класса или метода).

4.3. Методы

Имена методов ДОЛЖНЫ быть объявлены с использованием т.н. «camelCase» (первое слово пишется в нижнем регистре, далее каждое слово начинается с большой буквы, а между словами нет разделителей).

PSR-2 – Рекомендации по оформлению кода

PSR-12: Extended Coding Style (Расширенный стандарт стиля кодирования, заменяет и дополняет устаревший PSR-2). Во-первых, этот стандарт требует выполнения правил PSR-1. Во-вторых, он добавляет множество новых требований: к отступам, файлам, строкам, ключевым словам, классам, управляющим конструкциям, области видимости и другим элементам.

Цель данных рекомендаций – снижение сложности восприятия кода, написанного разными авторами; она достигается путём рассмотрения серии правил и ожиданий относительно форматирования PHP-кода.

Стилистические правила, представленные здесь, получены путём обобщения опыта различных проектов. Сотрудничество многих авторов из многих проектов позволяет выработать единый набор принципов и использовать его в этих проектах. Таким образом, польза представленных рекомендаций – не столько в самих рекомендациях, сколько в их распространении.

Слова «НЕОБХОДИМО» / «ДОЛЖНО» («MUST»), «НЕДОПУСТИМО» («MUST NOT»), «ТРЕБУЕТСЯ» («REQUIRED»), «НУЖНО» («SHALL»), «НЕ ПОЗВОЛЯЕТСЯ» («SHALL NOT»), «СЛЕДУЕТ» («SHOULD»), «НЕ СЛЕДУЕТ» («SHOULD NOT»), «РЕКОМЕНДУЕТСЯ» («RECOMMENDED»), «МОЖЕТ» / «ВОЗМОЖНО» («MAY») и «НЕОБЯЗАТЕЛЬНО» («OPTIONAL») в этом документе следует понимать так, как это описано в RFC 2119 (и его переводе).

Данный раздел будет обновлён в соответствии с новой спецификацией

PSR-3 – Интерфейс протоколирования

Данный документ описывает общий интерфейс библиотек протоколирования.

Основная цель данного документа – позволить библиотекам получать объект Psr\Log\LoggerInterface и использовать его простым и универсальным образом для реализации протоколирования. В случае, если некий фреймворк или CMS нуждается в расширенном функционале, МОЖНО расширять данный интерфейс, но СЛЕДУЕТ сохранять совместимость с описанными в данном документе правилами. Это позволит сторонним библиотекам, применяемым при разработке приложения, использовать централизованную систему протоколирования.

Слова «НЕОБХОДИМО» / «ДОЛЖНО» («MUST»), «НЕДОПУСТИМО» («MUST NOT»), «ТРЕБУЕТСЯ» («REQUIRED»), «НУЖНО» («SHALL»), «НЕ ПОЗВОЛЯЕТСЯ» («SHALL NOT»), «СЛЕДУЕТ» («SHOULD»), «НЕ СЛЕДУЕТ» («SHOULD NOT»), «РЕКОМЕНДУЕТСЯ» («RECOMMENDED»), «МОЖЕТ» / «ВОЗМОЖНО» («MAY») и «НЕОБЯЗАТЕЛЬНО» («OPTIONAL») в этом документе следует понимать так, как это описано в RFC 2119 (и его переводе).

Слово «разработчик» (implementor) в данном документе следует понимать как «автор, реализующий интерфейс LoggerInterface в неких библиотеке или фреймворке, связанных с протоколированием». Пользователи систем протоколирования упоминаются как просто «пользователи».

1. Спецификации

1.1 Основы

Интерфейс LoggerInterface предоставляет восемь методов протоколирования, соответствующих восьми уровням протоколирования, описанным в RFC 5424 (отладка (debug), информация (info), замечание (notice), предупреждение (warning), ошибка (error), критическая ошибка (critical), тревога (alert), авария (emergency)).

Девятый метод, «протокол» (log) принимает в качестве первого аргумента уровень протоколирования. Вызов этого метода с передачей константы одного из уровней протоколирования ДОЛЖЕН приводить к тому же результату, что и вызов соответствующего переданному уровню протоколирования специального метода.

Вызов этого метода с передачей уровня протоколирования, не описанного в данной спецификации, ДОЛЖЕН приводить к порождению исключения Psr\Log\InvalidArgumentException в случае, если конкретная реализация системы протоколирования не поддерживает переданный уровень протоколирования.

Пользователям НЕ СЛЕДУЕТ использовать собственные уровни протоколирования без полной уверенности в том, что конкретная реализация системы протоколирования их поддерживает.

1.2 Сообщения

  • Каждый метод протоколирования должен принимать строку-сообщение или объект с методом __toString(). Разработчики МОГУТ использовать специальные обработчики переданных объектов, но если этого не сделано, объект ДОЛЖЕН быть приведён к строке.
  • Строка-сообщение МОЖЕТ содержать плейсхолдеры, которые МОГУТ быть заменены на конкретные значения из массива context.
  • Имена плейсхолдеров ДОЛЖНЫ совпадать со значениями ключей массива context.
  • Плейсхолдеры ДОЛЖНЫ быть заключены в одиночные фигурные скобки, при этом НЕ ДОЛЖНО быть пробелов между фигурными скобками и именем плейсхолдера.
  • Имена плейсхолдеров НУЖНО составлять только из символов A-Z, a-z, 0-9, знак подчёркивания (_) и точка (.). Остальные символы зарезервированы для будущих изменений в спецификации плейсхолдеров.
  • Разработчики МОГУТ реализовывать со значениями плейсхолдеров различные стратегии экранирования и преобразования при отображении протокола. Пользователям НЕ НУЖНО предварительно экранировать данные в значениях плейсхолдеров, т.к. заранее не известно, как и в каком контексте содержащаяся в них информация может быть использована.

Ниже для ознакомления представлен пример обработки плейсхолдеров.

            
  1. <?php
  2.  
  3. /**
  4.  * Interpolates context values into the message placeholders.
  5.  */
  6. function interpolate($message, array $context = array())
  7. {
  8. // build a replacement array with braces around the context keys
  9. $replace = array();
  10. foreach ($context as $key => $val) {
  11. // check that the value can be cast to string
  12. if (!is_array($val) && (!is_object($val) || method_exists($val, '__toString'))) {
  13. $replace[`{ ` . $key . '}'] = $val;
  14. }
  15. }
  16.  
  17. // interpolate replacement values into the message and return
  18. return strtr($message, $replace);
  19. }
  20.  
  21. // a message with brace-delimited placeholder names
  22. $message = "User {username} created";
  23.  
  24. // a context array of placeholder names => replacement values
  25. $context = array('username' => 'bolivar');
  26.  
  27. // echoes "User bolivar created"
  28. echo interpolate($message, $context);

1.3 Контекст

  • Каждый метод получает массив сопутствующих данных (context), содержащих дополнительную информацию, представление которой в виде строки не является оптимальным. На содержимое массива не налагается никаких ограничений. Разработчики ДОЛЖНЫ обрабатывать данные массива context максимально гибко. Переданные в массиве context данные НЕ ДОЛЖНЫ порождать исключений, вызывать сообщений об ошибках, предупреждений или замечаний от интерпретатора PHP.
  • Если в массив context передан объект исключения, он ДОЛЖЕН находиться в элементе с ключом exception. Протоколирование исключений является распространённой практикой и позволяет разработчикам извлекать данные трассировки стека, если система протоколирования поддерживает такую функциональность. Разработчики ДОЛЖНЫ удостовериться, что в элементе с ключом exception на самом деле находится объект исключения, т.к. в реальности там МОЖЕТ оказаться что угодно.

1.4 Вспомогательные классы и интерфейсы

  • Класс Psr\Log\AbstractLogger позволяет очень легко реализовать интерфейс LoggerInterface – достаточно создать свой класс-наследник и реализовать там метод log. Остальные восемь методов будут передавать сообщения и контекст в этот метод.
  • Аналогично, использование Psr\Log\LoggerTrait требует всего лишь реализовать метод log. Однако в связи с тем, что примеси не могут реализовывать интерфейсы, вам всё равно придётся реализовать LoggerInterface.
  • Класс Psr\Log\NullLogger, поставляемый с соответствующим интерфейсом, МОЖЕТ быть использован для реализации «записи протокола в пустоту», однако условное протоколирование может оказаться лучшим решением в случае, если создание контекстной информации является затратной операцией.
  • Интерфейс Psr\Log\LoggerAwareInterface содержит только метод setLogger(LoggerInterface $logger) и может быть использован для автоматического связывания необходимых сущностей с системой протоколирования.
  • Примесь Psr\Log\LoggerAwareTrait может быть легко использована для реализации соответствующего интерфейса. Она предоставляет доступ к $this->logger.
  • Класс Psr\Log\LogLevel содержит константы восьми уровней протоколирования.

2. Пакет

Описанные интерфейсы и классы, равно как и соответствующие классы исключений и тестовые сценарии для проверки вашей реализации системы протоколирования предоставляются в составе пакета psr/log.

3. Интерфейс Psr\Log\LoggerInterface

  1. <?php
  2.  
  3. namespace Psr\Log;
  4.  
  5. /**
  6.  * Описывает систему протоколирования.
  7.  *
  8.  * Сообщение ДОЛЖНО быть строкой или объектом, реализующим __toString().
  9.  *
  10.  * Сообщение МОЖЕТ содержать плейсхолдеры в виде {foo}, где foo будет
  11.  * заменено на значение элемента массива context с ключом "foo".
  12.  *
  13.  * Массив context может содержать произвольные данные. Единственное
  14.  * предположение, допустимое для разработчиков, заключается в том, что
  15.  * если в массиве переда объект исключения для построения трассировки
  16.  * стека, он ДОЛЖЕН находиться в элементе массива с ключом "exception".
  17.  *
  18.  * См. полную спецификацию интерфейса здесь: https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-3-logger-interface.md
  19.  */
  20. interface LoggerInterface
  21. {
  22. /**
  23.   * Авария, система неработоспособна.
  24.   *
  25.   * @param строка $message
  26.   * @param массив $context
  27.   * @return null
  28.   */
  29. public function emergency($message, array $context = array());
  30.  
  31. /**
  32.   * Тревога, меры должны быть предприняты незамедлительно.
  33.   *
  34.   * Примеры: весь веб-сайт недоступен, БД недоступна и т.д. Вплоть до
  35.   * отправки SMS-сообщения ответственному лицу.
  36.   *
  37.   * @param строка $message
  38.   * @param массив $context
  39.   * @return null
  40.   */
  41. public function alert($message, array $context = array());
  42.  
  43. /**
  44.   * Критическая ошибка, критическая ситуация.
  45.   *
  46.   * Пример: недоступен компонент приложения, неожиданное исключение.
  47.   *
  48.   * @param строка $message
  49.   * @param массив $context
  50.   * @return null
  51.   */
  52. public function critical($message, array $context = array());
  53.  
  54. /**
  55.   * Ошибка на стадии выполнения, не требующая неотложного вмешательства,
  56.   * но требующая протоколирования и дальнейшего изучения.
  57.   *
  58.   * @param строка $message
  59.   * @param массив $context
  60.   * @return null
  61.   */
  62. public function error($message, array $context = array());
  63.  
  64. /**
  65.   * Предупреждение, нештатная ситуация, не являющаяся ошибкой.
  66.   *
  67.   * Пример: использование устаревшего API, неверное использование API,
  68.   * нежелательные эффекты и ситуации, которые, тем не менее,
  69.   * не обязательно являются ошибочными.
  70.   *
  71.   * @param строка $message
  72.   * @param массив $context
  73.   * @return null
  74.   */
  75. public function warning($message, array $context = array());
  76.  
  77. /**
  78.   * Замечание, важное событие.
  79.   *
  80.   * @param строка $message
  81.   * @param массив $context
  82.   * @return null
  83.   */
  84. public function notice($message, array $context = array());
  85.  
  86. /**
  87.   * Информация, полезные для понимания происходящего события.
  88.   *
  89.   * Пример: авторизация пользователя, протокол взаимодействия с БД.
  90.   *
  91.   * @param строка $message
  92.   * @param массив $context
  93.   * @return null
  94.   */
  95. public function info($message, array $context = array());
  96.  
  97. /**
  98.   * Детальная отладочная информация.
  99.   *
  100.   * @param строка $message
  101.   * @param массив $context
  102.   * @return null
  103.   */
  104. public function debug($message, array $context = array());
  105.  
  106. /**
  107.   * Протоколирование с произвольным уровнем.
  108.   *
  109.   * @param смешанный $level
  110.   * @param строка $message
  111.   * @param массив $context
  112.   * @return null
  113.   */
  114. public function log($level, $message, array $context = array());
  115. }

4. Интерфейс Psr\Log\LoggerAwareInterface

  1. <?php
  2.  
  3. namespace Psr\Log;
  4.  
  5. /**
  6.  * Описывает систему, поддерживающую протоколирование.
  7.  */
  8. interface LoggerAwareInterface
  9. {
  10. /**
  11.   * Устанавливает объект протоколирования в объект
  12.   * системы, поддерживающей протоколирование.
  13.   *
  14.   * @param LoggerInterface $logger
  15.   * @return null
  16.   */
  17. public function setLogger(LoggerInterface $logger);
  18. }

5. Класс Psr\Log\LogLevel

  1. <?php
  2.  
  3. namespace Psr\Log;
  4.  
  5. /**
  6.  * Описывает уровни протоколирования.
  7.  */
  8. class LogLevel
  9. {
  10. const EMERGENCY = 'emergency';
  11. const ALERT = 'alert';
  12. const CRITICAL = 'critical';
  13. const ERROR = 'error';
  14. const WARNING = 'warning';
  15. const NOTICE = 'notice';
  16. const INFO = 'info';
  17. const DEBUG = 'debug';
  18. }

PSR-4 – Улучшенная автозагрузка

Слова «НЕОБХОДИМО» / «ДОЛЖНО» («MUST»), «НЕДОПУСТИМО» («MUST NOT»), «ТРЕБУЕТСЯ» («REQUIRED»), «НУЖНО» («SHALL»), «НЕ ПОЗВОЛЯЕТСЯ» («SHALL NOT»), «СЛЕДУЕТ» («SHOULD»), «НЕ СЛЕДУЕТ» («SHOULD NOT»), «РЕКОМЕНДУЕТСЯ» («RECOMMENDED»), «МОЖЕТ» / «ВОЗМОЖНО» («MAY») и «НЕОБЯЗАТЕЛЬНО» («OPTIONAL») в этом документе следует понимать так, как это описано в RFC 2119 (и его переводе).

1. Обзор

Данный стандарт описывает спецификацию автозагрузки классов на основе путей к файлам. Он полностью совместим (и может использоваться как дополнение) с любой другой спецификацией автозагрузки, включая PSR-0. Данный стандарт также описывает правила размещения файлов, предназначенных для автозагрузки.

2. Спецификация

1.4 Вспомогательные классы и интерфейсы

  • Здесь под «классом» следует понимать также интерфейсы (interface), примеси (trait) и иные подобные конструкции.
  • Полностью определённое имя класса должно иметь следующую структуру: \<ПространствоИмён>(\<ПодпространствоИмён>)*\<ИмяКласса>
  • Полностью определённое имя класса ДОЛЖНО начинаться с пространства имён высшего уровня, указывающего на разработчика кода («имя производителя»).
  • Полностью определённое имя класса МОЖЕТ включать в себя одно или более подпространств имён.
  • Полностью определённое имя класса ДОЛЖНО заканчиваться именем класса.
  • Символ _ («знак подчёркивания») не обладает никаким особенным значением в полностью определённом имени класса.
  • В полностью определённом имени класса МОЖНО использовать буквенные символы в любых комбинациях нижнего и верхнего регистров.
  • Все имена классов ДОЛЖНЫ быть использованы с соблюдением регистрочувствительности.

При загрузке файла, соответствующего полностью определённому имени класса, используются следующие правила:

  • Последовательность из одного и более пространств и подпространств имён (не включая ведущий разделитель пространств имён) в полностью определённом имени класса (т.н. «префикс пространств имён») должна соответствовать хотя бы одному «базовому каталогу».
  • Последовательность подпространств имён после «префикса пространства имён» соответствует подкаталогу в «базовом каталоге», при этом разделители пространств имён \ соответствуют разделителям каталогов /. Имя подкаталога и имя подпространства имён ДОЛЖНЫ совпадать вплоть до регистра символов.
  • Имя класса, завершающее собой полностью определённое имя, соответствует имени файла с расширением .php. Имя файла и имя класса ДОЛЖНЫ совпадать вплоть до регистра символов.

В реализации автозагрузчика НЕДОПУСТИМО порождать исключения, ошибочные ситуации любого уровня и НЕ СЛЕДУЕТ возвращать какое бы то ни было значение.