Yii Tutorial

Yii is a modern and robust PHP framework aimed to secure and scalable programming. It is not hardern or more complex compared to the popular PHP frameworks such as CakePHP. It supports all major databases from MySQL to Sqlite. The best is that it is much faster and scalable compared to other frameworks. The latter is what made me reconsider using it over CakePHP.

SEO and Clean URLs

By default Yii routes all URL requests transparently through the main index.php file and your URLs look like this:

http://example.org/?r=site/page&view=about

Our aim is to make it look:

http://example.org/site/page/view/about

For this purpose follow these steps:

  1. Open your site root protected/config/main.php and uncomment the part about the urlManager so that it looks like this:
    		'urlManager'=>array(
    			'urlFormat'=>'path',
                        'showScriptName'=> false,
    			'rules'=>array(
    				'/'=>'/view',
    			),
    		),
    
    
  2. Add the following lines to your .htaccess (provided you are using Apache or compatible web server): RewriteEngine on RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule . index.php

Last you may wish to drop controller / action from the URL. This can be also done by a custom rule in the urlManager array in protected/config/main.php:

'about'=>'site/page/view/about',

This will ensure that by just going to http://example.org/about you will be routed to http://example.org/site/page/view/about.

That's all. Now your URLs will look better and Google will love your site(may be).

Simple User Authentication With The UserIdentity Component

If you have used the default test drive site of Yii you have found out that it comes with a login. By default there are two users: admin/admin and demo/demo.

In order to change these users you have to edit the file protected/components/UserIdentity.php. The users array looks like this:

$users=array( // username => password 'admin'=>'admin', 'demo'=>'demo, );

It does not seem very safe and secure to keep you passwords in clear plain text file. However, If anyone can read this file it means that he / she can read your configuration file, find out your database logins and execute queries. It will take a minute or two to discover your password or just to insert a new admin user...

Controller methods render and renderPartial

Yii has two powerful methods render and renderPartial for creating the controller's view content. Simply put this is the information the view will receive from the controller.

The difference between render and renderPartial is that the latter will not load the layout. This is useful in case you'd like to have a popup window or ajax functionality which shows short information.

Here is an example with a whole method:

public function actionView($slug) { 
$model = $this->loadSlug($slug);
$category = $this->loadCategory($model->category); 
$this->render('view', array( 'model' => $model, 'category' => $category->category )); 
}

The first argument for render is view. This is the view file to which will be added .php. This should be the file protected/views/view_name/view.php.

The next interesting thing is the array which comes as second argument. This is how you set the properties or variables that will be sent to the view and will be available there. In our case we will have $model (array) and $category at our disposal in the view file.

Eventually you could create variables in the view and you don't have to necessarily pass them from the controller. However, this will not be in the spirit of MVC.

Caching

Without a doubt caching is a very strong feature in Yii framework. It gives you great control on what and how to cache. For example, you can decide which database query to cache for how long and where the cache should be put. 

Let's go though a simple example in which we will cache our queries in files - CFileCache. This is less effective than using a memcached server for example but it is simpler to set.

First we define how caching in our configuration (protected/config/main.php):
        'cache' => array(
            'class' => 'CFileCache'
        ),
Next we decide to cache our 'heavy' query
$categories = Yii::app()->cache->get('cached_categories_value');

if ($categories === false) {
    $dbCommand = "select cat_name, cat_slug from category where `cat_name` != 'Main'";
    $categories = Yii::app()->db->createCommand($dbCommand)->queryAll();
    Yii::app()->cache->set('cached_categories_value', $main_menu, 1000);
}
What happens above is that if the $categories value is not found in the cache it will be generated and saved in the cache with cache key 'cached_categories_value'. Once cached we can use it in the next 1000 seconds. 

Again, for caching we use CFileCache mechanism which keeps all its cached files at: 

protected/runtime/cache 

Make sure to benchmark extensive to make sure that your caching is not contra-productive. In our case it might be just as fast for the SQL server to execute the query (and to cache it in its memory) than to read the cache from a file.

Access Rules and Access Control

Yii gives powerful options for limiting access per controller methods / actions. Imagine that in an example controller we have actions index, view, create, update, delete (typical CRUD). 

Here is how our access rules should look provided our remote IP is 4.2.2.2 and we want only authorized user 'admin' to access the administrative actions:
    public function accessRules() {
        return array(
            array('allow', // allow all users to perform 'index' and 'view' actions
                'actions' => array('index', 'view'),
                'users' => array('*'),
            ),
            array('allow', // allow admin users the admin actions
                'actions' => array('create', 'update', 'delete'),
                'users' => array('admin'),
                'ips'=>array('127.0.1.1','4.2.2.2'),

            ),
            array('deny', // deny all users
                'users' => array('*'),
            ),
        );
    }
The above shows a good practice to limit the access by IP and not only to rely on authorization. This is very important for your website security.

blog comments powered by Disqus