The Rundown
Yii Framework is getting ever closer to a 2.0 release, with the public preview announced in March now only having 60 open issues (579 closed). There are a lot of changes from Yii 1.1. Let’s take a look at a few of ’em.
Namespaces
Now that PHP 5.3 is required, and being that Yii 2.0 is not trying to be backwards-compatible with Yii 1.1, namespaces are used everywhere. The ‘C’ prefix from framework components has also been dropped as it is no longer needed
use yiihelpersHtml;
echo Html::submitButton('Login', array('class' => 'button'));
Testing
Yii 2.0 integrates with Codeception, described as "PHPUnit on steroids." With Symfony 2, Yii 2, and Zend Framework integration, it looks to have been accepted as an improved testing framework since being released in January 2012. It still integrates with Selenium, and elements can still be matched by name, CSS or XPath.
Requirements Checker
When your app requires a list of PHP extensions or settings, or external libraries to function correctly, it’s often necessary to write some sort of requirements checker. Yii 2 includes one right in the box, ready for your customizations.
$requirements = array(
array(
'name' => 'PHP Some Extension',
'mandatory' => true,
'condition' => extension_loaded('some_extension'),
'by' => 'Some application feature',
'memo' => 'PHP extension "some_extension" required',
),
);
Source: framework/yii/requirements/YiiRequirementChecker.php
Events
Yii 2 throws out the "onBeforeNsa"-type event methods in favor of a single on() method.
// attach handler
$component->on($eventName, $handler);
// detach handler
$component->off($eventName, $handler);
// trigger event
$component->trigger('beforeGettingSnowden');
Views
Yii 2 gives some much-needed attention to views by way of implementing an actual View class. In addition, View takes over the roles of the old CClientScript.
Most notably, within a view, $this
corresponds to the current view now instead of the controller or widget that is rendering it. $this->context
now refers to the controller or widget object.
Yii 2 also works out of the box with Smarty and Twig, if you desire those template engines.
Source: framework/yii/base/View.php
Models
Massive assignment has changed a bit. Instead of doing:
if (isset($_POST['userModel']))
{
$model->attributes = $_POST['userModel'];
}
… you can just do:
$model->load($_POST);
The key thing here is is that load() will automatically check for an appropriate index within $_POST
, defined by the override-able $model->formName()
.
Source: framework/yii/base/Model.php
Validation
Instead of model rules()
specifying which validation rules to use for which attributes on which validation scenario (e.g. "on"=>"createUser"
), Yii 2 adds a new method scenarios()
to declare which attributes require validation under which scenario (breathe!). This is an optional method; if you have but one validation scenario in your model you need not implement scenarios()
.
public function scenarios()
{
return array(
'createPlayer' => array('email', '!name'),
'joinGame' => array('gameId'),
);
}
Marking attributes as safe or unsafe is no longer done as it was in Yii 1; there are no "safe" or "unsafe" validators anymore. Instead, if an attribute is unsafe, you would prefix it with an exclamation point within the scenario.
ActiveRecord
Gone are the relations()
, now replaced by getters that return ActiveQuery objects.
class Game extends yiidbActiveRecord
{
public function getPlayers()
{
return $this->hasMany('Player', array('game_id' => 'id'));
}
}
The relation can thus still be used via $game->players
, but now you can customize query conditions on the fly, e.g.:
$winning = $game->getPlayers()->andWhere('winning=1')->all();
In Yii 1, the model()
method was used all over the place. This is no more in Yii 2. Instead, you use the much-improved find()
method which returns an ActiveQuery instance.
// get all active players
$players = Player::find()
->where(array('active'=>1))
->orderBy('id')
->all();
// get the player whose PK is 1
$firstPlayer = Player::find(1);
And when you want your records as arrays instead of objects, you can just tell ActiveQuery to make it so.
$players = Player::find()->asArray()->all();
Source: framework/yii/db/ActiveRecord.php
Controllers
render()
and renderPartial()
now no longer send output directly. For me this means one less additional parameter to remember, and more consistency.
Source: framework/yii/base/Controller.php
Onwards!
The more I dig through Yii 2, the more excited I am to use it. I still haven’t converted any Yii 1.x sites to it, but it is certainly worth considering for upcoming Yii Framework projects.
Further reading:
Yii Framework: Upgrading from Yii 1.1.