PHP - - By Matthew Beaumont

7 Reasons to Choose the Yii 2 Framework

Late last year, SitePoint published an article highlighting the top PHP frameworks. Tied for the number four spot was the Yii (pronounced Yee) Framework. At that time the latest version of the framework available was 1.1.14. Recently, Yii 2.0 was made available, so you can begin to use it in production.

While we did cover it recently when it was still in RC status, it just reached full release status, and we feel like it’s time to revisit the topic with some reasons for choosing it over alternatives.

1. Easy to Install

For web developers, time is money, and no one wants to spend their precious time on a complicated installation and configuration process.

Installation is handled using Composer. If you want a description of the installation process, Sitepoint recently published a great article here. I tend to favor using the basic application template, even when my site has a separate front- and backend component. Instead, I opt to use a Module for the backend portion of my sites. (Yii Modules are best described as mini-applications which reside inside your main application).

Note: Many of the directory references in later examples use the directory structure from the simple template.

2. Utilizes Modern Technologies

Yii is a pure OOP framework, and takes advantage of some of PHP’s more advanced features, including late static binding, SPL classes and interfaces, and anonymous functions.

All classes are namespaced, which allows you to take advantage of their PSR-4 compliant autoloader. That means that including Yii’s HTML helper class is as simple as:

use yii\helpers\Html;

Yii also allows you to define aliases to help simplify your namespaces. In the above example, that use statement will load a class definition which is located by default in the directory /vendor/yiisoft/yii2/helpers. This alias is defined in the BaseYii class on line 79:

public static $aliases = ['@yii' => __DIR__];

The framework itself is installed using Composer, as are its extensions. Even the process of publishing extensions is as easy as creating your own composer.json, hosting your code at Github, and listing your extension on Packagist.

3. Highly Extensible

Yii is like a suit that looks great off of the rack, but is also very easy to tailor to fit your needs. Virtually every component of the framework is extensible. A simple example is the addition of a unique body ID to your views. (In case you’re interested in knowing why you might want to do this, take a look at this article).

First, I would create a file in my app\components directory with the name View.php, and add the following:

namespace app\components;

class View extends yii\web\View {

    public $bodyId;

    /* Yii allows you to add magic getter methods by prefacing method names with "get" */

    public function getBodyIdAttribute() {
        return ($this->bodyId != '') ? 'id="' . $this->bodyId . '"' : '';
    }

}

Then, in my main layout file (app\views\layouts\main.php), I would add the following to the body tag of my HTML:

<body <?=$this->BodyIdAttribute?>>

And finally, I would add the following to my main configuration file to let Yii know to use my extended View class instead of its own default:

return [
    // ...
    'components' => [
        // ...
        'view' => [
            'class' => 'app\components\View'
        ]   
    ]
];

4. Encourages Testing

Yii is tightly integrated with Codeception. Codeception is a great PHP testing framework that helps simplify the process of creating unit, functional and acceptance tests for your application. Because you ARE writing automated tests for all your applications, right?

The Codeception extension makes it simple to configure your application during testing. Simply edit the provided /tests/_config.php file to configure your test application. For example:

return [
    'components' => [
        'mail' => [
            'useFileTransport' => true,
        ],
        'urlManager' => [
            'showScriptName' => true,
        ],
        'db' => [
                'dsn' => 'mysql:host=localhost;dbname=mysqldb_test',
        ],
    ],
];

Using this configuration, the following would happen:

  1. Any emails sent during your functional and acceptance tests would be written to a file instead of being sent.
  2. The URLs in your tests would take on the format index.php/controller/action rather than /controller/action
  3. Your tests would use your test database, rather than your production database.

A special module for the Yii Framework also exists within Codeception. It adds several methods to the TestGuy class, which help you work with Active Record (Yii’s ORM) during functional tests. For instance, if you wanted to see if your registration form successfully created a new User with the username “testuser”, you could do the following:

$I->amOnPage('register');
$I->fillField('username', 'testuser');
$I->fillField('password', 'qwerty');
$I->click('Register');
$I->seeRecord('app\models\User', array('name' => 'testuser'));

5. Simplifies Security

Security is a crucial part of any web application, and fortunately Yii has some great features to help ease your mind.

Yii comes with a Security application component that exposes several methods to help assist in creating a more secure application. Some of the more useful methods are:

  • generatePasswordHash: Generates a secure hash from a password and a random salt. This method makes a random salt for you, and then creates a hash from the supplied string using PHP’s crypt function.
  • validatePassword: This is the companion function to generatePasswordHash, and allows you to check whether the user supplied password matches your stored hash.
  • generateRandomKey: Allows you to create a random string of any length

Yii automatically checks for a valid CSRF token on all unsafe HTTP request methods (PUT, POST, DELETE), and will generate and output a token when you use the ActiveForm::begin() method to create your opening form tag. This feature can be disabled by editing your main configuration file to include the following:

return [
        'components' => [
            'request' => [
                'enableCsrfValidation' => false,
            ]
    ];

In order to protect against XSS, Yii provides another helper class called HtmlPurifier. This class has a single static method named process, and will filter your output using the popular filter library of the same name.

Yii also includes ready-to-use classes for user authentication and authorization. Authorization is broken into two types: ACF (Access Control Filters) and RBAC (Role-Based Access Control).

The simpler of the two is ACF, and is implemented by adding the following to the behaviors method of your controller:

use yii\filters\AccessControl;

class DefaultController extends Controller {
    // ...
    public function behaviors() {
        return [
            // ...
            'class' => AccessControl::className(),
            'only' => ['create', 'login', 'view'],
                'rules' => [
                [
                    'allow' => true,
                    'actions' => ['login', 'view'],
                    'roles' => ['?']
                ],
                [
                    'allow' => true,
                    'actions' => ['create'],
                    'roles' => ['@']
                ]
            ]
        ];
    }
    // ...
}

The preceding code tells DefaultControllerto allow guest users to access the login and view actions, but not the create action. (? is an alias for anonymous users, and @ refers to authenticated users).

RBAC is a more powerful method of specifying which users can perform specific actions throughout your application. It involves creating roles for your users, defining permissions for your app, and then enabling those permissions for their intended roles. You could use this method if you wanted to create a Moderator role, and allow all users assigned to this role to approve articles.

You can also define rules using RBAC, which allow you, under specific conditions, to grant access to certain aspects of your application. For instance, you could create a rule that allows users to edit their own articles, but not those created by others.

6. Shorten Development Time

Most projects involve a certain amount of repetitive tasks that no one wants to waste time with. Yii gives us a few tools to help you spend less time on those tasks, and more time customizing your application to suit your clients’ needs.

One of the most powerful of these tools is called “Gii”. Gii is a web-based code scaffolding tool, which allows you to quickly create code templates for:

  • Models
  • Controllers
  • Forms
  • Modules
  • Extensions
  • CRUD controller actions and views

Gii is highly configurable. You can set it to only load in certain environments. Simply edit your web configuration file as follows:

if (YII_ENV_DEV) {
    // ...
    $config['modules']['gii'] = [
        'class' => 'yii\gii\Module',
        'allowedIPs' => ['127.0.0.1', '::1']
    ]
}

This ensures that Gii will only load when the Yii environment variable is set to development, and that it will only load when accessed via localhost.

Now let’s take a look at the model generator:

Gii Model Generator

The table name uses a typeahead widget to try to guess which table your model is associated with, and all fields have a rollover tooltip to remind you how to fill them out. You can preview code before you ask Gii to generate it, and all the code templates are completely customizable.

There are also several command-line tools available to help create code templates for database migrations, message translations (I18N) and database fixtures for your automated tests. For instance, you can create a new database migration file with this command:

yii migrate/create create_user_table

This will create a new migration template in {appdir}/migrations that looks something like this:

<?php

    use yii\db\Schema;

    class m140924_153425_create_user_table extends \yii\db\Migration
    {
        public function up()
        {

        }

        public function down()
        {
            echo "m140924_153425_create_user_table cannot be reverted.\n";

            return false;
        }
}

So let’s say I wanted to add a few columns to this table. I would simply add the following to the up method:

public function up()
{
    $this->createTable('user', [
        'id' => Schema::TYPE_PK,
        'username' => Schema::TYPE_STRING . ' NOT NULL',
        'password_hash' => Schema:: TYPE_STRING . ' NOT NULL'
    ], null);
}

And then to make sure I can reverse the migration, I would edit the down method:

public function down()
{
    $this->dropTable('user');
}

Creating the table would simply involve running a command on the command line:

./yii migrate

and to remove the table:

./yii migrate/down

7. Easy to Tune for Better Performance

Everybody knows that a slow website creates disgruntled users, so Yii provides you with several tools to help you squeeze more speed out of your application.

All Yii’s cache components extend from yii/caching/Cache, which allows you to choose whichever caching system you want while using a common API. You can even register multiple cache components simultaneously. Yii currently supports database and file system caching, as well as APC, Memcache, Redis, WinCache, XCache and Zend Data Cache.

By default, if you’re using Active Record then Yii runs an extra query to determine the schema of the table(s) involved in generating your model. You can set the application to cache these schema by editing your main configuration file as follows:

return [
    // ...
    'components' => [
        // ...
        'db' => [
            // ...
            'enableSchemaCache' => true,
            'schemaCacheDuration' => 3600,
            'schemaCache' => 'cache',
        ],
        'cache' => [
            'class' => 'yii\caching\FileCache',
        ],
    ],
];

Finally, Yii has a command line tool to facilitate the minification of frontend assets. Simply run the following command to generate a configuration template:

./yii asset/template config.php

Then edit the configuration to specify which tools you want to you perform your minification (e.g. Closure Compiler, YUI Compressor, or UglifyJS). The generated configuration template will look like this:

<?php
    return [
        'jsCompressor' => 'java -jar compiler.jar --js {from} --js_output_file {to}',
        'cssCompressor' => 'java -jar yuicompressor.jar --type css {from} -o {to}',
        'bundles' => [
            // 'yii\web\YiiAsset',
            // 'yii\web\JqueryAsset',
        ],
        'targets' => [
            'app\config\AllAsset' => [
                'basePath' => 'path/to/web',
                'baseUrl' => '',
                'js' => 'js/all-{hash}.js',
                'css' => 'css/all-{hash}.css',
            ],
        ],
        'assetManager' => [
            'basePath' => __DIR__,
            'baseUrl' => '',
        ],
    ];

Next, run this console command in order to perform the compression.

yii asset config.php /app/assets_compressed.php

And finally, edit your web application configuration file to use the compressed assets.

'components' => [
    // ...
    'assetManager' => [
        'bundles' => require '/app/assets_compressed.php'
    ]
]

Note: You will have to download and install these external tools manually.

Conclusion

Like any good framework, Yii helps you create modern web applications quickly, and make sure they perform well. It pushes you to create secure and testable sites by doing a lot of the heavy lifting for you. You can easily use most of its features exactly as they are provided, or you can modify each one to suit your needs. I really encourage you to check it out for your next web project!

Have you tried Yii 2? Will you? Let us know!