Перевод стандартов PSR

PHP Стандартная рекомендация (PSR) является опубликованной спецификацией PHP Framework Interop Group в PHP. Подобно спецификации Java Specification Request для Java, он служит стандартизацией концепций программирования в PHP. Цель состоит в том, чтобы обеспечить функциональную совместимость компонентов и обеспечить общую техническую основу для реализации проверенных концепций для оптимального программирования и тестирования продукта. PHP-FIG образована несколькими основателями фреймворков.

Каждый PSR был предложен членами сообщества и утвержден в соответствии с установленным протоколом, чтобы последовательно и согласованно разрабатывать процессы в построении продукта.

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

Обязательные требования

  • Полностью определённое пространство имён и имя класса должны иметь следующую структуру: \<Vendor Name>\(\)*<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).

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

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

<?php

function autoload($className)
{
    $className = ltrim($className, '\\');
    $fileName  = '';
    $namespace = '';
    if ($lastNsPos = strrpos($className, '\\')) {
        $namespace = substr($className, 0, $lastNsPos);
        $className = substr($className, $lastNsPos + 1);
        $fileName  = str_replace('\\', DIRECTORY_SEPARATOR, $namespace) . DIRECTORY_SEPARATOR;
    }
    $fileName .= str_replace('_', DIRECTORY_SEPARATOR, $className) . '.php';
 
    require $fileName;
}

Реализация SplClassLoader

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

тыц на ГитХаб

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

Слова «НЕОБХОДИМО» / «ДОЛЖНО» («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 ?>) тегов или укороченную (сокращённую запись echo) версию (<\?= \?>) тегов и НЕДОПУСТИМО заключать ни в какие иные разновидности тегов.

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

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

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

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

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

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

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

<?php

// побочный эффект: изменение настроек
ini_set('error_reporting', E_ALL);
 
// побочный эффект: подключение файла
include "file.php";
 
// побочный эффект: передача данных в выходной поток
echo "\n";
 
// объявление
function foo()
{
    // тело функции
}

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

<?php

// объявление
function foo()
{
    // тело функции
}
 
// условное объявление -- это НЕ побочный эффект
if (! function_exists('bar')) {
    function bar()
    {
        // тело функции
    }
}

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

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

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

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

<?php

// PHP 5.3 и новее:
namespace Vendor\Model;
 
class Foo
{
}

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

<?php

// PHP 5.2.x и ранее:
class Vendor_Model_Foo
{
}

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

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

4.1. Константы

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

<?php

namespace Vendor\Model;

class Foo
{
    const VERSION = '1.0';
    const DATE_APPROVED = '2012-06-01';
}

4.2. Свойства

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

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

4.3. Методы

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

Данные рекомендации расширяют и дополняют базовый стандарт оформления кода PSR-1.

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

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

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

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

  • Код ДОЛЖЕН быть оформлен согласно стандарту PSR-1.
  • Для оформления отступов ДОЛЖНЫ использоваться четыре пробела (но не знак табуляции).
  • НЕДОПУСТИМО жёстко ограничивать длину строки; мягкое ограничение ДОЛЖНО составлять 120 символов; СЛЕДУЕТ стараться, чтобы длина строки составляла 80 символов или менее.
  • После определения пространства имён (namespace) и после блока импорта пространств имён (use) ДОЛЖНА быть одна пустая строка.
  • Открывающая фигурная скобка в определении класса ДОЛЖНА располагаться на новой строке, а закрывающая фигурная скобка ДОЛЖНА располагаться на следующей строке после тела класса.
  • Открывающая фигурная скобка в определении метода ДОЛЖНА располагаться на новой строке, а закрывающая фигурная скобка ДОЛЖНА располагаться на следующей строке после тела метода.
  • Область видимости ДОЛЖНА быть указана явно для всех свойств и методов; модификаторы abstract и final ДОЛЖНЫ располагаться перед модификаторами области видимости; модификатор static ДОЛЖЕН располагаться после модификаторов области видимости.
  • После ключевых слов в управляющих конструкциях ДОЛЖЕН располагаться один пробел, а после вызовов функций и методов – НЕ ДОЛЖЕН.
  • Открывающая фигурная скобка в управляющих конструкциях ДОЛЖНА располагаться в той же строке, что и сама конструкция, а закрывающая фигурная скобка ДОЛЖНА располагаться на следующей строке после тела конструкции.
  • После открывающей круглой скобки и перед закрывающей круглой скобкой в управляющих конструкциях НЕ ДОЛЖНО быть пробела.

1.1. Пример

Следующий пример охватывает часть из вышеописанных правил:

<?php
 
namespace Vendor\Package;
 
use FooInterface;
use BarClass as Bar;
use OtherVendor\OtherPackage\BazClass;
 
class Foo extends Bar implements FooInterface
{
    public function sampleFunction($a, $b = null)
    {
        if ($a === $b) {
            bar();
        } elseif ($a > $b) {
            $foo->bar($arg1);
        } else {
            BazClass::bar($arg2, $arg3);
        }
    }
 
    final public static function bar()
    {
        // тело метода
    }
}

2. Основные положения

2.1. Базовый стандарт оформления кода

Код ДОЛЖЕН быть оформлен согласно всем правилам, указанным в стандарте PSR-1.

2.2. Файлы

  • Во всех файлах с PHP-кодом ДОЛЖЕН быть использован Unix-вариант переноса строк (Unix linefeed, т.е. \n).
  • В конце каждого файла с PHP-кодом ДОЛЖНА быть одна пустая строка.
  • Закрывающий тег ?> ДОЛЖЕН отсутствовать в файлах, содержащих только PHP-код.

2.3. Строки

  • НЕ ДОЛЖНО быть жёсткого ограничения длины строки.
  • Мягкое ограничение длины строки ДОЛЖНО составлять 120 символов; автоматические системы проверки стиля ДОЛЖНЫ выдавать предупреждение при превышении этого ограничения, но НЕ ДОЛЖНЫ считать это ошибочной ситуацией.
  • СЛЕДУЕТ стараться, чтобы длина строки составляла 80 символов или менее; более длинные строки СЛЕДУЕТ разбивать на несколько отдельных строк, длина каждой из которых не превышала бы 80 символов.
  • В конце непустых строк НЕ ДОЛЖНО быть пробелов.
  • Пустые строки МОГУТ быть добавлены в код для повышения удобочитаемости и разделения блоков кода.
  • В одной строке НЕ ДОЛЖНО быть более одного выражения.

2.4. Отступы

Для оформления отступов ДОЛЖНЫ использоваться четыре пробела (но не знак табуляции).

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

2.5. Ключевые слова и константы true / false / null

Ключевые слова PHP ДОЛЖНЫ быть написаны в нижнем регистре.

Константы PHP true, false и null ДОЛЖНЫ быть написаны в нижнем регистре.

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

  • В случае наличия определения пространства имён, после него ДОЛЖНА располагаться одна пустая строка.
  • В случае наличия импорта пространств имён, он ДОЛЖЕН располагаться после определения пространства имён.
  • При реализации импорта каждое пространство имён ДОЛЖНО импортироваться отдельно (со своим ключевым словом use).
  • После блока импорта ДОЛЖНА быть одна пустая строка.

Пример:

<?php
 
namespace Vendor\Package;
 
use FooClass;
use BarClass as Bar;
use OtherVendor\OtherPackage\BazClass;
 
// ... далее следует PHP-код ...

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

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

4.1. Наследование и реализация

  • Ключевые слова extends и implements ДОЛЖНЫ находиться на той же строке, на которой находится имя класса.
  • Открывающая фигурная скобка в определении класса ДОЛЖНА располагаться на новой строке, а закрывающая фигурная скобка ДОЛЖНА располагаться на следующей строке после тела класса.
<?php
 
namespace Vendor\Package;
 
use FooClass;
use BarClass as Bar;
use OtherVendor\OtherPackage\BazClass;
 
class ClassName extends ParentClass implements \ArrayAccess, \Countable
{
    // константы, свойства, методы
}
  • Список реализуемых интерфейсов МОЖЕТ быть разделён на несколько строк, каждая из которых дополнена слева одним отступом (четырьмя пробелами). В таком случае первый элемент списка интерфейсов ДОЛЖЕН начинаться с новой строки, и в каждой строке ДОЛЖЕН быть указан только один интерфейс.
<?php
 
namespace Vendor\Package;
 
use FooClass;
use BarClass as Bar;
use OtherVendor\OtherPackage\BazClass;
 
class ClassName extends ParentClass implements
    \ArrayAccess,
    \Countable,
    \Serializable
{
    // константы, свойства, методы
}

4.2. Свойства

  • Область видимости ДОЛЖНА быть явно указана для каждого свойства.
  • При определении свойства НЕ ДОЛЖНО применяться ключевое слово var.
  • В одном выражении НЕ ДОЛЖНО быть определено более одного свойства.
  • Одиночный знак подчёркивания в начале имени свойства НЕ СЛЕДУЕТ использовать как признак защищённой (protected) или приватной (private) области видимости.

В общем случае определение свойства выглядит так:

<?php
 
namespace Vendor\Package;
 
class ClassName
{
    public $foo = null;
}

4.3. Методы

  • Область видимости ДОЛЖНА быть явно указана для каждого метода.
  • Одиночный знак подчёркивания в начале имени метода НЕ СЛЕДУЕТ использовать как признак защищённой (protected) или приватной (private) области видимости.
  • После имени метода НЕ ДОЛЖНО быть пробела. Открывающая фигурная скобка ДОЛЖНА находиться на отдельной строке, а закрывающая фигурная скобка ДОЛЖНА находиться на следующей за телом метода строке. НЕ ДОЛЖНО быть пробелов после открывающей и перед закрывающей круглыми скобками в определении метода.

В общем случае определение метода выглядит так. Обратите внимание на круглые скобки, запятые, пробелы и фигурные скобки:

<?php
 
namespace Vendor\Package;
 
class ClassName
{
    public function fooBarBaz($arg1, &$arg2, $arg3 = [])
    {
        // тело метода
    }
}

4.4. Аргументы методов

  • В списке аргументов НЕ ДОЛЖНО быть пробела перед запятыми, но ДОЛЖЕН быть пробел после каждой запятой.
  • Аргументы со значениями по умолчанию ДОЛЖНЫ располагаться в конце списка (после аргументов без значений по умолчанию). {Примечание переводчика: и тут дело не в красоте, нарушение этого правила может привести ко вполне явным ошибкам выполнения программы, когда аргументу без значения по умолчанию «не хватит» значения при вызове метода.}
<?php
 
namespace Vendor\Package;
 
class ClassName
{
    public function foo($arg1, &$arg2, $arg3 = [])
    {
        // тело метода
    }
}
  • Список аргументов МОЖЕТ быть разделён на несколько строк, каждая из которых дополнена слева одним отступом (четырьмя пробелами). В таком случае первый элемент списка аргументов ДОЛЖЕН начинаться с новой строки, и в каждой строке ДОЛЖЕН быть указан только один аргумент.
  • В случае, если список аргументов разделён на несколько строк, закрывающая круглая скобка и открывающая фигурная скобка ДОЛЖНЫ располагаться вместе на своей отдельной строке, а между ними должен быть один пробел.
<?php
 
namespace Vendor\Package;
 
class ClassName
{
    public function aVeryLongMethodName(
        ClassTypeHint $arg1,
        &$arg2,
        array $arg3 = []
    ) {
        // тело метода
    }
}

4.5. Ключевые слова abstract, final и static

  • Ключевые слова abstract и final, в случае их наличия, ДОЛЖНЫ располагаться перед указанием области видимости.
  • Ключевое слово static, в случае его наличия, ДОЛЖНО располагаться после указания области видимости.
<?php
 
namespace Vendor\Package;
 
abstract class ClassName
{
    protected static $foo;
 
    abstract protected function zim();
 
    final public static function bar()
    {
        // тело метода
    }
}

4.6. Вызовы методов и функций

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

<?php
bar();
$foo->bar($arg1);
Foo::bar($arg2, $arg3);

Список аргументов МОЖЕТ быть разделён на несколько строк, каждая из которых дополнена слева одним отступом (четырьмя пробелами). В таком случае первый элемент списка аргументов ДОЛЖЕН начинаться с новой строки, и в каждой строке ДОЛЖЕН быть указан только один аргумент.

<?php
$foo->bar(
    $longArgument,
    $longerArgument,
    $muchLongerArgument
);

5. Управляющие конструкции

Общие правила оформления управляющих конструкций:

  • После ключевого слова, определяющего управляющую конструкцию, ДОЛЖЕН быть один пробел.
  • После открывающих круглых скобок НЕ ДОЛЖНО быть пробелов.
  • Перед закрывающими круглыми скобками НЕ ДОЛЖНО быть пробелов.
  • Между закрывающей круглой скобкой и открывающей фигурной скобкой ДОЛЖЕН быть один пробел.
  • Тело конструкции ДОЛЖНО быть дополнено одним отступом (четырьмя пробелами).
  • Закрывающая фигурная скобка ДОЛЖНА располагаться на следующей строке после тела конструкции.

Тело каждой управляющей конструкции ДОЛЖНО быть заключено в фигурные скобки. Это позволяет стандартизировать внешний вид управляющих конструкций с снизить риск возникновения ошибок при добавлении новых строк в тело конструкции.

5.1. Конструкции if, elseif и else

Конструкция if выглядит следующим образом. Обратите внимание на круглые скобки, пробелы и фигурные скобки, а также на тот факт, что слова else и elseif располагаются в той же строке, что и закрывающая фигурная скобка предшествующего тела конструкции.

<?php
if ($expr1) {
    // тело if
} elseif ($expr2) {
    // тело elseif
} else {
    // тело else
}

Ключевое слово elseif СЛЕДУЕТ использовать вместо отдельного сочетания else и if. Так конструкция будет представлять собой одно слово.

5.2. Конструкции switch и case

Конструкция switch выглядит следующим образом. Обратите внимание на круглые скобки, пробелы и фигурные скобки. Выражение case ДОЛЖНО быть смещено на один отступ (четыре пробела) от switch, а ключевое слово break (или иное слово, обозначающее выход из конструкции) ДОЛЖНО располагаться на том же уровне отступов, что и тело case. В том случае, когда в непустом теле case умышленно не используется break, ДОЛЖЕН быть комментарий в стиле // no break.

<?php
switch ($expr) {
    case 0:
        echo 'First case, with a break';
        break;
    case 1:
        echo 'Second case, which falls through';
        // no break
    case 2:
    case 3:
    case 4:
        echo 'Third case, return instead of break';
        return;
    default:
        echo 'Default case';
        break;
}

5.3. Конструкции while и do while

Конструкция while выглядит следующим образом. Обратите внимание на круглые скобки, пробелы и фигурные скобки.

<?php
while ($expr) {
    // тело конструкции
}

Соответственно, конструкция do while выглядит следующим образом. Обратите внимание на круглые скобки, пробелы и фигурные скобки.

<?php
do {
    // тело конструкции
} while ($expr);

5.4. Конструкция for

Конструкция for выглядит следующим образом. Обратите внимание на круглые скобки, пробелы и фигурные скобки.

<?php
for ($i = 0; $i < 10; $i++) {
    // тело for
}

5.5. Конструкция foreach

Конструкция foreach выглядит следующим образом. Обратите внимание на круглые скобки, пробелы и фигурные скобки.

<?php
foreach ($iterable as $key => $value) {
    // тело foreach
}

5.6. Конструкция try catch

Блоки конструкции try catch выглядят следующим образом. Обратите внимание на круглые скобки, пробелы и фигурные скобки.

<?php
try {
    // тело try
} catch (FirstExceptionType $e) {
    // тело catch
} catch (OtherExceptionType $e) {
    // тело catch
}

6. Замыкания

  • Замыкания ДОЛЖНЫ описываться с использованием пробела после ключевого слова function и пробелами до и после ключевого слова use.
  • Открывающая фигурная скобка ДОЛЖНА располагаться на одной строке с именем замыкания строке, а закрывающая фигурная скобка ДОЛЖНА располагаться на следующей строке после тела замыкания.
  • После открывающей круглой скобки и перед закрывающей круглой скобкой в списке аргументов или переменных НЕ ДОЛЖНО быть пробела.
  • В списке аргументов или переменных НЕ ДОЛЖНО быть пробелов перед запятыми, но ДОЛЖЕН быть один пробел после каждой запятой.
  • Аргументы замыкания со значениями по умолчанию ДОЛЖНЫ располагаться в конце списка (после аргументов без значений по умолчанию). {Примечание переводчика: и тут дело не в красоте, нарушение этого правила может привести ко вполне явным ошибкам выполнения программы, когда аргументу без значения по умолчанию «не хватит» значения при вызове.}

Описание замыкания выглядит следующим образом. Обратите внимание на круглые скобки, запятые, пробелы и фигурные скобки.

<?php
$closureWithArgs = function ($arg1, $arg2) {
    // тело
};
 
$closureWithArgsAndVars = function ($arg1, $arg2) use ($var1, $var2) {
    // тело
};

Список аргументов и переменных МОЖЕТ быть разделён на несколько строк, каждая из которых дополнена слева одним отступом (четырьмя пробелами). В таком случае первый элемент списка ДОЛЖЕН начинаться с новой строки, и в каждой строке ДОЛЖЕН быть указан только один элемент.

Когда последний список (аргументов или переменных) разделён на несколько строк, закрывающая круглая скобка и открывающая фигурная скобка ДОЛЖНЫ располагаться на одной строке и быть разделены одним пробелом.

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

<?php
$longArgs_noVars = function (
    $longArgument,
    $longerArgument,
    $muchLongerArgument
) {
   // тело
};
 
$noArgs_longVars = function () use (
    $longVar1,
    $longerVar2,
    $muchLongerVar3
) {
   // тело
};
 
$longArgs_longVars = function (
    $longArgument,
    $longerArgument,
    $muchLongerArgument
) use (
    $longVar1,
    $longerVar2,
    $muchLongerVar3
) {
   // тело
};
 
$longArgs_shortVars = function (
    $longArgument,
    $longerArgument,
    $muchLongerArgument
) use ($var1) {
   // тело
};
 
$shortArgs_longVars = function ($arg) use (
    $longVar1,
    $longerVar2,
    $muchLongerVar3
) {
   // тело
};

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

<?php
$foo->bar(
    $arg1,
    function ($arg2) use ($var1) {
        // тело
    },
    $arg3
);

7. Заключение

В этом руководстве намеренно не рассмотрены правила и лучшие практики по оформлению многих элементов, список которых включает в себя, но не ограничивается следующим:

  • Определение глобальных переменных и констант.
  • Определение функций.
  • Использование операторов и присваивание.
  • Межстрочное выравнивание.
  • Блоки комментариев и документации.
  • Префиксы и суффиксы в именах классов.
  • Лучшие практики.

В будущем данные рекомендации МОГУТ быть пересмотрены и расширены, чтобы охватить те или иные элементы кода и практики оформления.

Приложение A. Опрос

Примечание переводчика: в оригинальном тексте стандарта содержится приложение с результатами опроса, на основе которого были приняты те или иные решения. Приложение представляет собой большой массив неудобочитаемых данных и не несёт явной пользы для понимания стандарта. Вы всегда можете ознакомиться с представленными там данными здесь.

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

Основная цель данного документа – позволить библиотекам получать объект 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, знак подчёркивания (_) и точка (.). Остальные символы зарезервированы для будущих изменений в спецификации плейсхолдеров.
  • Разработчики МОГУТ реализовывать со значениями плейсхолдеров различные стратегии экранирования и преобразования при отображении протокола. Пользователям НЕ НУЖНО предварительно экранировать данные в значениях плейсхолдеров, т.к. заранее не известно, как и в каком контексте содержащаяся в них информация может быть использована.

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

<?php
/**
* Подстановка значений в плейсхолдеры сообщения.
*/
function interpolate($message, array $context = array())
{
  // Построение массива подстановки с фигурными скобками
  // вокруг значений ключей массива context.
  $replace = array();
  foreach ($context as $key => $val) {
      $replace['{' . $key . '}'] = $val;
  }

  // Подстановка значений в сообщение и возврат результата.
  return strtr($message, $replace);
}

// Сообщение с плейсхолдером, имя которого обрамлено
// фигурными скобками.
$message = "User {username} created";

// Массив context с данными для замены плейсхолдера на
// итоговое значение.
$context = array('username' => 'bolivar');

// Результат: "User bolivar created"
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

<?php
 
namespace Psr\Log;
 
/**
 * Описывает систему протоколирования.
 *
 * Сообщение ДОЛЖНО быть строкой или объектом, реализующим __toString().
 *
 * Сообщение МОЖЕТ содержать плейсхолдеры в виде {foo}, где foo будет
 * заменено на значение элемента массива context с ключом "foo".
 *
 * Массив context может содержать произвольные данные. Единственное
 * предположение, допустимое для разработчиков, заключается в том, что
 * если в массиве переда объект исключения для построения трассировки
 * стека, он ДОЛЖЕН находиться в элементе массива с ключом "exception".
 *
 * См. полную спецификацию интерфейса здесь: https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-3-logger-interface.md
 */
interface LoggerInterface
{
    /**
     * Авария, система неработоспособна.
     *
     * @param строка $message
     * @param массив $context
     * @return null
     */
    public function emergency($message, array $context = array());
 
    /**
     * Тревога, меры должны быть предприняты незамедлительно.
     *
     * Примеры: весь веб-сайт недоступен, БД недоступна и т.д. Вплоть до
     * отправки SMS-сообщения ответственному лицу.
     *
     * @param строка $message
     * @param массив $context
     * @return null
     */
    public function alert($message, array $context = array());
 
    /**
     * Критическая ошибка, критическая ситуация.
     *
     * Пример: недоступен компонент приложения, неожиданное исключение.
     *
     * @param строка $message
     * @param массив $context
     * @return null
     */
    public function critical($message, array $context = array());
 
    /**
     * Ошибка на стадии выполнения, не требующая неотложного вмешательства,
     * но требующая протоколирования и дальнейшего изучения.
     *
     * @param строка $message
     * @param массив $context
     * @return null
     */
    public function error($message, array $context = array());
 
    /**
     * Предупреждение, нештатная ситуация, не являющаяся ошибкой.
     *
     * Пример: использование устаревшего API, неверное использование API,
     * нежелательные эффекты и ситуации, которые, тем не менее,
     * не обязательно являются ошибочными.
     *
     * @param строка $message
     * @param массив $context
     * @return null
     */
    public function warning($message, array $context = array());
 
    /**
     * Замечание, важное событие.
     *
     * @param строка $message
     * @param массив $context
     * @return null
     */
    public function notice($message, array $context = array());
 
    /**
     * Информация, полезные для понимания происходящего события.
     *
     * Пример: авторизация пользователя, протокол взаимодействия с БД.
     *
     * @param строка $message
     * @param массив $context
     * @return null
     */
    public function info($message, array $context = array());
 
    /**
     * Детальная отладочная информация.
     *
     * @param строка $message
     * @param массив $context
     * @return null
     */
    public function debug($message, array $context = array());
 
    /**
     * Протоколирование с произвольным уровнем.
     *
     * @param смешанный $level
     * @param строка $message
     * @param массив $context
     * @return null
     */
    public function log($level, $message, array $context = array());
}

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

<?php
 
namespace Psr\Log;
 
/**
 * Описывает систему, поддерживающую протоколирование.
 */
interface LoggerAwareInterface
{
    /**
     * Устанавливает объект протоколирования в объект
     * системы, поддерживающей протоколирование.
     *
     * @param LoggerInterface $logger
     * @return null
     */
    public function setLogger(LoggerInterface $logger);
}

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

<?php
 
namespace Psr\Log;
 
/**
 * Описывает уровни протоколирования.
 */
class LogLevel
{
    const EMERGENCY = 'emergency';
    const ALERT     = 'alert';
    const CRITICAL  = 'critical';
    const ERROR     = 'error';
    const WARNING   = 'warning';
    const NOTICE    = 'notice';
    const INFO      = 'info';
    const DEBUG     = 'debug';
}

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

1. Обзор

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

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

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

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

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

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

3. Примеры

В таблице ниже представлены примеры соответствий полностью определённого имени класса, префикса пространства имён, базового каталога и итогового пути к файлу.

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

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

1. Обзор

Основной целью этого раздела - является стандарт написания кода, чтобы обеспечить полное и формальное определение стандарта PHPDoc. Этот PSR стандарт отличается от своего предшественника (де-факто PHPDoc стандарта, связанного с PhpDocumentor 1.x), чтобы обеспечить поддержку новых функций на языке PHP и устранения некоторых недостатков своего предшественника.

Этот докумен НЕ:

  • Описывает стандарт для реализации аннотаций с помощью PHPDoc. Несмотря на то, что он делает написание универсальным, что делает возможным создать последующие стандарты PSR, основанные на существующей практике. Смотрите раздел 4.3 для получения дополнительной информации по этой теме.
  • Описываеть лучшие практики или рекомендации по Стандартам кодирования по применению стандарта PHPDoc. Этот документ ограничивается формальной спецификации синтаксиса и намерения.

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

  • "PHPDoc" представляет собой часть документации, которая содержит информацию по различным аспектам "структурного элемента".
    Важно отметить, что PHPDoc и заголовочный блок являются двумя отдельными сущностями. DocBlock является сочетанием DocComment, который является типом комментария и PHPDoc сущность. Это PHPDoc объект, который содержит синтаксис, как описано в данном описании, такие как описание и метки.
  • "Структурный элемент" представляет собой набор программных конструкций, которым могут предшествовать коментарии DocBlock. Сборник содержит следующие конструкции:
    • file
    • require(_once)
    • include(_once)
    • class
    • interface
    • trait
    • function (including methods)
    • property
    • constant
    • variables, как местные, так и глобальные.
  • РЕКОМЕНДУЕТСЯ писать "структурный элемент" с DocBlock, где он определен, а не с каждым использованием. Обычной практикой является написание DocBlock перед структурным элементом, но он также может быть отделен неопределенным количество пустых строк.

    Пример:

    <?php
     
    /** @var int $int This is a counter. */
    $int = 0;
    
    // there should be no docblock here
    $int++;
    

    или:

    <?php
     
    /**
    * This class acts as an example on where to position a DocBlock.
    */
    class Foo
    {
      /** @var string|null $title contains a title for the Foo with a max. length of 24 characters */
      protected $title = null;
    
    
      /**
       * Sets a single-line title.
       *
       * @param string $title A text with a maximum of 24 characters.
       *
       * @return void
       */
      public function setTitle($title)
      {
          // there should be no docblock here
          $this->title = $title;
      }
    }
    

    Примером использования, который выходит за рамки настоящего стандарта является документирование переменной в цикле; применительно как авто завершение структурирования IDE цикла

    Настоящий стандарт не распространяется на этот конкретный экземпляр как цикл, указание не рассматривается как "структурный элемент", но указание управлет потоком.

    <?php
     
    /** @var \Sqlite3 $sqlite */
    foreach($connections as $sqlite) {
        // there should be no docblock here
        $sqlite->open('/my/database\/path');
        <...>
    }
  • "DocComment" представляет собой особый тип комментария, который ДОЛЖЕН
    • начинаться с последовательности символов /** за которым следует символ пробела
    • заканчиваются */ и
    • иметь ноль или более строк между ними.

    В случае когда DocComment охватывает несколько строк, то каждая строка должна начинаться со звездочки (*), которые следует равнять в соответствие с первой звездочкой вступительной фразы.

    Пример "В одну строчку":

    <?php
     
    /** <...> */
    
  • "Многостроковый пример":

    <?php
     
      /**
       * <...>
       */
    
  • "DocBlock"-ом является "DocComment", содержащий одну "PHPDoc" структуру и представляет собой основной источник в-представлении.
  • "Tag" представляет собой единый кусок мета информации относительно "структурного элемента" или его компонента.
  • "Inline PHPDoc" является "PHPDoc"-ом, что связано с "Tag"-ом вместо "структурного элемента". Он заменяет часть описания элемента "Tag".
  • "Type" является определением того, какой тип данных связан с элементом. Это обычно используется при определении точных значений аргументов, констант, свойств и многого другого.

    Смотрите Приложение A для получения более подробной информации о типах.

  • "Семантическая версия" относится к определению установленой в спецификации Semantic Versioning Specification 2.0.0.
  • "FQSEN" это аббревиатура Полного Определенного Структурного Названия Элемена (Fully Qualified Structural Element Name). Эта запись расширяется на полное имя класса и добавляет обозначение для идентификации членов class/interface/trait повторно применяемых принципов FQCN в Interfaces, Traits, Functions и global Constants.
  • Эти обозначения могут быть использованы по типу "Структурный элемент (Structural Element)":

    Namespace: \My\Space Function: \My\Space\myFunction() Constant: \My\Space\MY_CONSTANT Class: \My\Space\MyClass Interface: \My\Space\MyInterface Trait: \My\Space\MyTrait Method: \My\Space\MyClass::myMethod() Property: \My\Space\MyClass::$my_property Class Constant: \My\Space\MyClass::MY_CONSTANT

    FQSEN имеет следующее ABNF определение:

    <?php
     
        FQSEN    = fqnn / fqcn / constant / method / property  / function
        fqnn     = "\" [name] *("\" [name])
        fqcn     = fqnn "\" name
        constant = (fqnn "\" / fqcn "::") name
        method   = fqcn "::" name "()"
        property = fqcn "::$" name
        function = fqnn "\" name "()"
        name     = (ALPHA / "_") *(ALPHA / DIGIT / "_")
    

1. Обзор

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

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

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

2. Цель

Цель данного PSR: показать разработчикам создание кэш-зависимых библиотек, которые могут быть интегрированы в существующие структуры и системы без необходимости заранее предопределять.

3. Определения

  • Calling Library - библиотеки или код, которые предоставляют услуги кэширования. Эти библиотеки будут использовать службы кэширования, которые реализуют интерфейсы этого стандарта, но не знают о реализации этих служб кэширования.
  • Implementing Library - эта библиотека отвечает за реализацию этого стандарта для того, чтобы обеспечить сервисы кэширования для любой Calling Library. Реализация библиотеки ДОЛЖНА предоставлять классы, реализующие Cache\CacheItemPoolInterface и Cache\CacheItemInterface интерфейсы. Реализация библиотеки должны поддерживаться при минимальной функциональности TTL, как описано ниже со всеми вытекающими.
  • TTL - время жизни (TTL), момент элемента от времени создания до окончания времени жизни, далее он считается устаревшим. TTL обычно определяется целым числом, представляющим время в секундах, или DateInterval объекта.
  • Expiration - фактическое время, когда элемент создан и зарегестрирован. Он, как правило, определяется путем добавления TTL к тому времени, когда объект сохраняется, но может также быть явно установлен с объектом DateTime.

    Элемент с 300 секундами TTL, созданый в 1:30:00, будет иметь окончание 1:35:00.

    В реализации библиотеки ВОЗМОЖНО истечение времени элемента до вызова Окончания срока, но они должно ссылаться на пункт окончания срока. Если вызывающая библиотека запрашивает пункт, чтобы быть сохраненной, но не определяет время истечения срока действия, или определяет нулевое время истечения или TTL, библиотека исполнителя может использовать сконфигурированную длительность по умолчанию. Если длительность по умолчанию не установлена, исполнительная библиотека должна интерпретировать это как запрос к данному пункту кэша всегда, или до тех пор, пока поддерживается основная реализация.

  • Key - строка, по крайней мере один символ, который однозначно идентифицирует элемент кэша. Реализация библиотеки должны поддерживать ключи, состоящие из символов A-Z, a-z, 0-9, _, и . в любом порядке в кодировке UTF-8 и длиной до 64 символов. Реализация библиотеки могут поддерживать дополнительные символы и кодировки или более длинные, но должны поддерживать минимум символов (1). Библиотеки несут ответственность за их собственной истечение ключевых строк в зависимости от обстоятельств, но они должны быть в состоянии вернуть первоначальный неизмененную ключевую строку. Следующие символы зарезервированы для будущих расширений и не должны поддерживаться за счет реализации библиотеки: {} () / \ @:
  • Hit - хит кэша происходит, когда вызов библиотеки запрашивает объект по ключу и совпадающее значение найдено для этого ключа, и время жизни этого значение не истекло, а значение не недействительно по какой-то другой причине. Вызывающие библиотеки должны убедиться, проверить isHit() по всем get() вызовам.
  • Miss - промах кэша противоположность попаданию в кэш. Промах кэша происходит, когда вызов библиотеки запрашивает объект по ключу, и это значение не найдено для этого ключа или значение было найдено, но истекло TTL, или значение является недействительным по какой-то другой причине. Просроченное значение всегда должно рассматриваться как промах кэша.
  • Deferred - отложенный кэш сохранения указывает на то, что элемент кэша не может быть сохранен непосредственно в pull. Пул объекта может задержать сохраняющихся отложенный элемент кэша для того, чтобы воспользоваться преимуществами bulk-set набора операций, поддерживаемых некоторыми механизмами хранения. A pull должен гарантировать, что любые отложенные элементы кэша в конечном итоге сохранились и данные не будут потеряны, и могут сохраняться перед их Вызывающими библиотеками запросов. Когда вызовается библиотека commit() - все оставшиеся отложенные элементы должны быть сохранены. Реализация библиотеки может любой. Целесообразно определить, когда сохраняются отсроченные элементы, такие, как объект деструктор, сохраняющий все на Save(), timeout или Max-items проверки или использовать любую другую подходящую логику. Запросы на элемента кэша, которые были отсроченные ДОЛЖНЫ возвращать отложенный элемент до сохранения пункта.
CRGHOME PRESENT