What to Expect from Yii 2.0

By Arno Slatius

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!

  • masudianpour

    Nice introduction. Thank you/

    • Arno Slatius

      You’re welcome.

  • dojoVader

    Yii Framework is a superb framework, what’s so superb about it is the way you can create usable classes from Validators,Widgets,Portlets,Component,Behaviours its so superb you gain the benefit from Yii when you create future Projects as you reuse every previous extension. Gii too is another superb tool, what am really hyped to see is the introduction of Composer, Namespace and Generators (ability to create your own custom generator). this is my backup framework as ZF2 isn’t for mere mortals like me :D nice article

    • Arno Slatius

      I agree completely, the re-usability factor of Yii based code is huge. I always grab pieces of other projects when I start a new one. It’s amazing how fast you’re able to realize something new that way.

  • Syed Zaeem ud Din

    I am waiting for the final stable release of Yii 2.0. Screenshots in article look great and they are much better than version 1. Thanks for the introduction.

    • pentium10

      We are using in production ready already, and if you know composer you can manage that way, and if you watch for security issues you can upgrade quickly. Coding is much more fun now.

      • Syed Zaeem ud Din

        Thank you for providing me more confidence to use Yii2.0 for production via composer. I’m on it now :-)

  • Said Bakr

    There are many PHP frameworks promise that it fast and quick application development tool. However, Yii is really do this.

  • Loganatan

    Thank you sitepoint. I did not expect you will also write tutorial for yii..i love this and go through

  • Zein Miftah

    Looking forward to this change.

  • darkheir

    Nice introduction.
    There is a great stuff that Yii 2 will add: the ability to quickly create a rest API. This is going to be really usefull!

  • Vincent

    I am writing a large and complex web application on top of Yii2 since november 2013. My experience has been very positive: we had to cope with a few breaking changes, but were never seriously hindered by the pre-release status. As our app is about to go live, I am confident about the framework, even if it is not officially released.

    But we do have around 3000 unit tests which we always run before deploying a new version of Yii2, so bear in mind that before the 1.0 release, any composer update might break your app :-)

    I sincerely want to thank the Yii2 core developers and all the other regular contributors. I think it is a superb piece of work, and it deserves much more attention!

  • Michel

    Great article, I want to know that is it really safe to start an entire application using Yii2 ? Its still beta … What kind of problems may we encounter ?

  • Carlos Mathers

    This shit’s pretty fucking sweet

  • Ahmed Mohamed

    We already working with yii2 for developing our new projects, It’s really awesome and every thing just work fine and fast, YII is Awesome

  • R22

    There’s a special page dedicated to upgrading Yii on the Yii website. Broken link here.

  • Bruno Skvorc

    Fixed, thanks for the heads up!

  • jovani

    The REST module is really awesome!!!

  • igorsantos07

    Any special reason for the more verbose relations?
    Models will get bloated with those methods now…

    There was a good reaction when Ardent (Eloquent’s son) added Yii1 relationship declaration style in addition to the original method – the same method on Yii2.

    • Arno Slatius

      I agree that the verbose relations will bloat the models but the guide ( only talks about these relations. They allow for more possibilities so they were certainly something good to mention.

      I can’t seem to find anything about the Yii 1 style relations in the Yii 2 docs, can you point me there because I’m certainly interested.

      • igorsantos07

        Just another person preferring old-style relations… Haha
        Anyways, I didn’t mean that hii2 had tat; I was talking about Ardent, a library above Laravel’s AR – Eloquent.

  • Arno Slatius

    Perhaps you all already saw it but Yii 2.0 went RC last sunday.

  • Jasper van der Hoeven

    What strikes me about the code examples above is that almost everything is called statically. Doesn’t this hurt testability?

    • Arno Slatius

      I actually had read back to understand what you were saying. But you’re right, the examples here use a lot of static functions.

      The static functions like Yii::t and CHtml::encode are very basic functions that use the static $app from the YiiBase class that holds all the application components and configuration of the application. They’ll therefore behave the way you’ve configured your application to behave. These are not something you’ll include in your testing since they are part of the framework itself..

      The ActiveRecord find() function returns an instance of ActiveQuery for the class it is called for and is therefore quite test-able I’d say.
      Does that answer your question or were you referring to something else?

      • Jasper van der Hoeven

        It does answer my question.. partially ;-)
        I understand that Yii::t and CHtml::encode are part of the framework itself and shouldn’t necessarily be part of tests you’ll want to run. However seeing code like $authors = Authors::find()->etc.. How would I go about mocking the Authors class?

        • Arno Slatius

          Can you explain when you’d want that?
          The Authors class would be a part of your application and your link to the database. You’d want to test whatever logic you put in there so I don’t see a scenario when you’d need a mock Authors.

          • Jasper van der Hoeven

            Let’s say I have a controller method that holds $authors = Authors::find()->etc.. code and I only want to test if the controller returns a string. I would not want to test the Authors:find()->etc.. code so I would typically mock it to make my unit test more concise. Now there is no way to test the controller method without testing the Authors class too.

          • Arno Slatius

            Ah, oke now I understand where you’re going. You’re looking for test fixtures I know the theory but I haven’t used that with Yii 2 yet. I can only point you towards the documentation, sorry.

            Test fixtures are a way to either fill a test database with predefined values or mock a complete database with your data. That way you’re sure you can always get the same result set and write test cases that validate.

          • Jasper van der Hoeven

            That was (kind of) what I was looking for. Still from a pure unit test perspective I would prefer to be able to mock objects to keep the scope of my tests as small as possible. Thanks for the link!

          • Arno Slatius

            It depends on the objective of your test really; if the goal is to test a class on it’s own then I’d agree. We’re talking about a database related model here and you probably want to test the business logic in your data model; test the defined database relations of the class, data validation rules and before/after validate/save events. Then you need data from a test fixture.

  • gondoSVK

    you have an error in one of yours code example:
    echo `Yii::t
    should be:
    echo Yii::t

  • jennifermorrison

    Sure we should expect some good things from Yii2.0. I hope it will be growing fast.Recently i studied this article about reasons to use Yii2.0 Framework. They talk about only eight reasons. i think its having some other reasons to use YII2.0 framework. We should find that.



Because We Like You
Free Ebooks!

Grab SitePoint's top 10 web dev and design ebooks, completely free!

Get the latest in PHP, once a week, for free.