What to Expect from Yii 2.0

Share this article

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.

Requirements

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.

Installation

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…

Yii2_installed.png

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.

<?php
$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.

<?php
echo `Yii::t('app', 'Hello, {username}!', [
  'username' => $username,
]);
?>

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

<?php
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:

<?php
//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.

Controllers

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():

<?php
    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.

Models

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:

<?php
$authors = Authors::find()
    ->where(['sitepointChannel' => $channel])
    ->orderBy('lastName')
    ->all();
?>

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:

<?php
//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:

<?php
//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'])
    ->via('Posts');
}
//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.

Views

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.

Conclusion

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!

Frequently Asked Questions about Yii 2.0

What are the new features in Yii 2.0 compared to its previous versions?

Yii 2.0 comes with a host of new features and improvements over its predecessors. It now supports the use of namespaces, which makes code organization much easier. It also introduces a new routing system that is more flexible and powerful. The ActiveRecord classes have been redesigned to support more database types, including NoSQL databases. The framework also includes a new RESTful API development support, making it easier to build APIs. Additionally, Yii 2.0 has improved security features, including built-in CSRF (Cross-Site Request Forgery) protection.

How does Yii 2.0 handle internationalization (i18n)?

Yii 2.0 has a robust internationalization (i18n) support. It allows you to store multiple translations of the same message in different languages. You can also format dates, numbers, and currencies according to the locale. Yii 2.0 also supports plural forms and message selection based on the context.

What is the Yii 2.0 debugger and how does it work?

The Yii 2.0 debugger is a powerful tool that helps you debug your applications. It collects and displays information about each request made to your application, including the SQL queries executed, the request and response data, and the performance timing data. You can access this information through a panel at the bottom of your application’s pages.

How can I extend Yii 2.0 with third-party extensions?

Yii 2.0 supports the use of third-party extensions, which can be installed using the Composer package manager. Once installed, you can use these extensions just like the built-in features of Yii. The Yii community has developed a wide range of extensions that provide additional functionality, such as user authentication, form validation, and database abstraction.

How does Yii 2.0 handle database migrations?

Yii 2.0 provides a powerful database migration tool that allows you to version control your database changes. You can create a new migration using the yii migrate/create command. The migration script will contain methods for applying and reverting the migration. You can then apply the migration using the yii migrate/up command.

How does Yii 2.0 support RESTful API development?

Yii 2.0 provides a set of tools to help you develop RESTful APIs. It includes support for routing, request processing, response formatting, and error handling. You can also use the ActiveController class to quickly generate CRUD (Create, Read, Update, Delete) actions for your API.

How does Yii 2.0 handle form validation?

Yii 2.0 provides a powerful form validation system. You can define validation rules for your form fields in the model class. When a form is submitted, Yii will automatically validate the input data against these rules and generate appropriate error messages.

How does Yii 2.0 handle user authentication?

Yii 2.0 provides a flexible user authentication system. It supports both traditional username/password authentication and more modern methods like OAuth and OpenID. You can also extend the built-in User model to add your own authentication methods.

How does Yii 2.0 handle error handling and logging?

Yii 2.0 provides a robust error handling and logging system. It can catch and handle both PHP errors and exceptions. The errors can be logged in different formats and sent to different destinations, such as files, emails, and browsers.

How can I test my Yii 2.0 applications?

Yii 2.0 provides a testing framework based on PHPUnit and Selenium. It supports both unit testing and functional testing. You can write test cases to test your models, views, and controllers. The testing framework also provides methods to simulate user inputs and check the output.

Arno SlatiusArno Slatius
View Author

Arno Slatius is a web developer from the Netherlands. He has a background in electronics and embedded systems and started web development over a decade ago, He works with Yii professionally and loves digging into new things. Arno loves clean, commented and simple code. When he's not coding, he spends most of his time with his family or flying his model helies, planes and quads.

BrunoScomposerframeworkOOPHPPHPyiiyii2
Share this article
Read Next
Get the freshest news and resources for developers, designers and digital creators in your inbox each week