Yii2 дайджест новостей разработки #7 Апр'14
16 апр. 2014 г., 10:04:09Счастливый 7-ой дайджест в честь Бета релиза. Хотя после развёрнутой заметки о Beta релизе на habrahabr, не так много нового, но всё же :)
Благодаря PR кампании Александра Макарова (@sam_dark), прошлый дайджест посмотрели более 5500 человек. Это радует и вдохновляет!
tl;dr;
Yii2 beta выпущена, PSR-2, DI, новый RBAC, улобный Url helper, много новых виджетов
- Yii 2 beta выпущена 13го апреля. В официальном пресс релизе и его русском переводе множество детальных описаний и примеров - обязательно посмотрите.
- Официальная документация по Yii 2.0
Yii2 стал следовать стандарту кодирования PSR-2. Да, "пробелы" победили. Отныне библиотеки типа PHPCodeSniffer будут работать с Yii2 лучше.
Разговор не о доводах "за"/"против", дело лишь в том, чтобы иметь одинковые стандарты в PHP мире.
Dependecy Injection контейнер из-коробки. Yii2 не переходит полностью на концепцию DI, но даёт готовый убодный класс, чтобы мы могли использовать DI в наших приложениях.
- Введён универсальный класс URL helper. Samdark хорошо расписал это в своём блоге и на Хабре в статье о Бета релизе. Очень удобный класс!
- Переосмысленный RBAC. Biz rules сейчас в виде отдельных классов и без
eval
. - Условные валидаторы. Собственная анонимная функция
when
может быть использована во всех валидаторах для специфического контроля применения данного валидатора. А также отдельная функцияwhenClient
для клиентской стороны. - REST Api совершенствуется, но ещё кое-что осталось для RC и GA релизов.
- Добавлен
ContentNegotiator
для определения формата и языка ответа - Добавлен
bootstrap
функционал для инициализации различных классов при старте приложения. Как я понимаю, он схож сpreload
, но унифицирован для расширений и компонент. - Добавлена функция
loadDefaultValues
для AR моделей. Как обобщённый путь для установки значений по-умолчанию без лишних валидаторов "default" и кастомизацииinit
. - Более целостное использование
find()
в AR. Введены методыfindOne
иfindAll
. - Возможно использовать Gii в CLI режиме
- Добавлен экшн
yii\web\ViewAction
, позволяющий рендерить представление по идентификатору из GET параметра, а-ля "статические страницы" - Добавлен
PrefixUrlRule
, представляющий набор URL правил с общим префиксом в путях.. Необходим, например, для модулей , где часто в пути присутствует ИД модуля. - Не будет официальной интеграции с JS менеджером пакетов Bower. Это предпологается не сферой ответсвенности server-side фрэймворка - и я думаю это правильно. В любом случае, тот кому это действительно нужно - найдёт способ подобной интеграции.
- Неофициальные примеры структур приложения
Визуализация разработки Yii2
Новые расширения Yii2
- Yii2 EpicEditor Markdown widget
- Yii2 Kudos widget
- Yii2 Share links widget
- Yii2 Lepture Markdown editor widget
- TinyMCE Widget for Yii2
- CKeditor Widget for Yii2
- Leaflet Widget for Yii2
- Yii2 resource manager component
- Yii2 taggable behavior
- Yii2 Highcharts widget
- X-Editable Widget for Yii2
- GridView Extensions for Yii2
- Расширенный CRUDs для Yii2 с автоматическим определением связей и типов полей (WIP). Первые скриншоты.
Подключайтесь, друзья! Создавайте и делитесь своими расширениями как это делает, например, 2amigos. Давайте расширять этоксистему Yii2 !
Yii2 Tips & Tricks
Форумная ветка Yii2, где ORey делится своими советами по Yii2.
-
Нет, используйте хорошие сторонние библиотеки типа Guzzle через Composer
Как получить путь, по которому зарегистрированны Assets?
$path = AppAsset::register($this);
Как многократно подключить и использовать Behavior
Точно также как и в Yii1. А потом вызывайте по имени
$model->getBehavior('xxx')->method()
Как создать url по параметрам Модели ?
Чтобы получить урл а-ля
site.com/somerouting/?Post[name]=smth&Post[date]=01.01.2014
$url = ['site/index'];
$url['Model'] = $model->attributes;
echo Url::to($url);
Зачем указывать имя класса в строков виде, вместо использования метода className() в конфиге?
У использования 'className' есть один недостаток - класс уже должен быть загружен, даже если в итоге не используется в запросе.
Как сделать динамическую связь в Модели и повторно использовать декларацию в разных контекстах?
Есть такие модели:
common\models\ArticleData
backend\models\ArticleData (extends from common\models\ArticleData)
frontend\models\ArticleData (extends from common\models\ArticleData)
Так можно повторно использовать их на фротэнде и бекэнде, без переопределения
$calledClass = static::className();
$nsPosition = strrpos($calledClass, '\\');
$calledNS = substr($calledClass, 0, $nsPosition);
...
return $this->hasMany(forward_static_call([$calledNS . '\ArticlesData', 'className']), ['bla' => 'bla_id']);
В чём проблема с производительностью при использовании контейнеров DI?
Проблема в основном связана с падением производительности при внедрнеии конструктора, т.к. для определения необходимой зависимости контейнре использует механизм рефлексии (что есть не самая быстрая операция). Это замедляет инстанциирование каждого компонента.
'request'=> [
'class' => '\yii\web\Request',
'hostInfo' => $params['backendUrl'],
'baseUrl' => $params['backendUrl'],
],
или подменить переменную $_SERVER где-то в процессе инициализации
$_SERVER['SERVER_NAME'] = 'mydomain.com';
$_SERVER['HTTP_HOST'] = 'mydomain.com';
Возвращаясь к DI. Ниже приведу пример использования DI Container из документации к классу
namespace app\models;
use yii\base\Object;
use yii\db\Connection;
use yii\di\Container;
interface UserFinderInterface
{
function findUser();
}
class UserFinder extends Object implements UserFinderInterface
{
public $db;
public function __construct(Connection $db, $config = [])
{
$this->db = $db;
parent::__construct($config);
}
public function findUser()
{
}
}
class UserLister extends Object
{
public $finder;
public function __construct(UserFinderInterface $finder, $config = [])
{
$this->finder = $finder;
parent::__construct($config);
}
}
$container = new Container;
$container->set('yii\db\Connection', [
'dsn' => '...',
]);
$container->set('app\models\UserFinderInterface', [
'class' => 'app\models\UserFinder',
]);
$container->set('userLister', 'app\models\UserLister');
$lister = $container->get('userLister');
// which is equivalent to:
$db = new \yii\db\Connection(['dsn' => '...']);
$finder = new UserFinder($db);
$lister = new UserLister($finder);