diff --git a/docs/guide-ru/rest-routing.md b/docs/guide-ru/rest-routing.md index 59a94605ce..0bf9fac8e8 100644 --- a/docs/guide-ru/rest-routing.md +++ b/docs/guide-ru/rest-routing.md @@ -73,6 +73,19 @@ ``` Как вы могли заметить, ID контроллера `user` в этих точках входа используется в форме множественного числа (как `users`). -Это происходит потому, что [[yii\rest\UrlRule]] автоматически приводит идентификаторы контроллеров к множественной форме для использования в точках входа. -Вы можете отключить такое поведение, назначив свойству [[yii\rest\UrlRule::pluralize]] значение false, или, если вы хотите использовать -какие-то особые имена, вы можете настроить свойство [[yii\rest\UrlRule::controller]]. +Это происходит потому, что [[yii\rest\UrlRule]] автоматически приводит идентификаторы контроллеров к множественной форме. +Вы можете отключить такое поведение, назначив свойству [[yii\rest\UrlRule::pluralize]] значение false. + +> Информация: Приведение ID контроллера к множественной форме производится в методе [[yii\helpers\Inflector::pluralize()]]. + При этом соблюдаются правила английского языка. Например, `box` будет преобразован в `boxes`, а не в `boxs`. + +В том случае, если автоматическое приведение к множественному числу вам не подходит, вы можете настроить +свойство [[yii\rest\UrlRule::controller]], где указать явное соответствие имени в URL и ID контроллера. +Например, код ниже ставит в соответствие имя `u` и ID контроллера `user`. + +```php +[ + 'class' => 'yii\rest\UrlRule', + 'controller' => ['u' => 'user'], +] +``` diff --git a/docs/guide-ru/rest-versioning.md b/docs/guide-ru/rest-versioning.md index 1f780e110a..ae3513a2b1 100644 --- a/docs/guide-ru/rest-versioning.md +++ b/docs/guide-ru/rest-versioning.md @@ -1,17 +1,28 @@ Версионирование =============== -Свои API вам следует версионировать. В отличие от Web-приложений, где у вас есть полный контроль и над серверным, и над клиентским кодом, -при работе с API у вас обычно нет контроля над клиентским кодом, работающим с вашими API. Поэтому всегда, когда это только возможно, -должна поддерживаться обратная совместимость API, и если в API должны быть внесены изменения, ломающие обратную совместимость, -следует увеличить номер версии. Почитайте про [семантическое версионирование](http://semver.org/) -для получения более подробной информации о возможных способах нумерации различных версий ваших API. +Хороший API должен быть *версионирован*: изменения и новые возможности реализуются в новых версиях API, а не в одной и +той же версии. В отличие от Web-приложений, где у вас есть полный контроль и над серверным, и над клиентским кодом, +API используются клиентами, код которых вы не контролируете. Поэтому, обратная совместимость (BC) должна по возможности +сохраняться. Если ломающее её изменение необходимо, делать его нужно в новой версии API. Существующие клиенты могут +продолжать использовать старую, совместимую с ними версию API. Новые или обновлённые клиенты могут использовать новую +версию. + Общей практикой при реализации версионирования API является включение номера версии в URL-адрес вызова API-метода. Например, `http://example.com/v1/users` означает вызов API `/users` версии 1. Другой способ версионирования API, получивший недавно широкое распространение, состоит в добавлении номера версии в HTTP-заголовки запроса, обычно в заголовок `Accept`: +> Подсказка: Чтобы узнать больше о выборе версий обратитесь к [Semantic Versioning](http://semver.org/). + +Один из типичных способов реализации версионирования — указание версии в URL. Например, `http://example.com/v1/users` +соответствует `/users` версии 1. + +Ещё один способ, ставший сейчас популярным — передача версии через заголовок HTTP. Чаще всего для этого используется +заголовок `Accept`: + + ``` // как параметр Accept: application/json; version=v1 @@ -51,6 +62,7 @@ api/ models/ User.php Post.php + Module.php v2/ controllers/ UserController.php @@ -58,6 +70,7 @@ api/ models/ User.php Post.php + Module.php ``` Конфигурация вашего приложения могла бы выглядеть так: @@ -66,10 +79,10 @@ api/ return [ 'modules' => [ 'v1' => [ - 'basePath' => '@app/modules/v1', + 'class' => 'app\modules\v1\Module', ], 'v2' => [ - 'basePath' => '@app/modules/v2', + 'class' => 'app\modules\v2\Module', ], ], 'components' => [ @@ -89,7 +102,7 @@ return [ В результате `http://example.com/v1/users` возвратит список пользователей API версии 1, в то время как `http://example.com/v2/users` вернет список пользователей версии 2. -При использовании модулей код API различных мажорных версий может быть хорошо изолирован. И по-прежнему возможно +Благодаря использованию модулей код API различных мажорных версий может быть хорошо изолирован. И по-прежнему возможно повторное использование кода между модулями через общие базовые классы и другие разделяемые классы. Для работы с минорными номерами версий вы можете использовать преимущества согласования содержимого, @@ -100,8 +113,8 @@ return [ Например, если запрос посылается с HTTP-заголовком `Accept: application/json; version=v1`, то после согласования содержимого свойство [[yii\web\Response::acceptParams]] будет содержать значение `['version' => 'v1']`. -На основе информации о версии из `acceptParams` вы можете написать условный код в таких местах, -как действия, классы ресурсов, сериализаторы и т.д. +На основе информации о версии из `acceptParams` вы можете выбирать поведение в действиях, классах ресурсов, +сериализаторах и т.д. Так как минорные версии требуют поддержания обратной совместимости, будем надеяться, что в вашем коде не так уж много проверок на номер версии. В противном случае велики шансы, что вам нужна новая мажорная версия. diff --git a/docs/guide-ru/runtime-bootstrapping.md b/docs/guide-ru/runtime-bootstrapping.md index 662e0e6124..c04d2747f9 100644 --- a/docs/guide-ru/runtime-bootstrapping.md +++ b/docs/guide-ru/runtime-bootstrapping.md @@ -27,7 +27,11 @@ участвовать в полном жизненном цикле процесса обработки запроса. Например, если модуль должен зарегистрировать дополнительные правила парсинга URL, то он должен быть указан в свойстве [предзагрузка](structure-applications.md#bootstrap), чтобы новые правила URL были учтены при обработке запроса. -В производственном режиме включите байткод кэшеры, такие как APC, для минимизации времени необходимого на подключение и парсинг php файлов. +В производственном режиме включите байткод кэшеры, такие как [PHP OPcache] или [APC], для минимизации времени +подключения и парсинг php файлов. + +[PHP OPcache]: http://php.net/manual/ru/intro.opcache.php +[APC]: http://php.net/manual/ru/book.apc.php Некоторые большие приложения могут иметь сложную [конфигурацию](concept-configurations.md), которая разделена на несколько мелких файлов. Если это тот самый случай, возможно вам стоит кэшировать весь конфигурационный файл и загружать его прямо из кэша до создания объекта diff --git a/docs/guide-ru/runtime-handling-errors.md b/docs/guide-ru/runtime-handling-errors.md index e9ed110b50..fa7dc10e9d 100644 --- a/docs/guide-ru/runtime-handling-errors.md +++ b/docs/guide-ru/runtime-handling-errors.md @@ -1,35 +1,86 @@ Обработка ошибок ================ -> Раздел в разработке. +В состав Yii входит встроенный [[yii\web\ErrorHandler|обработчик ошибок]], делающий работу с ошибками гораздо более +приятным занятием. А именно: -Обработка ошибок в Yii происходит несколько иначе, чем в обычном PHP. Во-первых, все нефатальные ошибки в Yii преобразуются в *исключения*: +* Все нефатальные ошибки PHP (то есть warning, notice) конвертируются в исключения, которые можно перехватывать. +* Исключения и фатальные ошибки PHP отображаются в режиме отладки с детальным стеком вызовов и исходным кодом. +* Можно использовать для отображения ошибок [действие контроллера](structure-controllers.md#actions). +* Поддерживаются различные форматы ответа. + +По умолчанию [[yii\web\ErrorHandler|обработчик ошибок]] включен. Вы можете выключить его объявив константу +`YII_ENABLE_ERROR_HANDLER` со значением false во [входном скрипте](structure-entry-scripts.md) вашего приложения. + + +## Использование обработчика ошибок + +[[yii\web\ErrorHandler|Обработчик ошибок]] регистрируется в качестве [компонента приложения](structure-application-components.md) +с именем `errorHandler`. Вы можете настраивать его следующим образом: + +```php +return [ + 'components' => [ + 'errorHandler' => [ + 'maxSourceLines' => 20, + ], + ], +]; +``` + +С приведённой выше конфигурацией на странице ошибки будет отображаться до 20 строк исходного кода. + +Как уже было упомянуто, обработчик ошибок конвертирует все нефатальные ошибки PHP в перехватываемые исключения. +Это означает что можно поступать с ошибками следующим образом: ```php -use yii\base\ErrorException; use Yii; +use yii\base\ErrorException; try { 10/0; } catch (ErrorException $e) { - Yii::warning("Попытка деления на ноль."); + Yii::warning("Деление на ноль."); } // можно продолжать выполнение ``` -Как это видно из примера, вы можете обрабатывать ошибки, используя конструкцию `try`-`catch`. +Если вам необходимо показать пользователю страницу с ошибкой, говорящей ему о том, что его запрос не верен или не +должен был быть сделан, вы можете выкинуть [[yii\web\HttpException|исключение HTTP]], такое как +[[yii\web\NotFoundHttpException]]. Обработчик ошибок корректно выставит статус код HTTP для ответа и использует +подходящий вид страницы ошибки. -Во-вторых, даже фатальные ошибки в Yii показываются в красивом виде. Это значит, что при отладке кода, вы можете отслеживать причины фатальных -ошибок. Это позволяет быстрее находить причины возникших проблем. +```php +use yii\web\NotFoundHttpException; + +throw new NotFoundHttpException(); +``` -Рендеринг ошибок в произвольном действии контроллера ----------------------------------------------------- +## Настройка отобажения ошибок -Обычная страница вывода ошибок Yii не только хороша в разработке, но и приемлема для уже развернутых проектов, если `YII_DEBUG` выключена в начальном загрузочном скрипте `index.php`. Но иногда хочется изменить внешний вид страницы с ошибками, чтобы лучше приспособить ее под свой проект. +[[yii\web\ErrorHandler|Обработчик ошибок]] меняет отображение ошибок в зависимости от значения константы `YII_DEBUG`. +При `YII_DEBUG` равной true (режим отладки), обработчик ошибок будет отображать для облегчения отладки детальный стек +вызовов и исходный код. При `YII_DEBUG` равной false отображается только сообщение об ошибке, тем самым не позволяя +получить информацию о внутренностях приложения. -Самый легкий способ создать свою страницу для отображения ошибок - использовать свое действие (action) для рендеринга сообщений об ошибке. -Сначала нужно дать приложению понять, что вы хотите использовать свое действие для обработки ошибок. Для этого нужно сконфигурировать компонент `errorHandler` в конфигурационном файле приложения: +> Информация: Если исключение является наследником [[yii\base\UserException]], стек вызовов не отображается вне + зависимости от значения `YII_DEBUG` так как такие исключения считаются ошибками пользователя и исправлять что-либо + разработчику не требуется. + +По умолчанию [[yii\web\ErrorHandler|обработчик ошибок]] показывает ошибки используя два [представления](structure-views.md): + +* `@yii/views/errorHandler/error.php`: используется для отображения ошибок БЕЗ стека вызовов. + При `YII_DEBUG` равной false используется только это преставление. +* `@yii/views/errorHandler/exception.php`: используется для отображения ошибок СО стеком вызовов. + +Вы можете настроить свойства [[yii\web\ErrorHandler::errorView|errorView]] и [[yii\web\ErrorHandler::exceptionView|exceptionView]] +для того, чтобы использовать свои представления. + +### Использование действий для отображения ошибок + +Лучшим способом изменения отображения ошибок является использование [действий](structure-controllers.md) путём +конфигурирования свойства [[yii\web\ErrorHandler::errorAction|errorAction]] компонента `errorHandler`: ```php // ... @@ -40,49 +91,120 @@ try { ], ] ``` -С вышеуказанной конфигурацией, если происходит ошибка, Yii запустит действие `error` контроллера `site`. Это действие запрашивает у компонента `errorHandler`, было ли выброшено исключение, и, если да, отображает соответствующий вид, передавая ему объект исключения в качестве параметра. + +Свойство [[yii\web\ErrorHandler::errorAction|errorAction]] принимает [маршрут](structure-controllers.md#routes) +действия. Конфигурация выше означает, что для отображения ошибки без стека вызовов будет использовано действие `site/error`. + +Само действие можно реализовать следующим образом: + +```php +namespace app\controllers; + +use Yii; +use yii\web\Controller; + +class SiteController extends Controller +{ + public function actions() + { + return [ + 'error' => [ + 'class' => 'yii\web\ErrorAction', + ], + ]; + } +} + ``` + +Приведённый выше код задаёт действие `error` используя класс [[yii\web\ErrorAction]], который рендерит ошибку используя +отображение `error`. + +Вместо использования [[yii\web\ErrorAction]] вы можете создать действие `error` как обычный метод: + ```php public function actionError() { - $exception = \Yii::$app->errorHandler->exception; + $exception = Yii::$app->errorHandler->exception; if ($exception !== null) { return $this->render('error', ['exception' => $exception]); } } ``` -После создания `action` нужно создать соответствующий вид, который и будет отображать информацию об исключении. Объект исключения, передаваемый в вид, имеет - следующие свойства: +Вы должны создать файл представления `views/site/error.php`. В этом файле, если используется [[yii\web\ErrorAction]], +вам доступны следующие переменные: -- `statusCode`: HTTP статус (например, 403, 500). Доступен только для [[yii\web\HttpException|HTTP exceptions]]. -- `code`: код исключения. -- `message`: сообщение об ошибке. -- `file`: имя файла PHP скрипта, в котором произошла ошибка. -- `line`: номер строки в коде, где произошла ошибка. -- `trace`: стэк вызовов, приведших к ошибке. +* `name`: имя ошибки; +* `message`: текст ошибки; +* `exception`: объект исключения, из которого можно получить дополнительную информацию, такую как статус HTTP, + код ошибки, стек вызовов и т.д. + +> Информация: Если вы используете шаблоны приложения [basic](start-installation.md) или [advanced](tutorial-advanced-app.md), + действие error и файл представления уже созданы за вас. + +### Изменение формата ответа -Рендеринг ошибок без создания отдельного действия -------------------------------------------------- +Обработчик ошибок отображает ошибки в соответствии с выбранным форматом [ответа](runtime-responses.md). +Если [[yii\web\Response::format|формат ответа]] задан как `html`, будут использованы представления для ошибок и +исключений, как описывалось ранее. Для остальных форматов ответа обработчик ошибок присваивает массив данных, +представляющий ошибку свойству [[yii\web\Response::data]]. Оно далее конвертируется в необходимый формат. Например, +если используется формат ответа `json`, вы получите подобный ответ: -Вместо создания отдельного действия внутри контроллера Site, вы можете просто указать Yii какой класс использовать для обработки ошибок: +``` +HTTP/1.1 404 Not Found +Date: Sun, 02 Mar 2014 05:31:43 GMT +Server: Apache/2.2.26 (Unix) DAV/2 PHP/5.4.20 mod_ssl/2.2.26 OpenSSL/0.9.8y +Transfer-Encoding: chunked +Content-Type: application/json; charset=UTF-8 -```php -public function actions() { - return [ - 'error' => [ - 'class' => 'yii\web\ErrorAction', - ], - ]; + "name": "Not Found Exception", + "message": "The requested resource was not found.", + "code": 0, + "status": 404 } ``` -После задания вышеуказанной связки ошибки с классом обработчиком, создайте вид `views/site/error.php`, который будет использоваться автоматически. -Виду передаются три параметра: +Изменить формат можно в обработчике события `beforeSend` компонента `response` в конфигурации приложения: -- `$name`: название ошибки -- `$message`: сообщение об ошибке -- `$exception`: обрабатываемое исключение +```php +return [ + // ... + 'components' => [ + 'response' => [ + 'class' => 'yii\web\Response', + 'on beforeSend' => function ($event) { + $response = $event->sender; + if ($response->data !== null) { + $response->data = [ + 'success' => $response->isSuccessful, + 'data' => $response->data, + ]; + $response->statusCode = 200; + } + }, + ], + ], +]; +``` -Объект `$exception` имеет те же свойства, которые были указаны ранее. +Приведённый код изменит формат ответа на подобный: + +``` +HTTP/1.1 200 OK +Date: Sun, 02 Mar 2014 05:31:43 GMT +Server: Apache/2.2.26 (Unix) DAV/2 PHP/5.4.20 mod_ssl/2.2.26 OpenSSL/0.9.8y +Transfer-Encoding: chunked +Content-Type: application/json; charset=UTF-8 + +{ + "success": false, + "data": { + "name": "Not Found Exception", + "message": "The requested resource was not found.", + "code": 0, + "status": 404 + } +} +```