@ -84,19 +84,26 @@ Yii поддерживает множество хранилищ кэша:
У всех компонентов кэша один базовый класс [[yii\caching\Cache]] со следующими методами:
* [[yii\caching\Cache::get()|get()]]: возвращает данные по указанному ключу. Если данные не найдены или устарели, то значение `false` будет возвращено;
* [[yii\caching\Cache::get()|get()]]: возвращает данные по указанному ключу. Если данные не найдены или устарели, то
значение `false` будет возвращено;
* [[yii\caching\Cache::set()|set()]]: сохраняет данные по ключу;
* [[yii\caching\Cache::add()|add()]]: сохраняет данные по ключу если такого ключа ещё нет;
* [[yii\caching\Cache::mget()|mget()]]: извлекает сразу несколько элементов данных из кэша по заданным ключам;
* [[yii\caching\Cache::mset()|mset()]]: сохраняет несколько элементов данных. Каждый элемент идентифицируется ключом;
* [[yii\caching\Cache::madd()|madd()]]: сохраняет несколько элементов данных. Каждый элемент идентифицируется ключом. Если ключ уже существует, то сохранения не происходит;
* [[yii\caching\Cache::multiGet()|multiGet()]]: извлекает сразу несколько элементов данных из кэша по заданным ключам;
* [[yii\caching\Cache::multiSet()|multiSet()]]: сохраняет несколько элементов данных. Каждый элемент идентифицируется ключом;
* [[yii\caching\Cache::multiAdd()|multiAdd()]]: сохраняет несколько элементов данных. Каждый элемент идентифицируется ключом.
Если ключ уже существует, то сохранения не происходит;
* [[yii\caching\Cache::exists()|exists()]]: есть ли указанный ключ в кэше;
* [[yii\caching\Cache::flush()|flush()]]: удаляет все данные.
> Примечание: Не кэшируйте непосредственно значение `false`, потому что [[yii\caching\Cache::get()|get()]] использует `false` для случая, когда данные не найдены в кэше. Вы можете обернуть `false` в массив и закэшировать его, чтобы избежать данной проблемы.
> Примечание: Не кэшируйте непосредственно значение `false`, потому что [[yii\caching\Cache::get()|get()]] использует
`false` для случая, когда данные не найдены в кэше. Вы можете обернуть `false` в массив и закэшировать его, чтобы
избежать данной проблемы.
Некоторые кэш-хранилища, например, MemCache или APC, поддерживают получение нескольких значений в пакетном режиме, что может сократить накладные расходы на получение данных. Данную возможность возможно использовать при помощи [[yii\caching\Cache::mget()|mget()]] и [[yii\caching\Cache::madd()|madd()]]. В случае, если хранилище не поддерживает эту функцию, она будет имитироваться.
Некоторые кэш-хранилища, например, MemCache или APC, поддерживают получение нескольких значений в пакетном режиме, что
может сократить накладные расходы на получение данных. Данную возможность возможно использовать при помощи
[[yii\caching\Cache::multiGet()|multiGet()]] и [[yii\caching\Cache::multiAdd()|multiAdd()]]. В случае, если хранилище
не поддерживает эту функцию, она будет имитироваться.
Так как [[yii\caching\Cache]] реализует `ArrayAccess` - следовательно компонент кэша можно использовать как массив:
В ходе разработки и ведения баз данных приложений, которые управляют данными, структуры используемых баз данных развиваются, как и исходный код приложений. Например, при разработке приложения, в будущем может оказаться необходимой новая таблица; уже после того, как приложение будет развернуто в рабочем режиме (продакшене), также может быть обнаружено, что для повышения производительности запросов должен быть создан определённый индекс; и так далее.
В связи с тем, что изменение структуры базы данных часто требует изменение исходного кода, yii поддерживает так
@ -156,6 +156,210 @@ class m150101_185401_create_news_table extends Migration
Весь список методов описания типов столбцов доступен в API документации [[yii\db\SchemaBuilderTrait]].
@ -194,16 +398,22 @@ class m150101_185401_create_news_table extends Migration
}
```
Обратите внимание, что обычно при выполнении нескольких операций в базе данных при помощи метода `safeUp()`, вы должны реализовать обратный порядок исполнения в методе `safeDown()`. В приведенном выше примере мы сначала создали таблицу, а затем вставили строку в `safeUp()`; а в `safeDown()` мы сначала удаляем строку и затем удаляем таблицу.
Обратите внимание, что обычно при выполнении нескольких операций в базе данных при помощи метода `safeUp()`, вы должны
реализовать обратный порядок исполнения в методе `safeDown()`. В приведенном выше примере мы сначала создали таблицу,
а затем вставили строку в `safeUp()`; а в `safeDown()` мы сначала удаляем строку и затем удаляем таблицу.
> Примечание: Не все СУБД поддерживают транзакции. И некоторые запросы к базам данных не могут быть введены в транзакции. Для различных примеров, пожалуйста, обратитесь к [негласным обязательствам](http://dev.mysql.com/doc/refman/5.1/en/implicit-commit.html). В этом случае вместо этих методов вы должны реализовать методы `up()` и `down()`.
> Примечание: Не все СУБД поддерживают транзакции. И некоторые запросы к базам данных не могут быть введены в транзакции.
Для различных примеров, пожалуйста, обратитесь к [негласным обязательствам](http://dev.mysql.com/doc/refman/5.7/en/implicit-commit.html).
В этом случае вместо этих методов вы должны реализовать методы `up()` и `down()`.
### Методы доступа к базе данных <spanid="db-accessing-methods"></span>
Базовый класс миграции [[yii\db\Migration]] предоставляет набор методов, которые позволяют Вам получить доступ и управлять базами данных. Вы можете найти эти методы, их названия аналогичны [методам DAO](db-dao.md), предоставленным в классе [[yii\db\Command]].
Базовый класс миграции [[yii\db\Migration]] предоставляет набор методов, которые позволяют Вам получить доступ и управлять
базами данных. Вы можете найти эти методы, их названия аналогичны [методам DAO](db-dao.md), предоставленным в классе [[yii\db\Command]].
Например, метод [[yii\db\Migration::createTable()]] позволяет создать новую таблицу, подобно методу [[yii\db\Command::createTable()]].
Преимущество методов, описанных при помощи [[yii\db\Migration]] заключается в том, что Вам не нужно явно создавать экземпляр/копию [[yii\db\Command]] и исполнение каждого метода будет автоматически отображать полезные сообщения
Преимущество методов, описанных при помощи [[yii\db\Migration]] заключается в том, что Вам не нужно явно создавать
экземпляр/копию [[yii\db\Command]] и исполнение каждого метода будет автоматически отображать полезные сообщения
говорящие вам, что операции с базой данных выполняются и сколько они идут.
Ниже представлен список всех этих методов доступа к базам данных:
@ -319,33 +529,58 @@ yii migrate/mark 1392853618 # используя вре
Есть несколько способов настроить команду миграции.
### Используя Параметры Командной Строки<spanid="using-command-line-options"></span>
### Используя параметры командной строки<spanid="using-command-line-options"></span>
В команду миграций входит несколько параметров командной строки, которые могут использоваться, для того, чтобы настроить поведение миграции:
В команду миграций входит несколько параметров командной строки, которые могут использоваться, для того, чтобы настроить
поведение миграции:
* `interactive`: логический тип - boolean (по умолчанию true). Указывает, следует ли выполнять миграцию в интерактивном режиме. Если это значение является - true, то пользователю будет выдан запрос, перед выполнением командой определенных действий. Вы можете установить это значение в false если команда используется в фоновом режиме.
* `interactive`: логический тип - boolean (по умолчанию true). Указывает, следует ли выполнять миграцию в интерактивном
режиме. Если это значение является - true, то пользователю будет выдан запрос, перед выполнением командой определенных
действий. Вы можете установить это значение в false если команда используется в фоновом режиме.
* `migrationPath`: строка - string (по умолчанию `@app/migrations`). Указывает каталог для хранения всех файлов классов миграций. Этот параметр может быть определён либо как путь до директории, либо как [псевдоним](concept-aliases.md) пути. Обратите внимание, что данный каталог должен существовать, иначе команда будет выдавать ошибку.
* `migrationPath`: строка - string (по умолчанию `@app/migrations`). Указывает каталог для хранения всех файлов классов
миграций. Этот параметр может быть определён либо как путь до директории, либо как [псевдоним](concept-aliases.md) пути.
Обратите внимание, что данный каталог должен существовать, иначе команда будет выдавать ошибку.
* `migrationTable`: строка - string (по умолчанию `migration`). Определяет имя таблицы в базе данных в которой хранится информация о истории миграций. Эта таблица будет автоматически создана командой миграции, если её не существует. Вы также можете создать её вручную, используя структуру `version varchar(255) primary key, apply_time integer`.
* `migrationTable`: строка - string (по умолчанию `migration`). Определяет имя таблицы в базе данных в которой хранится
информация о истории миграций. Эта таблица будет автоматически создана командой миграции, если её не существует.
Вы также можете создать её вручную, используя структуру `version varchar(255) primary key, apply_time integer`.
* `db`: строка - string (по умолчанию `db`). Определяет ID базы данных [компонента приложения](structure-application-components.md).
Этот параметр представляет собой базу данных, которая подвергается миграциям при помощи команды миграций.
* `templateFile`: строка - string (по умолчанию `@yii/views/migration.php`). Указывает путь до файла шаблона, который используется для формирования скелета класса файлов миграции. Этот параметр может быть определён либо как путь до файла, либо как [псевдоним](concept-aliases.md) пути. Файл шаблона - это PHP скрипт, в котором можно использовать предопределенную переменную с именем `$className` для того, чтобы получить имя класса миграции.
* `templateFile`: строка - string (по умолчанию `@yii/views/migration.php`). Указывает путь до файла шаблона, который
используется для формирования скелета класса файлов миграции. Этот параметр может быть определён либо как путь до файла,
либо как [псевдоним](concept-aliases.md) пути. Файл шаблона - это PHP скрипт, в котором можно использовать
предопределенную переменную с именем `$className` для того, чтобы получить имя класса миграции.
* `generatorTemplateFiles`: массив (по умолчанию `[
]`), в котором указаны файлы шаблонов для генерации миграций. Подробнее в разделе «[Генерация миграций](#generating-migrations)».
* `fields`: массив конфигураций столбцов, который используется для генерации кода миграции. По умолчанию пуст. Формат
каждой конфигурации `ИМЯ_СТОЛБЦА:ТИП_СТОЛБЦА:ДЕКОРАТОР_СТОЛБЦА`. Например, `--fields=name:string(12):notNull` даст нам
столбец типа строка размера 12 с ограничением not null.
В следующем примере показано, как можно использовать эти параметры.
Например, если мы хотим перенести модуль `forum`, чьи файлы миграций расположены в каталоге `migrations` данного модуля, для этого мы можем использовать следующую команду:
Например, если мы хотим перенести модуль `forum`, чьи файлы миграций расположены в каталоге `migrations` данного модуля,
для этого мы можем использовать следующую команду:
### Глобальная Настройка Команд <spanid="configuring-command-globally"></span>
### Глобальная настройка команд <spanid="configuring-command-globally"></span>
Вместо того, чтобы каждый раз вводить одинаковые значения параметров миграции, когда вы запускаете команду миграции, можно настроить её раз и навсегда в конфигурации приложения, как показано ниже:
Вместо того, чтобы каждый раз вводить одинаковые значения параметров миграции, когда вы запускаете команду миграции,
можно настроить её раз и навсегда в конфигурации приложения, как показано ниже:
- `$type`: тип объединения, например, `'INNER JOIN'`, `'LEFT JOIN'`.
- `$table`: имя таблицы, которая должна быть присоединена.
- `$on`: необязательное условие объединения, то есть фрагмент `ON`. Пожалуйста, обратитесь к документации для
[where()](#where) для более подробной информации о определении условий.
[where()](#where) для более подробной информации о определении условий. Отметим, что синтаксис массивов **не работает**
для задания условий для столбцов, то есть `['user.id' => 'comment.userId']` будет означать условие, где ID пользователя
долен быть равен строке `'comment.userId'`. Вместо этого стоит указывать условие в виде строки `'user.id = comment.userId'`.
- `$params`: необязательные параметры присоединяемые к условию объединения.
Вы можете использовать следующие сокращающие методы для указания `INNER JOIN`, `LEFT JOIN` и `RIGHT JOIN`, в указанном порядке.
@ -526,7 +528,7 @@ $row = (new \yii\db\Query())
Все методы выборки могут получать необязательный параметр `$db`, представляющий [[yii\db\Connection|соединение с БД]],
которое должно использоваться, чтобы выполнить запрос к БД. Если вы упускаете этот параметр, будет использоваться
[компонент приложения](structure-application-components.md) `$db`. Ниже приведён ещё один пример использования метода
`count()`:
[[yii\db\Query::count()|count()]]:
```php
// executes SQL: SELECT COUNT(*) FROM `user` WHERE `last_name`=:last_name
@ -540,7 +542,7 @@ $count = (new \yii\db\Query())
* Вызывается [[yii\db\QueryBuilder]] для генерации SQL запроса на основе текущего [[yii\db\Query]];
* Создаёт объект [[yii\db\Command]] с сгенерированным SQL запросом;
* Вызывается выбирающий метод (например `queryAll()`) из [[yii\db\Command]] для выполнения SQL запроса и извлечения данных.
* Вызывается выбирающий метод (например [[yii\db\Command::queryAll()|queryAll()]]) из [[yii\db\Command]] для выполнения SQL запроса и извлечения данных.
Иногда вы можете захотеть увидеть или использовать SQL запрос построенный из объекта [[yii\db\Query]]. Этой цели можно
добиться с помощью следующего кода:
@ -640,5 +642,6 @@ foreach ($query->batch() as $users) {
Для форматирования вывода Yii предоставляет класс, преобразующий данные в человеко понятный формат.
[[yii\i18n\Formatter]] это класс-помощник, который зарегистрирован как [компонент приложения](structure-application-components.md), по-умолчанию под именем `formatter`.
[[yii\i18n\Formatter]] это класс-помощник, который зарегистрирован как
[компонент приложения](structure-application-components.md), по-умолчанию под именем `formatter`.
Он предоставляет набор методов для форматирования таких данных как дата/время, числа и другие часто используемые в целях локализации форматы.
Он предоставляет набор методов для форматирования таких данных как дата/время, числа и другие часто используемые в целях
локализации форматы.
Formatter может быть использован двумя различными способами.
1. Напрямую используя методы форматирования (все методы форматирования имеют префикс `as`):
@ -19,8 +21,8 @@ Formatter может быть использован двумя различны
```
2. Используя метод [[yii\i18n\Formatter::format()|format()]] и имя формата.
Этот метод также используется в виджетах на подобии [[yii\grid\GridView]] и [[yii\widgets\DetailView]], в которых вы можете
задать формат отображения данных в колонке через конфигурацию виджета.
Этот метод также используется в виджетах на подобии [[yii\grid\GridView]] и [[yii\widgets\DetailView]], в которых
вы можете задать формат отображения данных в колонке через конфигурацию виджета.
```php
echo Yii::$app->formatter->format('2014-01-01', 'date'); // выведет: January 1, 2014
@ -29,11 +31,13 @@ Formatter может быть использован двумя различны
Все данные, отображаемые через компонент formatter, будут локализованы, если [расширение PHP intl](http://php.net/manual/ru/book.intl.php) было установлено.
Для этого вы можете настроить свойство [[yii\i18n\Formatter::locale|locale]]. Если оно не было настроено, то
будет использован [[yii\base\Application::language|язык приложения]] в качестве локали. Подробнее см. [раздел интернационализация](tutorial-i18n.md).
Компонент форматирования будет выбирать корректный формат для даты и чисел в соответствии с локалью, включая имена месяца и дней недели,
переведённые на текущий язык. Форматирование дат также зависит от [[yii\i18n\Formatter::timeZone|временной зоны]], которая
Все данные, отображаемые через компонент formatter, будут локализованы, если
[расширение PHP intl](http://php.net/manual/ru/book.intl.php) было установлено. Для этого вы можете настроить свойство
[[yii\i18n\Formatter::locale|locale]]. Если оно не было настроено, то в качестве локали будет использован
[[yii\base\Application::language|язык приложения]]. Подробнее смотрите в разделе «[интернационализация](tutorial-i18n.md)».
Компонент форматирования будет выбирать корректный формат для даты и чисел в соответствии с локалью, включая имена
месяцев и дней недели, переведённые на текущий язык. Форматирование дат также зависит от
[[yii\i18n\Formatter::timeZone|часового пояса]], которая
также будет из свойства [[yii\base\Application::timeZone|timeZone]] приложения, если она не была задана явно.
Например, форматирование даты, вызванное с разной локалью, отобразит разные результаты::
echo Yii::$app->formatter->asDate('2014-01-01'); // выведет: 1 января 2014 г.
```
> Обратите внимание, что форматирование может различаться между различными версиями библиотеки ICU, собранных с PHP, а также на основе того установлено ли
> [расширение PHP intl] (http://php.net/manual/ru/book.intl.php) или нет. Таким образом, чтобы гарантировать, что ваш сайт будет одинаково отображать данные
> во всех окружениях рекомендуется установить расширение PHP intl во всех окружениях и проверить, что версия библиотеки ICU совпадает.
> Обратите внимание, что форматирование может различаться между различными версиями библиотеки ICU, собранных с PHP,
> а также на основе того установлено ли [расширение PHP intl] (http://php.net/manual/ru/book.intl.php) или нет.
> Таким образом, чтобы гарантировать, что ваш сайт будет одинаково отображать данные во всех окружениях рекомендуется
> установить расширение PHP intl во всех окружениях и проверить, что версия библиотеки ICU совпадает.
> См. также: [Настройка PHP окружения для интернационализации](tutorial-i18n.md#setup-environment).
>
> Отметим также, что даже если установлено расширение PHP intl, форматирование даты и времени для значений года >=2038 или <=1901
> на 32-ух разрядных системах будет обращаться к реализации PHP, которая не обеспечивает локализованные имена месяца и дня,
> потому что в этом случае intl будет использовать 32-ух битный UNIX timestamp. На 64-битной системе intl formatter будет работать во всех случаях, если, конечно, intl был установлен.
> Отметим также, что даже если установлено расширение PHP intl, форматирование даты и времени для значений года >=2038
> или <=1901 на 32-ух разрядных системах будет обращаться к реализации PHP, которая не обеспечивает локализованные
> имена месяца и дня, потому что в этом случае intl будет использовать 32-ух битный UNIX timestamp. На 64-битной системе
> intl formatter будет работать во всех случаях, если, конечно, intl был установлен.
Форматы по-умолчанию, используемые в методах форматирования, можно настраивать через свойства [[yii\i18n\Formatter|класса форматирования]].
Вы можете задать форматирование по-умолчанию для всего приложения, настроив компонент `formatter` в вашей [конфигурации приложения](concept-configurations.md#application-configurations).
Ниже приведён пример конфигурации.
Чтобы узнать больше о доступных свойствах см. [[yii\i18n\Formatter|API документацию к классу Formatter]] и следующим подсекциям.
Форматы по-умолчанию, используемые в методах форматирования, можно настраивать через свойства
[[yii\i18n\Formatter|класса форматирования]]. Вы можете задать форматирование по-умолчанию для всего приложения, настроив
компонент `formatter` в вашей [конфигурации приложения](concept-configurations.md#application-configurations). Ниже
приведён пример конфигурации. Чтобы узнать больше о доступных свойствах см. [[yii\i18n\Formatter|API документацию к классу Formatter]]
- [[yii\i18n\Formatter::asDate()|date]] - значение будет отформатировано как дата, например `January 01, 2014`.
- [[yii\i18n\Formatter::asTime()|time]] - значение будет отформатировано как время, например `14:23`.
- [[yii\i18n\Formatter::asDatetime()|datetime]] - значение будет отформатировано как дата и время, например `January 01, 2014 14:23`.
- [[yii\i18n\Formatter::asTimestamp()|timestamp]] - значение будет отформатировано как [unix timestamp](http://en.wikipedia.org/wiki/Unix_time), например, `1412609982`.
- [[yii\i18n\Formatter::asRelativeTime()|relativeTime]] - значение будет отформатировано как временной промежуток между заданной датой и
текущий временем в человеко понятном формате, например: `1 час назад`.
- [[yii\i18n\Formatter::asDuration()|duration]]: значение будет отформатировано как продолжительность в человеко понятном формате, например `1 день, 2 минуты`.
- [[yii\i18n\Formatter::asDatetime()|datetime]] - значение будет отформатировано как дата и время, например
`January 01, 2014 14:23`.
- [[yii\i18n\Formatter::asTimestamp()|timestamp]] - значение будет отформатировано как
[unix timestamp](http://en.wikipedia.org/wiki/Unix_time), например, `1412609982`.
- [[yii\i18n\Formatter::asRelativeTime()|relativeTime]] - значение будет отформатировано как временной промежуток между
заданной датой и текущий временем в человеко понятном формате, например: `1 час назад`.
- [[yii\i18n\Formatter::asDuration()|duration]]: значение будет отформатировано как продолжительность в человеко понятном
формате, например `1 день, 2 минуты`.
Форматирование даты и времени для методов [[yii\i18n\Formatter::asDate()|date]], [[yii\i18n\Formatter::asTime()|time]] и
[[yii\i18n\Formatter::asDatetime()|datetime]] может быть задано глобально через конфигурацию свойств форматирования [[yii\i18n\Formatter::$dateFormat|$dateFormat]], [[yii\i18n\Formatter::$timeFormat|$timeFormat]] и
[[yii\i18n\Formatter::asDatetime()|datetime]] может быть задано глобально через конфигурацию свойств форматирования
[[yii\i18n\Formatter::$dateFormat|$dateFormat]], [[yii\i18n\Formatter::$timeFormat|$timeFormat]] и
Для форматирования значений даты и времени Yii будет преобразовывать их в соответствии с [[yii\i18n\Formatter::timeZone|настроенной временной зоной]].
Поэтому предполагается, что входные значения будут в UTC, если часовой пояс не был указан явно. По этой причине
рекомендуется хранить все значения даты и времени в формате UTC, предпочтительно в виде UNIX timestamp, которая всегда во временной зоне UTC по определению.
Если входное значение находится в часовом поясе, отличном от UTC, часовой пояс должен быть указан явно, как в следующем примере:
Для форматирования значений даты и времени Yii будет преобразовывать их в соответствии с
[[yii\i18n\Formatter::timeZone|настроенным часовым поясом]]. Поэтому предполагается, что входные значения будут в UTC,
если часовой пояс не был указан явно. По этой причине рекомендуется хранить все значения даты и времени в формате UTC,
предпочтительно в виде UNIX timestamp, которая всегда в часовом поясе UTC по определению. Если входное значение
находится в часовом поясе, отличном от UTC, часовой пояс должен быть указан явно, как в следующем примере:
```php
// при условии Yii::$app->timeZone = 'Europe/Berlin';
Начиная с версии 2.0.1 стало возможно настраивать временную зону для предполагаемых timestamp, которые не включают в себя временную зону,
как во втором примере в коде выше. Вы можете задать [[yii\i18n\Formatter::defaultTimeZone]] временной зоной, которую вы используете для хранения данных.
Начиная с версии 2.0.1 стало возможно настраивать часовой пояс для предполагаемых timestamp, которые не включают в себя
часовой пояс, как во втором примере в коде выше. Вы можете задать [[yii\i18n\Formatter::defaultTimeZone]] часовым поясом,
который вы используете для хранения данных.
> Примечание: Поскольку временные зоны являются субъектом ответственности правительств по всему миру и могут часто меняться,
> это значит, что вы, вероятно, не имеете самую свежую информацию в базе данных временных зон, установленной на вашем сервере.
> Примечание: Поскольку часовые пояса являются субъектом ответственности правительств по всему миру и могут часто меняться,
> это значит, что вы, вероятно, не имеете самую свежую информацию в базе данных часовых поясов, установленной на вашем сервере.
> Вы можете обратиться к [ICU руководству](http://userguide.icu-project.org/datetime/timezone#TOC-Updating-the-Time-Zone-Data)
> для получения подробностей об обновлении базы данных временных зон.
> для получения подробностей об обновлении базы данных часовых поясов.
> См. также: [Настройка вашего PHP окружения для интернационализации](tutorial-i18n.md#setup-environment).
Для форматирования числовых значений класс форматирования предоставляет следующие методы:
- [[yii\i18n\Formatter::asInteger()|integer]] - значение будет отформатировано как целое число, например `42`.
- [[yii\i18n\Formatter::asDecimal()|decimal]] - значение будет отформатировано как дробное число, состоящее из целого и дробной части, например: `2,542.123` или `2.542,123`.
- [[yii\i18n\Formatter::asDecimal()|decimal]] - значение будет отформатировано как дробное число, состоящее из целого и
дробной части, например: `2,542.123` или `2.542,123`.
- [[yii\i18n\Formatter::asPercent()|percent]] - значение будет отформатировано как процентное значение, например `42%`.
- [[yii\i18n\Formatter::asScientific()|scientific]] - значение будет отформатировано в научном формате, например: `4.2E4`.
- [[yii\i18n\Formatter::asCurrency()|currency]] - значение будет отформатировано в денежном формате, например: `£420.00`.
Обратите внимание, чтобы эта функция работала правильно, локаль должна включать в себя часть со страной, например: `en_GB` или` en_US` потому что только язык будет неоднозначным в этом случае.
- [[yii\i18n\Formatter::asSize()|size]] - значение будет отформатировано как количество байт в человеко понятном формате, например: `410 kibibytes`.
- [[yii\i18n\Formatter::asShortSize()|shortSize]] - сокращённая версия [[yii\i18n\Formatter::asSize()|size]], например: `410 KiB`.
Обратите внимание, чтобы эта функция работала правильно, локаль должна включать в себя часть со страной, например: `en_GB`
или` en_US` потому что только язык будет неоднозначным в этом случае.
- [[yii\i18n\Formatter::asSize()|size]] - значение будет отформатировано как количество байт в человеко понятном формате,
например: `410 kibibytes`.
- [[yii\i18n\Formatter::asShortSize()|shortSize]] - сокращённая версия [[yii\i18n\Formatter::asSize()|size]], например:
`410 KiB`.
Форматирование чисел может быть скорректирована с помощью [[yii\i18n\Formatter::decimalSeparator|дробного разделителя]] и
[[yii\i18n\Formatter::thousandSeparator|тысячного разделителя]], которые были заданы в соответствии с локалью.
Для более сложной конфигурации, [[yii\i18n\Formatter::numberFormatterOptions]] и [[yii\i18n\Formatter::numberFormatterTextOptions]]
могут быть использованы для настройки внутренне используемого [класса NumberFormatter](http://php.net/manual/ru/class.numberformatter.php)
Например, чтобы настроить максимальное и минимальное количество знаков после запятой, вы можете настроить свойство [[yii\i18n\Formatter::numberFormatterOptions]] как в примере ниже:
Например, чтобы настроить максимальное и минимальное количество знаков после запятой, вы можете настроить свойство
[[yii\i18n\Formatter::numberFormatterOptions]] как в примере ниже:
Кроме форматирование даты, времени и чисел, Yii предоставляет набор других полезных средств форматирования для различных ситуаций:
Кроме форматирование даты, времени и чисел, Yii предоставляет набор других полезных средств форматирования для различных
ситуаций:
- [[yii\i18n\Formatter::asRaw()|raw]] - значением будет отображено как есть, это псевдо-форматирование, которое не имеет никакого эффекта,
- [[yii\i18n\Formatter::asRaw()|raw]] - значением будет отображено как есть, это псевдо-форматирование, которое не даёт
никакого эффекта,
кроме значений `null`, которые будет отформатированы в соответствии с [[nullDisplay]].
- [[yii\i18n\Formatter::asText()|text]] - значением будет экранированный от HTML текст.
Это формат по-умолчанию, используемый в [GridView DataColumn](output-data-widgets.md#data-column).
- [[yii\i18n\Formatter::asNtext()|ntext]] - значением будет экранированный от HTML текст с новыми строками, сконвертированными в разрывы строк.
- [[yii\i18n\Formatter::asParagraphs()|paragraphs]] - значением будет экранированный от HTML текст с параграфами, обрамлёнными в `<p>` теги.
- [[yii\i18n\Formatter::asHtml()|html]] - значение будет очищено, используя [[HtmlPurifier]] с целью предотвратить XSS атаки. Вы можете
задать дополнительные параметры, такие как `['html', ['Attr.AllowedFrameTargets' => ['_blank']]]`.
- [[yii\i18n\Formatter::asNtext()|ntext]] - значением будет экранированный от HTML текст с новыми строками,
сконвертированными в разрывы строк.
- [[yii\i18n\Formatter::asParagraphs()|paragraphs]] - значением будет экранированный от HTML текст с параграфами,
обрамлёнными в `<p>` теги.
- [[yii\i18n\Formatter::asHtml()|html]] - значение будет очищено, используя [[HtmlPurifier]] с целью предотвратить XSS
атаки. Вы можете задать дополнительные параметры, такие как `['html', ['Attr.AllowedFrameTargets' => ['_blank']]]`.
- [[yii\i18n\Formatter::asEmail()|email]] - значение будет отформатировано как ссылка `mailto`.
- [[yii\i18n\Formatter::asImage()|image]] - значение будет отформатировано как тег картинки.
- [[yii\i18n\Formatter::asUrl()|url]] - значение будет отформатировано как ссылка <a>.
- [[yii\i18n\Formatter::asBoolean()|boolean]] - значение форматируется как логическое. По-умолчанию `true` будет отображено как `Yes` и `false` как `No`,
переведенное на язык приложения. Вы можете настроить это через свойство [[yii\i18n\Formatter::booleanFormat]].
- [[yii\i18n\Formatter::asBoolean()|boolean]] - значение форматируется как логическое. По-умолчанию `true` будет
отображено как `Yes` и `false` как `No`, переведенное на язык приложения. Вы можете настроить это через свойство
[[yii\i18n\Formatter::booleanFormat]].
`null` значения <spanid="null-values"></span>
-------------
Для значений `null` в PHP, класс форматирования будет отображать вместо пустой строки маркер, по-умолчанию это
`(not set)`, переведенный на язык приложения. Вы можете настроить свойство [[yii\i18n\Formatter::nullDisplay|nullDisplay]] для установки собственного маркера.
Если вы не хотите обрабатывать `null` значения, то установите свойство [[yii\i18n\Formatter::nullDisplay|nullDisplay]] в `null`.
`(not set)`, переведенный на язык приложения. Вы можете настроить свойство [[yii\i18n\Formatter::nullDisplay|nullDisplay]]
для установки собственного маркера. Если вы не хотите обрабатывать `null` значения, то установите свойство
[[yii\i18n\Formatter::nullDisplay|nullDisplay]] в `null`.
> Информация: далее в данном руководстве предполагается, что Yii установлен в директорию `basic/web`, которая, в свою очередь, установлена как корневой каталог в настройках Web сервера. В результате, обратившись по URL `http://hostname/index.php`, Вы получите доступ к приложению, расположенному в `basic/web`. Детальнее с процессом начальной настройки можно познакомиться в разделе [Установка Yii](start-installation.md).
Отметим, что в отличие от фреймворка как только приложение установлено, оно становится целиком вашим. Вы можете изменять
его код как угодно.
Функциональность <spanid="functionality"></span>
---------------
@ -13,11 +16,16 @@
* домашняя страница, отображается при переходе по URL `http://hostname/index.php`
* страница "About" ("О нас")
* на странице "Contact" находится форма обратной связи, на которой пользователь может обратиться к разработчику по e-mail
* на странице "Login" отображается форма авторизации. Попытайтесь авторизоваться с логином/паролем "admin/admin". Обратите внимание на изменение раздела "Login" в главном меню на "Logout".
* на странице "Login" отображается форма авторизации. Попытайтесь авторизоваться с логином/паролем "admin/admin".
Обратите внимание на изменение раздела "Login" в главном меню на "Logout".
Эти страницы используют смежный хедер (шапка сайта) и футер (подвал). В "шапке" находится главное меню, при помощи которого пользователь перемещается по сайту. В "подвале" - копирайт и общая информация.
Эти страницы используют смежный хедер (шапка сайта) и футер (подвал). В "шапке" находится главное меню, при помощи
которого пользователь перемещается по сайту. В "подвале" - копирайт и общая информация.
В самой нижней части окна Вы будете видеть системные сообщения Yii - журнал, отладочную информацию, сообщения об ошибках, запросы к базе данных и т.п. Выводом данной информации руководит [встроенный отладчик](tool-debugger.md), он записывает и отображает информацию о ходе выполнения приложения.
В самой нижней части окна Вы будете видеть системные сообщения Yii - журнал, отладочную информацию, сообщения об ошибках,
запросы к базе данных и т.п. Выводом данной информации руководит
[встроенный отладчик](https://github.com/yiisoft/yii2-debug/blob/master/docs/guide/README.md), он записывает и отображает
информацию о ходе выполнения приложения.
В дополнение к веб приложению имеется консольный скрипт с названием `yii`, который находится в базовой директории приложения.
Этот скрипт может быть использован для выполнения фоновых задач и обслуживания приложения. Всё это описано в разделе
В целом, приложение Yii можно разделить на две категории файлов: расположенные в `basic/web` и расположенные в других директориях. Первая категория доступна через Web (например, браузером), вторая не доступна из вне и не должна быть доступной т.к. содержит служебную информацию.
В Yii реализована схема проектирования [модель-вид-контроллер (MVC)](http://ru.wikipedia.org/wiki/Model-View-Controller),
В Yii реализована [архитектурный паттерн MVC](http://ru.wikipedia.org/wiki/Model-View-Controller),
которая соответствует структуре директорий приложения. В директории `models` находятся [Модели](structure-models.md),
в `views` расположены [Виды](structure-views.md), а в каталоге `controllers` все [Контроллеры](structure-controllers.md) приложения.
## Создание модулей <spanid="creating-modules"></span>
Модуль помещается в директорию, которая называется [[yii\base\Module::basePath|базовым путем]] модуля. Так же как и в директории приложения, в этой директории существуют поддиректории `controllers`, `models`, `views` и другие, в которых размещаются контроллеры, модели, представления и другие элементы. В следующем примере показано примерное содержимое модуля:
Модуль помещается в директорию, которая называется [[yii\base\Module::basePath|базовым путем]] модуля. Так же как и в
директории приложения, в этой директории существуют поддиректории `controllers`, `models`, `views` и другие, в которых
размещаются контроллеры, модели, представления и другие элементы. В следующем примере показано примерное содержимое модуля:
Каждый модуль объявляется с помощью уникального класса, который наследуется от [[yii\base\Module]]. Этот класс должен быть помещен в корне [[yii\base\Module::basePath|базового пути]] модуля и поддерживать [автозагрузку](concept-autoloading.md). Во время доступа к модулю будет создан один экземпляр соответствующего класса модуля. Как и [экземпляры приложения](structure-applications.md), экземпляры модулей нужны, чтобы код модулей мог получить общий доступ к данным и компонентам.
Каждый модуль объявляется с помощью уникального класса, который наследуется от [[yii\base\Module]]. Этот класс должен
быть помещен в корне [[yii\base\Module::basePath|базового пути]] модуля и поддерживать [автозагрузку](concept-autoloading.md).
Во время доступа к модулю будет создан один экземпляр соответствующего класса модуля. Как и
[экземпляры приложения](structure-applications.md), экземпляры модулей нужны, чтобы код модулей мог получить общий
доступ к данным и компонентам.
Приведем пример того, как может выглядеть класс модуля:
@ -42,7 +48,8 @@ class Module extends \yii\base\Module
}
```
Если метод `init()` стал слишком громоздким из-за кода, который задает свойства модуля, эти свойства можно сохранить в виде [конфигурации](concept-configurations.md), а затем загрузить в методе `init()` следующим образом:
Если метод `init()` стал слишком громоздким из-за кода, который задает свойства модуля, эти свойства можно сохранить
в виде [конфигурации](concept-configurations.md), а затем загрузить в методе `init()` следующим образом:
```php
public function init()
@ -53,7 +60,8 @@ public function init()
}
```
При этом в конфигурационном файле `config.php` может быть код следующего вида, аналогичный [конфигурации приложения](structure-applications.md#application-configurations):
При этом в конфигурационном файле `config.php` может быть код следующего вида, аналогичный
### Контроллеры в модулях <spanid="controllers-in-modules"></span>
При создании контроллеров модуля принято помещать классы контроллеров в подпространство `controllers` пространства имен класса модуля. Это также подразумевает, что файлы классов контроллеров должны располагаться в директории `controllers` [[yii\base\Module::basePath|базового пути]] модуля. Например, чтобы описать контроллер `post` в модуле `forum` из предыдущего примера, класс контроллера объявляется следующим образом:
При создании контроллеров модуля принято помещать классы контроллеров в подпространство `controllers` пространства
имён класса модуля. Это также подразумевает, что файлы классов контроллеров должны располагаться в директории `controllers`
[[yii\base\Module::basePath|базового пути]] модуля. Например, чтобы описать контроллер `post` в модуле `forum` из
предыдущего примера, класс контроллера объявляется следующим образом:
```php
namespace app\modules\forum\controllers;
@ -83,19 +94,56 @@ class PostController extends Controller
}
```
Изменить пространство имен классов контроллеров можно задав свойство [[yii\base\Module::controllerNamespace]]. Если какие-либо контроллеры выпадают из этого пространства имен, доступ к ним можно осуществить, настроив свойство [[yii\base\Module::controllerMap]], аналогично тому, [как это делается в приложении](structure-applications.md#controller-map).
Изменить пространство имен классов контроллеров можно задав свойство [[yii\base\Module::controllerNamespace]]. Если
какие-либо контроллеры выпадают из этого пространства имен, доступ к ним можно осуществить, настроив свойство
[[yii\base\Module::controllerMap]], аналогично тому, [как это делается в приложении](structure-applications.md#controller-map).
### Представления в модулях <spanid="views-in-modules"></span>
Представления модуля также следует поместить в в поддиректорию `views` [[yii\base\Module::basePath|базового пути]] модуля. Виды, которые рендерит контроллер модуля, должны располагаться в директории `views/ControllerID`, где `ControllerID` соответствует [идентификатору контроллера](structure-controllers.md#routes). Например, если контроллер реализуется классом `PostController`, представления следует разместить в поддиректории `views/post` [[yii\base\Module::basePath|базового пути]] модуля.
Представления модуля также следует поместить в в поддиректорию `views` [[yii\base\Module::basePath|базового пути]]
модуля. Виды, которые рендерит контроллер модуля, должны располагаться в директории `views/ControllerID`, где `ControllerID`
соответствует [идентификатору контроллера](structure-controllers.md#routes). Например, если контроллер реализуется
классом `PostController`, представления следует разместить в поддиректории `views/post`
Ваши команды будут доступны из командной строки как:
```
yii <module_id>/<command>/<sub_command>
```
В модуле можно задать [шаблон](structure-views.md#layouts), который будет использоваться для рендеринга всех представлений контроллерами модуля. По умолчанию шаблон помещается в директорию `views/layouts`, а свойство [[yii\base\Module::layout]] должно указывать на имя этого шаблона. Если не задать свойство `layout`, модуль будет использовать шаблон, заданный в приложении.
## Использование модулей <spanid="using-modules"></span>
Чтобы задействовать модуль в приложении, достаточно включить его в свойство [[yii\base\Application::modules|modules]] в конфигурации приложения. Следующий код в [конфигурации приложения](structure-applications.md#application-configurations) задействует модуль `forum`:
Чтобы задействовать модуль в приложении, достаточно включить его в свойство [[yii\base\Application::modules|modules]]
в конфигурации приложения. Следующий код в [конфигурации приложения](structure-applications.md#application-configurations)
задействует модуль `forum`:
```php
[
@ -108,25 +156,40 @@ class PostController extends Controller
]
```
Свойству [[yii\base\Application::modules|modules]] присваивается массив, содержащий конфигурацию модуля. Каждый ключ массива представляет собой *идентификатор модуля*, который однозначно определяет модуль среди других модулей приложения, а соответствующий массив - это [конфигурация](concept-configurations.md) для создания модуля.
Свойству [[yii\base\Application::modules|modules]] присваивается массив, содержащий конфигурацию модуля. Каждый ключ массива
представляет собой *идентификатор модуля*, который однозначно определяет модуль среди других модулей приложения,
а соответствующий массив - это [конфигурация](concept-configurations.md) для создания модуля.
### Маршруты <spanid="routes"></span>
Как маршруты приложения используются для обращения к контроллерам приложения, [маршруты](structure-controllers.md#routes) модуля используются, чтобы обращаться к контроллерам этого модуля. Маршрут контроллера в модуле должен начинаться с идентификатора модуля, за которым следуют идентификатор контроллера и идентификатор действия. Например, если в приложении задействован модуль `forum`, то маршрут `forum/post/index` соответствует действию `index` контроллера `post` этого модуля. Если маршрут состоит только из идентификатора модуля, то контроллер и действие определяются исходя из свойства [[yii\base\Module::defaultRoute]], которое по умолчанию равно `default`. Таким образом, маршрут `forum` соответствует контроллеру `default` модуля `forum`.
Как маршруты приложения используются для обращения к контроллерам приложения, [маршруты](structure-controllers.md#routes)
модуля используются, чтобы обращаться к контроллерам этого модуля. Маршрут контроллера в модуле должен начинаться с
идентификатора модуля, за которым следуют [идентификатор контроллера](structure-controllers.md#controller-ids) и
[идентификатор действия](structure-controllers.md#action-ids). Например, если в приложении задействован модуль `forum`,
то маршрут `forum/post/index` соответствует действию `index` контроллера `post` этого модуля. Если маршрут состоит только
из идентификатора модуля, то контроллер и действие определяются исходя из свойства [[yii\base\Module::defaultRoute]],
которое по умолчанию равно `default`. Таким образом, маршрут `forum` соответствует контроллеру `default` модуля `forum`.
### Получение доступа к модулям <spanid="accessing-modules"></span>
Зачастую внутри модуля может потребоваться доступ к экземпляру [класса модуля](#module-classes), через который получаются идентификатор модуля, его параметры, компоненты, и т. п. Это можно сделать с помощью следующей конструкции:
Зачастую внутри модуля может потребоваться доступ к экземпляру [класса модуля](#module-classes), через который получаются
идентификатор модуля, его параметры, компоненты, и т. п. Это можно сделать с помощью следующей конструкции:
```php
$module = MyModuleClass::getInstance();
```
где `MyModuleClass` соответствует имени класса модуля, доступ к которому нужно получить. Метод `getInstance()` возвращает запрошенный в данный момент экземпляр класса модуля. Если модуль не запрошен, метод вернет null. Учтите, что обычно экземпляры класса модуля вручную не создаются, так как созданный вручную экземпляр будет отличаться от экземпляра, созданного Yii в качестве ответа на запрос.
где `MyModuleClass` соответствует имени класса модуля, доступ к которому нужно получить. Метод `getInstance()` возвращает
запрошенный в данный момент экземпляр класса модуля. Если модуль не запрошен, метод вернет null. Учтите, что обычно
экземпляры класса модуля вручную не создаются, так как созданный вручную экземпляр будет отличаться от экземпляра,
созданного Yii в качестве ответа на запрос.
> Информация: При разработке модуля нельзя исходить из предположения, что модулю будет назначен конкретный идентификатор. Это связано с тем, что идентификатор, назначаемый модулю при использовании в приложении или в другом модуле, может быть выбран совершенно произвольно. Чтобы получить идентификатор модуля, нужно вначале выбрать экземпляр модуля, как это описано выше, а затем получить доступ к идентификатору через свойство `$module->id`.
> Информация: При разработке модуля нельзя исходить из предположения, что модулю будет назначен конкретный идентификатор.
Это связано с тем, что идентификатор, назначаемый модулю при использовании в приложении или в другом модуле, может быть
выбран совершенно произвольно. Чтобы получить идентификатор модуля, нужно вначале выбрать экземпляр модуля, как это
описано выше, а затем получить доступ к идентификатору через свойство `$module->id`.
Доступ к экземпляру модуля можно получить следующими способами:
Может потребоваться запускать некоторые модули при каждом запросе. Модуль [[yii\debug\Module|debug]] - один из таких модулей. Для этого список идентификаторов таких модулей необходимо указать в свойстве [[yii\base\Application::bootstrap|bootstrap]] приложения.
Может потребоваться запускать некоторые модули при каждом запросе. Модуль [[yii\debug\Module|debug]] - один из таких
модулей. Для этого список идентификаторов таких модулей необходимо указать в свойстве
Модули могут вкладываться друг в друга без ограничений по глубине. Иными словами, в модуле содержится модуль, в который входит еще один модуль, и т. д. Первый модуль называется *родительским*, остальные - *дочерними*. Дочерние модули объявляются в свойстве [[yii\base\Module::modules|modules]] родительских модулей. Например,
Модули могут вкладываться друг в друга без ограничений по глубине. Иными словами, в модуле содержится модуль, в который
входит еще один модуль, и т. д. Первый модуль называется *родительским*, остальные - *дочерними*. Дочерние модули
объявляются в свойстве [[yii\base\Module::modules|modules]] родительских модулей. Например,
```php
namespace app\modules\forum;
@ -189,13 +257,21 @@ class Module extends \yii\base\Module
}
```
Маршрут к контроллеру вложенного модуля должен содержать идентификаторы всех его предков. Например, маршрут `forum/admin/dashboard/index` соответствует действию `index` контроллера `dashboard` модуля `admin`, который в свою очередь является дочерним модулем модуля `forum`.
Маршрут к контроллеру вложенного модуля должен содержать идентификаторы всех его предков. Например, маршрут
`forum/admin/dashboard/index` соответствует действию `index` контроллера `dashboard` модуля `admin`, который в свою
очередь является дочерним модулем модуля `forum`.
> Информация: Метод [[yii\base\Module::getModule()|getModule()]] возвращает только те дочерние модули, которые принадлежат родительскому модулю непосредственно. В свойстве [[yii\base\Application::loadedModules]] содержится список загруженных модулей, в том числе прямых и косвенных потомков, с индексированием по имени класса.
> Информация: Метод [[yii\base\Module::getModule()|getModule()]] возвращает только те дочерние модули, которые
принадлежат родительскому модулю непосредственно. В свойстве [[yii\base\Application::loadedModules]] содержится
список загруженных модулей, в том числе прямых и косвенных потомков, с индексированием по имени класса.
## Лучшие практики<spanid="best-practices"></span>
Модули лучше всего подходят для крупных приложений, функционал которых можно разделить на несколько групп, в каждой из которых функции тесно связаны между собой. Каждая группа функций может разрабатываться в виде модуля, над которым работает один разработчик или одна команда.
Модули лучше всего подходят для крупных приложений, функционал которых можно разделить на несколько групп, в каждой из
которых функции тесно связаны между собой. Каждая группа функций может разрабатываться в виде модуля, над которым работает
один разработчик или одна команда.
Модули - это хороший способ повторно использовать код на уровне групп функций. В виде модулей можно реализовать такой функционал как управление пользователями или управление комментариями, а затем использовать эти модули в будущих разработках.
Модули - это хороший способ повторно использовать код на уровне групп функций. В виде модулей можно реализовать такая
функциональность как управление пользователями или управление комментариями, а затем использовать эти модули в будущих