Yii Framework Database Migrations

The Yii Framework offers what is called Database Migrations.

Database Migrations is a term used whenever there are any database changes that occur. This could be any database changes from table creations, additional fields, dropping fields to adding keys.

Database Migrations are especially helpful whenever people work in a team. Most developers won’t have the time to inform all the other developers or some might not be very attentive to any database changes. Having Database Migrations would be very helpful.

To Start

To start, go to you protected and create a migrations folder if it isn’t already there.

cd /path/to/application/protected
mkdir migrations

Now, you are ready to create migration files:

yiic migrate create migration_name

Migration names aren’t unique like in Ruby On Rails. You would be able to create multiple migrations with the same name.

Create Table Migration

Creating a table in Yii is done using the migrate command. Below is a run through of table creation:

php yiic.php migrate create create_products_table

Yii Migration Tool v1.0 (based on Yii v1.1.15)

Create new migration '/Library/WebServer/Documents/dealsite/protected/migrations/m140810_064319_create_products_table.php'? (yes|no) [no]:yes

To create a table, you will need the following function:

$this->createTable('downloads', array(
    'id' => 'pk',
    'name' => 'varchar NOT NULL'

Running the migration

Running the migration would be done by just one simple command:

php yiic.php migrate

Yii Migration Tool v1.0 (based on Yii v1.1.15)

Creating migration history table "tbl_migration"...done.
Total 1 new migration to be applied:

Apply the above migration? (yes|no) [no]:yes
*** applying m140810_060412_create_products_table
    > create table deals ... done (time: 0.003s)
*** applied m140810_060412_create_products_table (time: 0.036s)

Migrated up successfully.

Aside from creating the table, this will create the tbl_migrations table if there isn’t one. This will also insert any information regarding the migration as records inside it.

Common error

Error: The migration directory does not exist: application.migrations

This commonly occurs whenever we try to use the yiic of the framework folder. Remember the one we used to create the application?

To fix this, we should use the yiic file inside the protected folder:


Successfully running migration commands should output the following:

php yiic.php migrate create create_deals_table

Yii Migration Tool v1.0 (based on Yii v1.1.15)

Create new migration '/Library/WebServer/Documents/webapplication/protected/migrations/m140810_060412_create_products_table.php'? (yes|no) [no]:yes
New migration created successfully.

Things to Remember

  • You need to execute the yiic inside the protected directory to use on unix machines
  • There should be an yiic.bat inside the protected directory if you are on a windows machine
  • The migrations directory inside the protected directory must be available and is writable


 Managing Files with Yii Framework

File Uploading has never been this easy with the Yii Framework.

 What's with a Yii Framework Form Model

There are a lot of times when you build a form that have fields that do not translate into database fields. A simple example is a contact form.

Commonly, you would have the following fields in a contact form:

  • Name
  • Email
  • Subject
  • Message

And most of the time, you don’t need a database table for that. How would you validate a form in a framework that has validations in the model?

The CFormModel is Yii Framework’s answer to this. The CFormModel you can accept user input data and validate for you. But it does not relate to any data in the database.

The CFormModel works just like most things in Yii. You will need just need to extend the CFormModel:

class ContactForm extends CFormModel {

Now we would need properties that will relate to things we would want to validate. In our case we would need, name, email, subject and message.

public $name;
public $email;
public $subject;
public $message;

Now we would need to add our validation rules:

public function rules()
    return array(
        array('name, email, subject, message', 'required'),
        array('email', 'email'),
        array('message, subject', 'length', 'min' => 20)

Now in the controller, you will need to pass the form model to the view for us to use it in the view.

$contact_form_model = new ContactForm;
$this->render('contact_form', array('contact_form_model' => $contact_form_model));

When you accept a POST from the client, you can validate the form via:

if ($_POST)
    $contact_form_model->attributes = $_POST['ContactForm'];
    if ($contact_form_model->validate())
        // do your stuff

It is really important that you instantiate the model before you validate() because if you instantiate it on the render portion, you’d lose any validation done before it including any validation errors from a POST.

Here is a complete controller method with accepting and validating a POST:

$contact_form_model = new ContactForm;
if ($_POST)
    $contact_form_model->attributes = $_POST['ContactForm'];
    if ($contact_form_model->validate())
        // do your stuff
$this->render('contact_form', array('contact_form_model' => $contact_form_model));

The Form Model will of course never be complete without the view. This is a sample of a form using our Form Model.

<?php $form=$this->beginWidget('CActiveForm'); ?>
<p><?php echo $form->labelEx($contact_form_model,'name'); ?></p>
<p><?php echo $form->textField($contact_form_model,'name'); ?></p> 
<p><?php echo $form->labelEx($contact_form_model,'email'); ?></p>
<p><?php echo $form->textField($contact_form_model,'email'); ?></p>
<p><?php echo $form->labelEx($contact_form_model,'subject'); ?></p>
<p><?php echo $form->textField($contact_form_model,'subject'); ?></p> 
<p><?php echo $form->labelEx($contact_form_model,'message'); ?></p>
<p><?php echo $form->textArea($contact_form_model,'message',array('rows'=>0, 'cols'=>50)); ?></p>
<p><?php echo CHtml::submitButton('Submit', array('value' => 'Send A Message', 'id' => 'quote_submit')); ?></p>
<?php $this->endWidget(); ?>

Now, you can have fun with the Yii Framework Form Model.

 Simplifying Databases with the Active Record Class

Active Record is a software design pattern where in a Class typically represents a set of data. Active Record is a pattern that is commonly used by ORM where in relationships are built between Classes.

Advantages of using the Active Record Class

The Active Record class saves time typing and thinking about queries. Instead of typing a long number of lines, you just manipulate your classes.

Reading Records

Reading records from the database has never been easier through the find* methods.


The findAll method returns an array of instances of Model_Post:

$posts = Post::model()->findAll();
foreach ($posts as $post) {
    echo $post->title;
    echo $post->description;

The findBy* methods are a godsend as it again minimizes typing when searching for records.

$post = Post::model()->findByPk(813);
echo $post->title;
// echoes Yii is Awesome!

$post = Post::model()->findByTitle('Yii is Awesome');
echo $post->id;
// echoes 813;

The CDbCriteria is commonly used to fine grain queries using the find* methods:

$criteria = new CDbCriteria;
$criteria->condition = 'status = :published';
$criteria->params = array(':published' => 'published');

$posts = Post:model()->findAll($criteria);

Saving Records

$post = new Post;
$post->title = "Working with the Active Record Class";
$post->description = "This is a long long long string about the Active Record Class";

Deleting Records

The Active Record class won’t be complete without without a way to delete records.

$post = Post::model()->findByPk(813);

As with the find* methods, the deleteAll can also accepted CDbCriteria instances, although as of version, 1.1.14, the delete method cannot:

$criteria = new CDbCriteria;
$criteria->condition = 'status = :published';
$criteria->params = array(':published' => 'published');


 Yii Framework Controllers

Yii Framework Controllers are classes that accepts requests from the user and responses with the aid of views, models and widgets.

Yii Controllers can usually be found in the URLs of requests:


In the above example, Yii would attempt to find a controller named postsController.php and load it.

Let’s Try an Example

Let’s try to create a Controller so that we can see how it works. Using your favorite text editor, create a file named TestingController.php and put the following code in it:

class TestingController extends Controller
    public function actionIndex()
        echo 'Hello World!';

Then save the file to protected/controllers/ folder.

Now, using a browser, navigate to a URL similar to this:


If you did it right, you would see Hello World!


In the above example, TestingController had a method named, actionIndex. The index function was loaded by default whenever you access a URL and the second segment is empty. Another way to navigate to the actionIndex is like this:


Let’s try adding a second method to our TestingController:

class TestingController extends Controller
    public function actionIndex()
        echo 'Hello World!';
    public function actionUniverse()
        echo 'Hello Universe!';

Now load the following URL to see, Hello Universe!