By Arno Slatius

What to Expect from Yii 2.0

By Arno Slatius
Help us help you! You'll get a... FREE 6-Month Subscription to SitePoint Premium Plus you'll go in the draw to WIN a new Macbook SitePoint 2017 Survey Yes, let's Do this It only takes 5 min

Yii 2.0 was released into beta last April and the goal for a first stable release was set for the middle of 2014. The GitHub issue list has 300 open issues and 2913 closed while I’m writing this and both numbers are still increasing. The progress to the 2.0RC milestone was at 99%. My guess is that the team is close, but we’ll probably have to wait just a little bit longer. While we’re all waiting, lets take a look at what we can expect by looking at an already available example.

A tiny bit of history

The first version of Yii became popular quite fast after it was released in 2008. It’s founder, Qiang Xue, previously worked on the Prado framework and used experience and feedback from that to build Yii.

Yii uses many ideas from other frameworks, languages and libraries: Prado, Ruby, jQuery, Symfony and Joomla are all acknowledged as sources of inspiration.

The first commits for Yii 2.0 date back to 2011 but the development picked up last year. The team did a rewrite with an aim to become the state of the art new generation PHP framework. It adopts the latest technologies and features, such as Composer, PSR, namespaces, traits, and more.

Something worth mentioning is that according to the download page Yii version 1.1 support will end on December 31, 2015, so we do get some time to start thinking about making the transition.


The usage of namespaces and traits upped the requirements to PHP 5.4. Additionally, you’ll need the mb_string, PDO and intl extensions when you start developing. This should not be a problem if you run your own server, but might be if you’re on a shared environment. Of course, in time, that issue will disappear.


Yii is now installable from Composer. We’ll go through this installation method soon.

Currently, there are two application examples available. There is a basic example containing a few pages, a contact page and a login page. The advanced example adds a separate front and backend, database interaction, signup and password recovery.

Getting started

I’ll start with the basic example. If you’ve looked at Yii before, you’ll recognize the same basic webapp that Yii 1.1 came with. Install the basic example with Composer using the following command:

composer.phar create-project --prefer-dist --stability=dev yiisoft/yii2-app-basic

You can then check if your server meets the requirements by opening up http://localhost/yii2-app-basic/requirements.php. The actual application will then run from http://localhost/yii2-app-basic/web/.

This is the first important thing to notice: the idea is that you set the document root of your application to the /path/to/application/web, much like with Symfony. The directory layout changed a bit from version 1.1. If you look closely, the change makes sense and will improve the security of your application.

Previously, all the application components (models, views, controllers, framework and vendor libraries) would live under the document root in the protected folder. That way the security depended on .htaccess files to be respected, which meant your application was 100% insecure by default on Nginx. Moving all the application components away from the document root prevents the web server from sending your application components to a user.

You might find yourself looking for the actual framework sources. The framework is a component that was installed using Composer, so it’ll reside under the vendor\yiisoft\yii directory. Here you’ll find a lot more, but for now, we’ll just leave it at that.

For now, let’s change the local web server configuration and set the document root to /path/to/application/web. I added a virtualhost http://yii2-app-basic.localhost/, but do as you see fit for your own situation. The default configuration is set to hide the script file in the URL. If you’re using Apache, you’ll need to add an .htaccess file to the web directory to instruct Apache to do rewriting, it’s not there by default.

RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . index.php

A look at the basic Yii application

Now that we have the basic application running, some congratulations are in order…


Thanks! No rocket science so far.

You’ll start with start page, a static about page, a contact page and a login page. The contact page and login form have the same functionality available as before; captcha code, form validation and two users available for logging in. Logging in does the same as before; close to nothing. Still, it is a good start.

The design of the basic application changed dramatically. Previously you’d get an application built on the Blueprint CSS framework whereas now we start off with Twitter Bootstrap. Improvement? It probably is compared to Blueprint, but then again Bootstrap is a lot more than Blueprint ever tried to be.
Bootstrap will give you all sorts of application components and will speed up building an application. Some might argue on the other hand that all sites look the same with Bootstrap (themes only fix this partially) and it will also make your site larger size-wise. Either way, the integration with Yii 2.0 is done with the yii2-bootstrap extension. This makes it very easy to integrate the Bootstrap components in your views.

Another thing you’ll notice is the debug bar at the bottom. It is installed and activated by default, just like in Symfony. It allows for quick access to loads of information about your configuration, requests and application logging. It’ll keep a history of requests with debug information as well.

Yii2 debugger

Yii handles errors different than PHP normally would. Yii converts all errors (fatal and non-fatal) to exceptions. Those are handled by rendering an insightful output pointing you towards the point where you messed up or your code generated a notice. Even parse errors, for which Yii 1.1 would fall back to the basic PHP errors, get a nicely rendered overview of your code. This is something most of us will appreciate.

Yii2 error handling

Gii is also present again and activated by default.

Yii2 Gii

Gii will help you by generating code for you to start with, another great tool to help speed up your development. It will generate models and controllers for you. The CRUD generator will go one step further and generate a complete MVC set for all the actions. Gii will also generate code better suited for Internationalization (i18n) by immediately inserting the Yii::t() function where you’ll need it.

The basic application now also comes with a simple command line application which you can build upon. Yii 1.1 already supported this but you’d have to get an example from the Wiki.

That’s what you’ll find in the basic application. There is also an advanced application example available. It has a somewhat different structure but adds even more functionality to your application out of the box:

  • User authorization, authentication and password restore.
  • An application split into a front and backend.

Continuing the look at the basic version, let’s take a closer look and dive into the code…

What changed?

A lot has changed. Some changes might confuse you at first, but I find most changes make sense and are easy to accept. Here are some of the changes that I found interesting, fun or puzzling.

The PHP 5.4 requirement made some changes possible; the array short tags are available. It’s also safe to use the echo short tags in views because that doesn’t depend on configuration settings anymore.

$elements = array(1,2,3,4); //Yii 1.1
$elements = [1,2,3,4]; //Yii 2.0
<?php echo $someVar; ?> //Yii 1.1
<?= $someVar ?> //always safe to use in Yii 2.0

A small change, but one you’ll run into fast; before, you’d use Yii::app() to access the application instance and it’s components. In Yii 2.0 this changed from a static function to a static variable Yii::$app.

The translate function Yii::t() is still with us. It instructs Yii to use the i18n component to translate the supplied text to the current language used. You can also instruct it to substitute variables.

echo `Yii::t('app', 'Hello, {username}!', [
  'username' => $username,

The placeholder formatting and styling has been seriously reworked allowing for more formatting options. Some examples:

echo \Yii::t('app', '{n, number} is spelled as {n, spellout}', ['n' => 81]);
echo \Yii::t('app', 'You are {n, ordinal} in line, please hold.', ['n' => 3]); //Will echo "You are 3rd in line, please wait.".
echo \Yii::t('app', 'There {n, plural, =0{are no cats} =1{is one cat} other{are # cats}}!', array(
    'n' => 14,

Because of this placeholder formatting, the DateTimeFormatter is gone:

//Previously in Yii 1.1
Yii::app()->dateFormatter->formatDateTime(time(), 'medium', 'medium');

//In Yii 2.0
echo \Yii::t('app', 'The date is {0, date, short}', time());    //uses the pre-defined 'short' notation (i18n save)
echo \Yii::t('app', 'The date is {0, date, YYYY-MM-dd}', time()); //or define your own notation

This functionality is supplied by the ICU library. The Yii documentation calls the original documentation for this: “quite cryptic”. I dare you to read it and try to understand it… Let’s hope the Yii documentation includes a more readable version in time.


Before, accessControl() would be a function of your controller if you wanted to use the Yii access control functionality. With Yii 2.0, access control is part of the controllers behavior():

    public function behaviors()
        return [
            'access' => [
                'class' => AccessControl::className(),
                'only' => ['logout','login','signup'],
                'rules' => [
                        'allow' => true,
                        'actions' => ['logout'],
                        'roles' => ['@'],
                        'allow' => true,
                        'actions' => ['login', 'signup'],
                        'roles' => ['?'],

This is almost identical to the way it was in Yii 1.1.

I did notice that the example code (not the framework itself!) is missing many docblocks and has a lot of @inheritdoc comments. This isn’t what you’d expect from an example but I assume that this will be fixed in time.


The basic model (previously CModel) didn’t change much. Scenarios now allow you to change the enforcement of validation rules. You can change what needs to be validated based on your current scenario (i.e. a model with different rules when used from a front or backend).

The derived ActiveRecord underwent some serious changes, though. The syntax for searching with ActiveRecord became more like writing queries because CDbCriteria is gone. It has been replaced by ActiveQuery making retrieving information easier:

$authors = Authors::find()
    ->where(['sitepointChannel' => $channel])

Relations definition also changed dramatically. Lets take for example a site with bloggers that post articles on which users comment. The relations definitions for the authors table is described below. I’ll start with how it looked in Yii 1.1:

//Define the relations
public function relations()
  return array(
    'posts' => array(self::HAS_MANY, 'Posts', 'authorID'),
    'comments' => array(self::HAS_MANY, 'Comments', array('ID'=>'PostID'), 'through'=>'posts'),

//Querying an author with posts and comments
$activity = Author::model()->with(array('posts','comments')->find('fullname = "Arno Slatius"');
$posts = $activity->posts;
$comments = $activity->comments;

As you can see, you’d define all the relations of an Active record in a large array. In Yii 2.0 you’ll have to define getter methods that return an ActiveQuery object for all those relations. You’d have to use the keyword ‘through’ in a relation to define a relation between an intermediary table.

You now have two options to define this; normally you’d use the via() method in a relation function. You can also define the relation using the viaTable() method if you only need the data in the table after the pivot table. Same example as above but now for Yii 2.0:

//Define relations by creating getter functions
public function getPosts()
  return $this->hasMany(Posts::className(), ['authorID' => 'ID']);
public function getComments()
  return $this->hasMany(Comments::className(), ['ID' => 'PostID'])
//If you'd only need comments you'd define it at once:
public function getComments()
  return $this->hasMany(Comments::className(), ['ID' => 'PostID'])
    ->viaTable(Posts::className(), ['authorID' => 'ID']);

//Querying an author with posts and comments
$activity= Authors::findOne(['fullname' => 'Arno Slatius']);
$posts = $activity->posts;
$comments = $activity->comments;

This is a rather simple example. Defining the relations through the getter functions that return ActiveQuery objects allows for much more. You can, for instance, add a specific function that does a query for posts that get >50 comments by adding a where() call in the returned ActiveQuery.

An interesting addition is the possibility to define cross DBMS relations. You can define relations between for instance MySQL and MongoDB or Redis and use them in your application as one object.


The main thing to note in views is that $this doesn’t refer to the controller instance anymore. In a view, $this is an instance of the yii\web\View object. The controller is accessible through $this->context.

As I said before; PHP 5.4 makes the short echo tag consistently available. This makes the views which consist of mixed PHP and HTML more readable;

<h1><?= Html::encode($this->title) ?></h1>

The render() and renderPartial() functions changed as well. Before it would echo the rendered output automatically and you’d have to add an additional parameter to get the rendered output as a string. Yii 2.0 will always return a string on render()-like calls making it more consistent with the way widgets behave.

Upgrading from Yii 1.1

Should you consider upgrading your Yii 1.1 application to Yii 2.0 in time?

Bruno Škvorc recently wrote about legacy code here on SitePoint. He argues that a rewrite that can be done in 2 months should be considered – especially if the software you’re using is business critical. I agree with him and would suggest you consider it if you feel seriously about your application and want to maintain it beyond the end of life of Yii 1.1. But as always; it depends on your situation.

There’s a special page dedicated to upgrading Yii on the Yii website. The biggest problem, for now, are your extensions. If you rely on a lot of extensions, you’ll have a hard time because it’ll take some time for the community to take up (re)writing the extensions for Yii 2.0. If you’re a real pro, you could of course take a serious look at the extensions you’re using and consider (re)writing them.

The migration manual has a section on running Yii 1.1 and Yii 2.0 together in an application. For large projects this is a good way to create a safe migration path. Migrate your generic code to Yii 2.0 and take your time on the more complex or extension filled parts.


Going over the The Definitive Guide to Yii 2.0 gets me more and more enthusiastic to get started with Yii 2.0. I already had to stop myself from using it in a new project because I couldn’t risk problems with pre-production code.

The documentation quality for Yii 2.0 improved from Yii 1.1. I had a hard time figuring stuff out when I started with Yii 1.1 a few years ago and I feel the documentation is more extensive than before.

Have you looked at Yii 2.0 already or perhaps even built something with it already? Please tell us what you came across. I would love to know your experiences!

Login or Create Account to Comment
Login Create Account
Get the most important and interesting stories in tech. Straight to your inbox, daily.Is it good?