Состоялся релиз PHP фреймворка Yii версии 2.0.13. В него вошли более 90 улучшений и исправлений.
Обратите внимание, что в релиз попали изменения, которые могут повлиять на существующие приложения. Они описаны в UPGRADE.md.
Огромное спасибо сообществу Yii за поддержку и пулл-реквесты!
За процессом разработки можно следить поставив звёздочку на GitHub. Также подписывайтесь
на наш Twitter и Facebook.
Так как мы работаем над Yii 2.1, убедитесь что версия фреймворка в composer.json
прописана верно (~2.0.13
) и вы не обновитесь на 2.1 случайно когда он релизнется.
Ниже мы рассмотрим самые интересные улучшения и исправления релиза. Полный список можно найти в CHANGELOG.
Шаблоны приложений
Как шаблон "basic", так и "advanced" теперь использую asset-packagist.org вместо Composer asset plugin.
Vagrant окружение в advanced обзавелось XDdebug-ом. Также его стало ещё проще поднять. Необходимые плагины ставятся автоматически.
В шаблон "basic" добавлен виджет Alert
(он уже был в "advanced").
Логирование, отладка и обработка ошибок
Логирование, отладка и обработка ошибок — это то, чем мы занимаемся каждый день. Инструменты для этого должны работать как часы предоставляя как можно больше релевантной информации. В этом релизе на эту тему улучшения следующие:
yiiwebDbSession
теперь использует возможности обработчика ошибок для показа страницы исключения. Как оказалось, довольно часто разработчики забывали проверить объекты на существование при записи дополнительных данных в базу данных с сессиями. Отлаживать это было очень тяжело, потому как ошибки были про неудачную запись в сессию. Теперь показывается реальная причина.- Ранее миграции можно было создавать с именами любой длины. В этой версии были введены ограничения в 180 символов, так как большая длина вызывает проблемы в некоторых СУБД. В случае превышения выбрасывается исключение.
- В логах теперь есть миллисекунды.
Кроме прочего, Carsten Brandt улучшил страницу исключения добавив несколько полезных кнопок:
Фильтры данных
Благодаря замечательной работы Павла Климова, в Yii появились фильтры данных и их интеграция в REST API. Фильтры могут быть использованы для построения сложных условий для провайдеров данных. Они отлично настраиваются и подходят как к
веб-приложениям, так и к REST API.
Документация доступна в разделе "Filtering Data Providers using Data Filters".
Параллелизм
Правильное поведение при параллелизме очень важно для высоконагруженных проектов. Мы исправили несколько ошибок на эту тему. @kidol поправил обработку состояния гонки в yiimutexFileMutex
. @dynasource сделал то же для публикации ассетов в
случае с использованием символических ссылок.
Контейнер Dependency Injection и его использование
Что поменялось:
- Добавлена поддержка переменного числа параметров в сигнатурах.
- Зависимости автоматически внедряются в конструктор миграций.
- Cookie инстанциируются через контейнер.
PHP 7.2
PHP 7.2 уже близко. Публикуются RC и скоро будет стабильный релиз. В 7.2 есть значительные улучшения, но есть и поломка совместимости. Начиная с этого релиза Yii 2 полностью совместим с PHP 7.2.
Кроме небольших изменений есть и вынужденное большое, которое может затронуть ваши приложения. Начиная с PHP 7.2, было запрещено использование некоторых ключевых слов в названии классов, в том числе object
.
Использование Object
в PHP 7.2 вызывает фатальную ошибку. В Yii есть класс yiibaseObject
, который использовался как базовый для большинства классов фреймворка, многих расширений и приложений.
Чтобы Yii работал с PHP 7.2, мы переименовали класс. yiibaseObject
помечен как deprecated. Используйте yiibaseBaseObject
. Версии Yii 2 до 2.0.13 не совместимы с PHP 7.2.
Более детально необходимые приложениям изменения описаны в UPGRADE.
Запросы
В класс yiiwebRequest
добавлен метод getOrigin()
. Он возвращает HTTP_ORIGIN
текущего CORS запроса.
Также появился новый фильтр yiifiltersAjaxFilter
, позволяющий ограничить доступ к действию контроллера AJAX запросами.
Безопасность
Была найдена и исправлена не критичная проблема CVE-2017-11516 с экранированием в обработчике ошибок в режиме отладки.
Безопасность запросов повысилась за счёт поддержки списка доверенных прокси. В процессе мы убрали получение статуса HTTP/HTTPS через X-Forwarded-Proto
по умолчанию.
Консоль
В консоли появились интересные улучшения. Во-первых, класс yiiconsoleExitCode
, содержащий константы, которые можно использовать для кодов возврата консольных команд:
if ($this->importData()) {
return ExitCode::OK;
} else {
ExitCode::SOFTWARE;
}
Во-вторых, стало возможным выводить таблицы:
echo Table::widget([
'headers' => ['test1', 'test2', 'test3'],
'rows' => [
['col1', 'col2', 'col3'],
['col1', 'col2', ['col3-0', 'col3-1', 'col3-2']],
],
]);
выведет
╔═══════╤═══════╤══════════╗
║ test1 │ test2 │ test3 ║
╟───────┼───────┼──────────╢
║ col1 │ col2 │ col3 ║
╟───────┼───────┼──────────╢
║ col1 │ col2 │ • col3-0 ║
║ │ │ • col3-1 ║
║ │ │ • col3-2 ║
╚═══════╧═══════╧══════════╝
Базы данных
Сергей Макинен реализовал API для управления ограничениями:
$connection = Yii::$app->db;
$connection
->createCommand()
->addUnique('unique-username', 'user', 'username')
->execute();
$connection
->createCommand()
->dropUnique('unique-username', 'user')
->execute();
$connection
->createCommand()
->addCheck('check-price', 'order', 'price > 0')
->execute();
$connection
->createCommand()
->dropCheck('check-price', 'order')
->execute();
$connection
->createCommand()
->addDefaultValue('default-balance', 'account', 'balance', 0)
->execute();
$connection
->createCommand()
->dropDefaultValue('default-balance', 'account')
->execute();
Также можно получить различную информацию:
/** @var Schema $schema */
$schema = $connection->getSchema();
$fks = $schema->getTableForeignKeys('user');
foreach ($fks as $fk) {
echo $fk->onUpdate;
}
Интересующиеся могут посмотреть на этот коммит.
Интерфейсы
Мы начали плавно вводить интерфейсы для некоторых компонентов. На этот раз это yiicachingCacheInterface
. Будут ещё как в 2.0, так и в 2.1.
Миграции
Новая команда migrate/fresh
вычищает базу и заново применят все миграции.
В класс Migration
добавлены опции $compact
(делает вывод более сжатым) и $maxSqlOutputLength
(режет SQL до заданного количества символов).
Модули
Сервис локатор модуля стал доступен из его контроллеров как $this->module->get('myComponent')
. Если из него не удаётся получить объект, происходят попытки получить объект из сервис локатора родительского модуля. Так как родителем всех модулей является приложение, компонент, в конечном итоге, будет искаться и в нём.
Это изменение позволят легче строить изолированные модули. При использовании $this->module->get('myComponent')
вы автоматически получаете возможность переопределить зависимости из конфигурации модуля, но при этом полагаться на компоненты приложения.
Примеры вы можете найти в "Accessing components from within modules".
Хелперы
В ArrayHelper
появился метод setValue()
. Он пишет значение в ассоциативный массив по указанному пути. Если такого пути нет, соответствующие ключи будут созданы. Если есть, то значение будет перезаписано. Поддерживаются два синтаксиса:
ArrayHelper::setValue($array, 'key.in', ['arr' => 'val']);
и
ArrayHelper::setValue($array, ['key', 'in'], ['arr' => 'val']);
Ещё один метод в релизе — StringHelper::floatToString()
. Он конвертирует float
в string
, но, в отличие от нативного кастинга, всегда использует точки как разделитель целой части.
RBAC
yiirbacDbManager::checkAccess()
перестал делать лишние запросы при получении назначений. Если вы хранили иерархию в базе, производительность после обновления, вероятно, вырастет. Также в таблицы был добавлен дополнительный индекс, что сделало сами запросы быстрее.
Совместимость с jQuery 3.0
Несмотря на то, что в Yii 2.1 мы пытаемся сделать фреймворк независимым от JavaScript, 2.0 завязан на jQuery. Мы обновили JS и PHP код для совместимости с jQuery 3.0.
ActiveRecord и поведения
В yiidbActiveRecordInterface
через новый yiibaseStaticInstanceInterface
было добавлен новый метод instance($refresh = false);
. Его назначение — предоставлять статические экземпляры классов, которые могут использоваться для получения различных
метаданных, недоступных через статические методы. Например, изменения, сделанные через DI или при помощи поведений можно сделать только на уровне объектов, но, в некоторых слуаях, было бы полезно делать их на статическом уровне класса.
Был добавлен yiibehaviorsAttributesBehavior
. Он присваивает значения одному или нескольким атрибутам объекта ActiveRecord при определённых событиях. В отличие от yiibehaviorsAttributeBehavior
он работает с несколькими атрибутами сразу. Как в AttributeBehavior
, так и в AttributesBehavior
была добавлена опция preserveNonEmptyValues
. При выставлении в true
она позволяет перезаписывать значения только в том случае, когда они пусты.
В yiibehaviorsSluggableBehavior
добавлена опция skipOnEmpty
. Включение её предотвращает генерацию нового slug-а если атрибут равен null
или пуст.
Asset-ы
Хеширование директорий ресурсов теперь учитывает символические ссылки. Тем самым, исправлена инвалидация кеша в том случае, когда после перехода от копирования к ссылкам ресурсы не обновлялись. Ранее приходилось удалять содержимое директории assets.
Компрессия и сборка ресурсов консольной командой теперь учитывает, что многие популярные библиотеки не ставят ;
в конце файла. Из этого не работали некоторые комбинации скриптов.
CSRF и кеш
Добавлен метод yiiwebView::registerCsrfMetaTags()
. Он регистрирует CSRF теги динамически, что позволяет быть уверенным, что кеширование на них не влияет.
Новые методы форматтера
В Formatter
добавлены следующие методы:
asWeight()
форматирует число как вес, то есть "12 kilograms".asShortWeight()
форматирует число как вес в короткой форме, то есть "12 kg".asLength()
форматирует число как длину, то есть "12 meters".asShortLength()
форматирует число как длину в короткой форме, то есть "12 m".
Автор: Александр Макаров