codeigniter_doctrineBeing inspired by the wonderful series of articles/screencasts on the nettuts website called CodeIgniter From Scratch I decided to write my own series on using CodeIgniter and Doctrine together to build a functional website in a series of tutorials.

In this first part of series, I will show you how to create a basic CodeIgniter install and add Doctrine as a plug-in.

"CodeIgniter and Doctrine from Scratch" Series:

download_code

Why add Doctrine to CodeIgniter?

Before we get started, first let me explain the reason I am doing this. Doctrine is an Object Relational Mapper for PHP. It’s OK if you don’t know this term. It basically means that you can map your database tables to classes in your web application. And instances of these classes (i.e. objects) represent records in the database.

This makes it very easy to create, read, update and delete records from the database, while handling them almost like regular objects, so you don’t even have to write any queries. It will also handle relationships between your tables. There are several other benefits that I will not get into until later in these tutorials. See the Doctrine Introduction, if you would like more info right now.

Here is an illustration I put together, that might give you a visual picture.

CodeIgniter Doctrine

First Step: Setup your development environment

If you already have a web server with PHP and MySQL setup, you can skip some of this.

  • Download and install WAMP (for Mac: MAMP)
    Warning Skype Users: You must shutdown Skype first before you start up WAMP, due to a port conflict. After WAMP starts up, you can open Skype again.
  • Visit http://localhost/ in your browser to make sure it’s working
  • Open the “www” folder under the WAMP installation.
  • Create a folder named “ci_doctrine_day1″. We will put our files here.

Install CodeIgniter

  • Download CodeIgniter
  • Extract and copy the contents into your new “ci_doctrine_day1″ folder.
  • You may delete the “user_guide” folder.

Your new folders should look like this:

ci_doctrine_day1_1

You should see this:

ci_doctrine_day1_3

CodeIgniter Crash Course: Controllers

Controllers are called by CodeIgniter on every page load.
They are located under:

system/application/controllers/

The url structure looks like this:

http://localhost/ci_doctrine_day1/index.php/CONTROLLER_NAME/FUNCTION_NAME

For example if you open this url:

http://localhost/ci_doctrine_day1/index.php/hello/world

CodeIgniter will look for a controller class named “Hello” and call it’s method named “world()”.

So let’s create our first controller.

Our First Controller

  • Create this file: system/application/controllers/hello.php
<?php
// system/application/controllers/hello.php

class Hello extends Controller {

	function world() {
		echo "Hello CodeIgniter!";
	}

}

You should see:

Hello CodeIgniter!

Please Note:

  • The class must extend Controller.
  • The class name must be capitalized.
  • The file name must be lowercase.

Recommended Reading:

Install Doctrine

CodeIgniter allows us to add plug-ins. That’s how we will be installing it.

  • Create this folder: system/application/plugins
  • Create this folder: system/application/plugins/doctrine
  • Download Doctrine
  • Extract the files. Find the folder named “lib” and copy it to system/application/plugins/doctrine.

Now your folders should look like this:

ci_doctrine_day1_5

  • Create the plug-in file: system/application/plugins/doctrine_pi.php
<?php
// system/application/plugins/doctrine_pi.php

// load Doctrine library
require_once APPPATH.'/plugins/doctrine/lib/Doctrine.php';

// load database configuration from CodeIgniter
require_once APPPATH.'/config/database.php';

// this will allow Doctrine to load Model classes automatically
spl_autoload_register(array('Doctrine', 'autoload'));

// we load our database connections into Doctrine_Manager
// this loop allows us to use multiple connections later on
foreach ($db as $connection_name => $db_values) {

	// first we must convert to dsn format
	$dsn = $db[$connection_name]['dbdriver'] .
		'://' . $db[$connection_name]['username'] .
		':' . $db[$connection_name]['password'].
		'@' . $db[$connection_name]['hostname'] .
		'/' . $db[$connection_name]['database'];

	Doctrine_Manager::connection($dsn,$connection_name);
}

// CodeIgniter's Model class needs to be loaded
require_once BASEPATH.'/libraries/Model.php';

// telling Doctrine where our models are located
Doctrine::loadModels(APPPATH.'/models');

// (OPTIONAL) CONFIGURATION BELOW

// this will allow us to use "mutators"
Doctrine_Manager::getInstance()->setAttribute(
	Doctrine::ATTR_AUTO_ACCESSOR_OVERRIDE, true);

// this sets all table columns to notnull and unsigned (for ints) by default
Doctrine_Manager::getInstance()->setAttribute(
	Doctrine::ATTR_DEFAULT_COLUMN_OPTIONS,
	array('notnull' => true, 'unsigned' => true));

// set the default primary key to be named 'id', integer, 4 bytes
Doctrine_Manager::getInstance()->setAttribute(
	Doctrine::ATTR_DEFAULT_IDENTIFIER_OPTIONS,
	array('name' => 'id', 'type' => 'integer', 'length' => 4));

Read the comments in the code for explanations. However, don’t worry if you don’t understand all of it for now.

Database Setup and Configuration

ci_doctrine_day1_6

  • Edit file: system/application/config/database.php
  • Find the lines below and input the values.
// in system/application/config/database.php
// ... 

$db['default']['hostname'] = "localhost";
$db['default']['username'] = "root";
$db['default']['password'] = "";
$db['default']['database'] = "ci_doctrine";

// ...

We just edited the database configuration file of CodeIgniter.

More Configuration

Almost done.

config.php

  • Edit file: system/application/config/config.php
// in system/application/config/config.php
// ...

$config['base_url']	= "http://localhost/ci_doctrine_day1/";

// ...

Now CodeIgniter knows the url of our site.

autoload.php

  • Edit file: system/application/config/autoload.php
// in system/application/config/autoload.php
// ...

$autoload['plugin'] = array('doctrine');

// ...

This makes sure the Doctrine plug-in is always loaded.

Finished!

Now we’re ready to rock. Let’s start testing our setup.

Our First Doctrine Model

Create a user Table

  • Open phpMyAdmin: http://localhost/phpmyadmin/
  • Go to database “ci_doctrine”
  • Create a table named “user” with columns:
    id => int, primary key, auto_increment,
    username => varchar(255), unique,
    password => varchar(255),
    first_name => varchar(255),
    last_name => varchar(255)

You may use this query:

CREATE TABLE `ci_doctrine`.`user` (
`id` INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY ,
`username` VARCHAR( 255 ) NOT NULL ,
`password` VARCHAR( 255 ) NOT NULL ,
`first_name` VARCHAR( 255 ) NOT NULL ,
`last_name` VARCHAR( 255 ) NOT NULL ,
UNIQUE (
`username`
)
)

ci_doctrine_day1_7

Create the Model

  • Create file: system/application/models/user.php
<?php
// system/application/models/user.php
class User extends Doctrine_Record {

	public function setTableDefinition() {
		$this->hasColumn('username', 'string', 255);
		$this->hasColumn('password', 'string', 255);
		$this->hasColumn('first_name', 'string', 255);
		$this->hasColumn('last_name', 'string', 255);
	}

}

Note:

  • We extend Doctrine_Record, instead of Model (which you normally would with CodeIgniter models).
  • Inside the function setTableDefinition() we need to define the table structure.
  • By default, Doctrine will look for a table with same name as the class. In this case: “user”. (this can be changed)
  • In our doctrine_pi.php file above in this tutorial, we specified for a default primary key named “id”. Therefore we don’t need to put it again in our User class.

Testing the Model: Add Some Users

  • Edit our controller we created earlier: system/application/controllers/hello.php
<?php
// system/application/controllers/hello.php

class Hello extends Controller {

	function world() {
		echo "Hello CodeIgniter!";
	}

	function user_test() {

		$u = new User;
		$u->username = 'johndoe';
		$u->password = 'secret';
		$u->first_name = 'John';
		$u->last_name = 'Doe';
		$u->save();

		$u2 = new User;
		$u2->username = 'phprocks';
		$u2->password = 'mypass';
		$u2->first_name = 'Codeigniter';
		$u2->last_name = 'Doctrine';
		$u2->save();

		echo "added 2 users";
	}

}

We just generated 2 objects, and populated them with some data. Simply calling save() should save them into our database.

Note:

  • We are able to access the fields as parameters (e.g. $u->username), even though we did not create these as class parameters. Isn’t Doctrine nice?
  • If you are familiar with CodeIgniter, you might remember that you need to call $this->load->model() function to load models. However since we registered the autoload function of Doctrine, just saying “new User;” is enough.
  • We didn’t create the “save()” function, because it comes from the Doctrine_Record class we extended. It saves the objects to the database. There are many other functions and goodies that come with Doctrine classes, we will see later in the tutorials.

You should see output:

added 2 users

Voila! Now you should be able see the 2 new records that just got created.

ci_doctrine_day1_8

Stay Tuned

We just saw how to install and setup CodeIgniter with Doctrine. It took some work, but now we have a powerful MVC framework and ORM combination.

In the next tutorials, I will show you more practical examples and eventually build a functional website. You will see how easy it is to create models with Doctrine and save time from having to write repetitive CRUD (Create, read, update and delete) functions in all of your models.

Doctrine will also help us handle the relationships between our classes, and let us avoid writing complex logic code and queries.

See you next time!

"CodeIgniter and Doctrine from Scratch" Series: