Yii2 dev digest #7 Apr'14
Apr 16, 2014, 10:07:12 AMLucky 7th digest dedicated to Beta release . Not so much really new to say after Beta release notes on Yii site, but I can't stay away :)
Thanks for a big PR campaign by Alexander Makarov (@sam_dark), previous dev digest was seen by more than 5500 people. Quite impressive and gives me more inspiration to make new reviews!
As usual - Russian version of this digest is available (see the link above) !
tl;dr;
Yii2 beta Release, PSR-2, DI, new RBAC, consistent Url helper, a lot of new widgets
- Yii 2 beta Released on April 13. Official press-release is great in details, you should definitely read it through. Russian press-release.
- Official docs for Yii 2.0
Yii2 now follow PSR-2. Yes "Space" intendation wins. Now tools like PHPCodeSniffer will work with Yii2 better.
It is not about pro-contra features, it's just about having the same standard across the PHP world.
Dependecy Injection container out of the box. Yii2 is not migrating completely to DI concepts, but gives you an utility class for DI in your app.
- Introduced universal URL helper class. Samdark made a good explanation in Russian in his blog also in Beta release notes it has good usage examples. Very handy helper class!
- Remastered RBAC. Biz rules are separate classes now, no eval.
- Conditional validators. Custom anonymous function
when
could be use with all validators to have additional control on validator usage. AlsowhenClient
for a client side. - REST Api got more improvements, but still something left fot RC and GA releases.
- Added
ContentNegotiator
to support response format and language negotiation - Added separate
bootstrap
ability to init different Classes on each App run. Similar to formerpreload
, but now it is unified way for Extensions and Components. - Added
loadDefaultValues
for AR Model. As a generic way to set default values and not overuse "default" validator or custominit
. - More consistent AR
find()
usage. IntroducedfindOne
andfindAll
. - Ability to use Gii via CLI
- Added
yii\web\ViewAction
that allow render views based on GET parameter, aka Static Pages - Added
PrefixUrlRule
that represents a collection of URL rules sharing the same prefix in their patterns and routes.. It is best used by a module which often uses module ID as the prefix for the URL rules. - There will no be offficial out of the box integration with Bower. It's considered not a server-side framework core issue - and I am agree with it. In any case thos who need it - will find a way to use with his tools stack.
- Non official examples of custom app structures
Yii2 Development Visualization
Yii2 Extensions
- 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
- Extended CRUDs for Yii2 with relation and automatic field type detection (WIP). First look on a screenshot.
Come on people! Connect your efforts to other great contributors as 2amigos, create and share your extensions. Let's increase Yii2 ecosystem !
Yii2 Tips & Tricks
Yii2 forum thread where ORey share his Yii2 tips.
Is there HTTP Client in Yii2 ?
No, use some great 3rd party libs like Guzzle via Composer
How to get path to registerd Assets?
$path = AppAsset::register($this);
How to attach Behavior multiple times
The same way as in Yii1. Then get it by name
$model->getBehavior('xxx')->method()
How to get url by Model params?
To get something like this
site.com/somerouting/?Post[name]=smth&Post[date]=01.01.2014
$url = ['site/index'];
$url['Model'] = $model->attributes;
echo Url::to($url);
Why used string representation of class name instead of className() method in app template configs?
Using 'className' has the drawback that the class needs to be included even if it is not used in a request.
How to make dynamic relation in Model and reuse declaration in different context?
I have the following models:
common\models\ArticleData
backend\models\ArticleData (extends from common\models\ArticleData)
frontend\models\ArticleData (extends from common\models\ArticleData)
This way I can re-use this relation both from backend and frontend without re-declaring
$calledClass = static::className();
$nsPosition = strrpos($calledClass, '\\');
$calledNS = substr($calledClass, 0, $nsPosition);
...
return $this->hasMany(forward_static_call([$calledNS . '\ArticlesData', 'className']), ['bla' => 'bla_id']);
What is the performance issues with DI container usage?
There is some drawback by using DI container. It is mainly related with the performance degradation caused by constructor injection because the container needs to use reflection to detect dependencies. That means, the instantiation of every application component will be slightly slower.
How to setup Request component to use urlManager for making URLs in Console app ?
'request'=> [
'class' => '\yii\web\Request',
'hostInfo' => $params['backendUrl'],
'baseUrl' => $params['backendUrl'],
],
or mock $_SERVER somewhere in app bootstrap
$_SERVER['SERVER_NAME'] = 'mydomain.com';
$_SERVER['HTTP_HOST'] = 'mydomain.com';
Back to the DI. Below is an example of using DI Container from class docs
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);