CodeIgniter Hacks

6 CodeIgniter Hacks for the Masters

CodeIgniter is a simple and powerful open source web application framework for PHP. Today, we’ll do some core “hacks” to this framework to change and improve its functionality. In the process, you’ll gain a better understanding of the intricacies of CodeIgniter.

Disclaimer

  1. It is not recommended to apply these hacks to an existing project. Since they change some of CodeIgniter’s core functionality, it can break the existing code.
  2. As of this writing, CodeIgniter 1.7.2 is the latest stable release. These hacks are not guaranteed to work for future (or past) releases.
  3. Even though CodeIgniter is designed to be PHP 4 compatible, some of these hacks are not. So you will need a server with PHP 5 installed.
  4. When you make any changes to the files inside the system folder, you should document it somewhere for future reference. Next time you upgrade CodeIgniter (even though they do not release updates very often), you may need to reapply those changes.

1. Autoloading Models PHP 5 Style

The Goal

On the left side, you see the regular way of loading a model in CodeIgniter, from within a Controller. After this hack, we will be able to create objects directly. The code is cleaner, and your IDE will be able to recognize the object types. This enables IDE features such as auto-complete, or previewing documentation.

There are two more side effects of this hack. First, you are no longer required to extend the Model class:

And you no longer have to add a require_once call before you do model class inheritance.

The Hack

All we need to do is add a PHP 5 style autoloader function.

Add this code to the bottom of system/application/config/config.php:

<?php
// ...

function __autoload($class) {
	if (file_exists(APPPATH."models/".strtolower($class).EXT)) {
		include_once(APPPATH."models/".strtolower($class).EXT);
	}
}
?>

If you are interested in applying this hack for controllers too, you can use this code instead:

<?php
// ...

function __autoload($class) {
	if (file_exists(APPPATH."models/".strtolower($class).EXT)) {
		include_once(APPPATH."models/".strtolower($class).EXT);
	} else if (file_exists(APPPATH."controllers/".strtolower($class).EXT)) {
		include_once(APPPATH."controllers/".strtolower($class).EXT);
	}
}
?>

Any time you try to use a class that is not defined, this __autoload function is called first. It takes care of loading the class file.

2. Prevent Model-Controller Name Collision

The Goal

Normally, you can not have the same class name for a Model and a Controller. Let’s say you created a model name Post:

class Post extends Model {

	// ...

}

Now you can not have a URL like this:


http://www.mysite.com/post/display/13

The reason is because that would require you to also have a Controller class named ‘Post.’ Creating such a class would result in a fatal PHP error.

But with this hack, it will become possible. And the Controller for that URL will look like this:

// application/controllers/post.php

class Post_controller extends Controller {

	// ...

}

Note the ‘_controller’ suffix.

The Hack

To get around this issue, normally most people add the ‘_model’ suffix to the Model class names (eg. Post_model). Model objects are created and referenced all over the application, so it might seem a bit silly to have all of these names with ‘_model’ floating around. I think it is better to add a suffix to the Controllers instead, since they are almost never referenced by their class names in your code.

First we need to extend the Router class. Create this file: “application/libraries/MY_Router.php”

class MY_Router extends CI_Router {
	var $suffix = '_controller';

	function MY_Router() {
		parent::CI_Router();
	}

	function set_class($class) {
		$this->class = $class . $this->suffix;
	}

	function controller_name() {

		if (strstr($this->class, $this->suffix)) {
			return str_replace($this->suffix, '', $this->class);
		}
		else {
			return $this->class;
		}

	}
}

Now edit “system/codeigniter/CodeIgniter.php” line 153:

if ( ! file_exists(APPPATH.'controllers/'.$RTR->fetch_directory().$RTR->controller_name().EXT))

Same file, line 158:

include(APPPATH.'controllers/'.$RTR->fetch_directory().$RTR->controller_name().EXT);

Next, edit: “system/libraries/Profiler.php”, line 323:

$output .= "
".$this->CI->router->controller_name()."/".$this->CI->router->fetch_method()."
";

That is all. Keep in mind that with this hack you are required to put the ‘_controller’ suffix on all of your controller class names. But not in the file names or the URL’s.

3. Form Validation for Unique Values

The Goal

CodeIgniter has a nice Form_validation class. It comes with several validation rules:

These are useful, but there is an important one missing from this list: to check for unique values. For example, most user registration forms need to check that the username is not already taken, or the e-mail address is not already in the system.

With this hack, you will be able add this validation rule to your form submission handler very easily:

$this->form_validation->set_rules('username', 'Username',
		'required|alpha_numeric|min_length[6]|unique[User.username]');

Note the last part that says “unique[User.username].” This new validation rule is just called “unique,” and takes a parameter inside the square brackets, which is “tablename.fieldname”. So it will check the “username” column of the “User” table to make sure the submitted value does not already exist.

Similarly, you can check for duplicate e-mails:

$this->form_validation->set_rules('email', 'E-mail',
		'required|valid_email|unique[User.email]');

And your application can respond with proper error messages:

The Hack

This might be considered more of an extension than a hack. Nevertheless, we are going to take a core CodeIgniter library and improve it.

Create: “application/libraries/MY_Form_validation.php”

class MY_Form_validation extends CI_Form_validation {

	function unique($value, $params) {

		$CI =& get_instance();
		$CI->load->database();

		$CI->form_validation->set_message('unique',
			'The %s is already being used.');

		list($table, $field) = explode(".", $params, 2);

		$query = $CI->db->select($field)->from($table)
			->where($field, $value)->limit(1)->get();

		if ($query->row()) {
			return false;
		} else {
			return true;
		}

	}
}

Now you can use the unique validation rule.

4. Running CodeIgniter from the Command Line

The Goal

Just like the title says, our goal is to be able to run CodeIgniter applications from the command line. This is necessary for building cron jobs, or running more intensive operations so you don’t have the resource limitations of a web script, such as maximum execution time.

This is what it looks like on my local Windows machine:

The above code would be like calling this URL:


http://www.mysite.com/hello/world/foo

The Hack

Create a “cli.php” file at the root of your CodeIgniter folder:

if (isset($_SERVER['REMOTE_ADDR'])) {
	die('Command Line Only!');
}

set_time_limit(0);

$_SERVER['PATH_INFO'] = $_SERVER['REQUEST_URI'] = $argv[1];

require dirname(__FILE__) . '/index.php';

If you are on a Linux environment and want to make this script self executable, you can add this as the first line in cli.php:

#!/usr/bin/php

If you want a specific controller to be command line only, you can block web calls at the controller constructor:

class Hello extends Controller {

	function __construct() {
		if (isset($_SERVER['REMOTE_ADDR'])) {
			die('Command Line Only!');
		}
		parent::Controller();
	}

	// ...

}

5. Adding Doctrine ORM to CodeIgniter

The Goal

Doctrine is a popular Object Relational Mapper for PHP. By adding it to CodeIgniter, you can have a very powerful Model layer in your framework.

The Hack

Just installing Doctrine is not very “hacky” per se, as we can just add it as a plug-in. However, once added, your Model classes will need to extend the Doctrine base classes, instead of the CodeIgniter Model class. This will completely change the way the Model layer works in the framework. The objects you create will have database persistence and also will able to have database relationships with other objects.

Follow these steps:

  1. Create folder: application/plugins
  2. Create folder: application/plugins/doctrine
  3. Download Doctrine (1.2 as of this article)
  4. Copy the “lib” folder from Doctrine to: “application/plugins/doctrine”
  5. Create “application/plugins/doctrine_pi.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');

Next, edit “application/config/autoload.php” to autoload this Doctrine plugin

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

Also make sure you have your database configuration in “application/config/database.php”.

That is all. Now you can create Doctrine Models within your CodeIgniter application. Read my tutorials on this subject for more information.

6. Running Multiple Sites

The Goal

This hack will make it possible for you to run multiple sites from a single install of CodeIgniter. Each website will have its own application folder, but they will all share the same system folder.

The Hack

Install CodeIgniter anywhere on the server. It doesn’t need to be under a website folder. Then take the application folder out of the system folder. And make additional copies of it, as seen in the image above, for every website you want to run. You can place those application folders anywhere, like under each separate website folders.

Now copy the index.php file to the root of each website folder, and edit it as follows:

At line 26, put the full path to the system folder:

	$system_folder = dirname(__FILE__) . '../codeigniter/system';

At line 43, put the full path to the application folder:

	$application_folder = dirname(__FILE__) . '../application_site1';

Now you can have independent websites using separate application folders, but sharing the same system folder.

There is a similar implementation in the CodeIgniter User Guide you can read also.

7. Allowing All File Types for Uploads

The Goal

When using the Upload library in CodeIgniter, you must specify which file types are allowed.

$this->load->library('upload');

$this->upload->set_allowed_types('jpg|jpeg|gif|png|zip');

If you do not specify any file types, you will receive an error message from CodeIgniter: “You have not specified any allowed file types.”

So, by default, there is no way to allow all file types to be uploaded. We need to do small hack to get around this limitation. After that we will be able to allow all file types by setting it to ‘*’.

$this->load->library('upload');

$this->upload->set_allowed_types('*');

The Hack

For this hack we are going to modify the Upload class behavior.

Create file: application/libraries/My_Upload.php

class MY_Upload extends CI_Upload {

	function is_allowed_filetype() {

		if (count($this->allowed_types) == 0 OR ! is_array($this->allowed_types))
		{
			$this->set_error('upload_no_file_types');
			return FALSE;
		}

		if (in_array("*", $this->allowed_types))
		{
			return TRUE;
		}

		$image_types = array('gif', 'jpg', 'jpeg', 'png', 'jpe');

		foreach ($this->allowed_types as $val)
		{
			$mime = $this->mimes_types(strtolower($val));

			// Images get some additional checks
			if (in_array($val, $image_types))
			{
				if (getimagesize($this->file_temp) === FALSE)
				{
					return FALSE;
				}
			}

			if (is_array($mime))
			{
				if (in_array($this->file_type, $mime, TRUE))
				{
					return TRUE;
				}
			}
			else
			{
				if ($mime == $this->file_type)
				{
					return TRUE;
				}
			}
		}

		return FALSE;

	}

}

Conclusion

I hope some of these are useful to you. If not, they are still interesting to know and can help you learn more about the internal workings of a framework and some of the core PHP language features.

If you know any other cool hacks or modifications, let us know in the comments. Thank you!

Ready to take your skills to the next level, and start profiting from your scripts and components? Check out our sister marketplace, CodeCanyon.

CodeCanyon

Note: Want to add some source code? Type <pre><code> before it and </code></pre> after it. Find out more
  • Max

    thx for the tut! Will read it now!

  • http://www.pedrasmachado.com Ricardo Machado

    Nice tips :)

    Specially the doctrine tip… Pretty neat.

    Congratz ;)

  • Paul du Long

    I assume there aren’t coming any more CodeIgniter from scratch tutorials?

    • http://nathanledet.com Nathan Ledet

      Well, Jeff said he was working on a finale – but it has been a few months since anything new has come out. I sure do miss that series :(

      • m4tthie

        Yeah me too! Jeff would show how to make a CMS right? We had CRUD and login… but it isn’t complete yet.

        I’m looking forward to a finale! :)

      • Khalil

        Yes we want to watch more CI series from scratch please complete series.

      • http://nicolahibbert.com Nikki

        Looking forward to the next (last?) CI tut :)

    • Walter

      I check everyday looking for Codeigniter CMS tutorial. I’d say any CI tutorial is very welcome.

  • Sid

    Nice tips. I could use a couple of them right away.

  • http://www.dailygrind.it Sergio

    CI from command line sounds interesting…

  • http://realizetheweb.com Michael

    Just started learning CodeIgniter, these will be helpful thanks.

    Michael
    http://www.realizetheweb.com

  • 130db

    You all should definetely try out Kohana. It’s pure PHP5. I was useing Codeigniter for a long time, but since Kohana there’s no way back for me.

    • http://www.pcbsd.pl piker

      Kohana still has too much changes in core. I will stay with CodeIgniter

      • http://www.memoclic.com nico

        >> Kohana still has too much changes in core. I will stay with CodeIgniter
        same for me. will stick to CI :)

  • NssY

    I can’t believe how much i was missing out without an orm. Doctrine is super.

    Thanks man.

  • ShadowAssassin

    7 Hacks for the masters ;)

  • http://latavish.imeem.com/ Latavish

    Hi Burak,

    Thank for this great tutorial as I am a vivd CI user. I really like the idea you gave for “3. Form Validation for Unique Values”. This is a nice little trick. Usually I take advantage of CI’s call back feature and setup a private function to take care of this. But the more tips and tricks the better!

    Again thanks and always looking forward to your tutorials.

  • http://fwebde.com/ Eric B.

    Cool tips.

    For number 4, on a Linux system, would you have to also chmod the file to make it executable?

  • http://www.urbanvideos.tv alan

    nice , but I’m in to CakePhP. I hope you guys post some CakePhP tuts on nettuts+ in the future!

    • http://imjp.net/ JP

      I was JUST about to write the same thing lol.

      Why are there so many Code Igniter tutorials and only 2 VERY basic CakePHP ones?

      I’d gladly renew my tutsplus account if you guys make some decent CakePHP tutorials (please no screencasts!).

      Hope you guys take my suggestions into consideration. :)

      • http://www.paulchater.co.uk Paul Chater

        Because CodeIgniter rocks! :)

      • http://www.pjerky.com Pjerky

        Because unlike CakePHP, CodeIgniter isn’t frustrating to use and doesn’t get in your way. Also CodeIgniter’s user documentation makes it much easier for others to jump in and learn it and it comes with great tutorials already. So it is pretty simple to write an article about CI and extending it.

        I worked with CakePHP for 8 months and I will never do that again. Not only does it fight you every step of the way, but it is slow, the documentation is piss-poor, and the developers behind it are arrogant and snide. Not a group I want to be involved with.

        I will give CakePHP this, they have some neat features such as the command line interface for auto-generating files. Its a bit of genius work, but it is too heavy handed in how it controls what you do and the people behind it are not people I want to deal with.

        Thats my take on it.

        -Pjerky

  • Kelly T

    Why not use Kohana instead? It’s a CI style framework that comes with all that stuff out of the box? It just seems crazy to hack the core of the framework, only to be locked down when a new version of the framework comes out.

    Just thought I’d put that out there…

    Other than that, nice tutorial.

    • http://nathanledet.com Nathan Ledet

      Documentation… Eek.

  • http://www.designil.com/ DesigNIL

    The title actually has to be ’7 Hacks’.

    Well, the article is good though. Really like the one about using Codeigniter from command line. :)

  • http://taimurian.com Taimur

    I’m still reading the previous nettuts CI tutorials … I’m sure I’m gonna use these hacks in the near future. Thanks and Please post more CI tuts.

  • http://livelyworks.net Lively Works

    Very useful.

  • Dayton

    #1 – Aoutoload in the config makes this unnecessary
    #2 – Routes allow you to do this with 0 hacking
    #3 – Custom validation function makes this unnecessary

    Some of the other tips were handy but you really should exhaust CI’s built in extendability. That way, you can upgrade without worrying about custom core changes. Some of these “hacks” seem to defeat the built-in architecture of CI. I would spend more time learning the framework and working with it, not against it.

    • cahva

      Ehm.. Did you read the #1 at all? :) No, its not the same. If you autoload in the config, you wont see your IDE magically giving you autocompletion to your models or extra definitions in them. I personally use datamapper so I already have the autocompletion as it has the autoloading, but for regular CI models I definately see the benefits of using this autoloader.

      • Shiro

        what I did is create an object from the model, then my IDE will magically give me the autocompletion :)

    • Bretticus

      Yeah, when I read #1 I could see how it completely destroys CI’s notion of extension (bypassing load). If you ever want to upgrade the core, you’re in for a pain in the backside where you could have just used framework override means to do the same thing (I suppose I should read the rest of this tut now ;) )

      • Bretticus

        Ah yes, I read the rest of #1. Just a way to take advantage of PHP 5 auto-loader. I suppose if you wrote your auto-loader to look for MY_ customizations than my comment above is nullified (although it already written for you in the framework.)

        As for autocomplete…
        If you use netbeans, no problem thanks to Rakibul Hasan http://rhasan.com/blog/2009/09/codeigniter-auto-complete-with-netbeans/

    • http://www.phpandstuff.com Burak
      Author

      #1 – You would have to put all of your models in the autoload.php and keep updating it when you add models. And they would be loaded every time, which would be a waste of memory.

      #2 – I have already tried routes. You would either keep adding a new route for every single controller you have, or you would need to use regular expressions, which doesn’t work well for nested folders under the controller folder. Also you would have to name all of your controller files “*_controller.php” which can look ugly.

      #3 – Instead of creating a custom validation function inside the controller, I prefer extending the library class so the solution is reusable.

  • Mannyatico

    Very useful, but I have a question; I’m running a server on Debian, and I make a connection to a MSSQL server, and my app in raw php is working fine….

    When I try to use CI with that connection (using freetds and unixodbc BTW), it didn’t work, somebady has idea why :P

    PS. i know, this is not a forum, but i dont find much information…

  • Miami-software

    Hi Burak,

    Great tips and well-written, thanks. I know there are multiple htaccess files that people suggest on the Codeigniter forums and wiki but can you post a sample (or link) for your tip #6?

  • http://smashingwebs.com/ SmashingWebs.com

    It’s pretty cool.. informative.
    b/w I just forgot to tell something !!!

    We are proud to present our FIRST wordpress psd theme in front of you, Smashing Revolution Theme. We are now at the end of 2009 and at the begining of 2010. Let’s celebrate it with the New WordPress theme. SmashingWebs introduces our first WordPress PSD theme, Smashing Revolution.This is a General Theme that can be used for any type of blogs.

    http://smashingwebs.com/

  • http://blog.creative-webdesign.info Andi

    I love Codeigniter tuts!

    • Carlos Caniguante

      Me too!!

  • John Denis

    I would like to use #1 (specially for the auto-complete feature in the IDE and the simplicity), but is not working for me. I keep getting errors when running the page.

    I added the required code to the end of application/config/config.php

    function __autoload($class) {
    if (file_exists(APPPATH.”models/”.strtolower($class).EXT)) {
    include_once(APPPATH.”models/”.strtolower($class).EXT);
    } else if (file_exists(APPPATH.”controllers/”.strtolower($class).EXT)) {
    include_once(APPPATH.”controllers/”.strtolower($class).EXT);
    }
    }

    Then created a test controller: application/controllers/test.php

    getTest();
    print_r($db_array);
    }
    }
    ?>

    I then created a test model: application/models/test_model.php

    db->query(‘select * from table where PostStatus = 1′);

    if($query->num_rows() > 0) {

    foreach ($query->result() as $row) {
    $data[] = $row;
    }
    }
    return $data;
    }

    }
    ?>

    When I run the URL: mysite.com/test/
    I get this message:

    Fatal error: Class ‘Model’ not found in /path/to/web/application/models/test_model.php on line 2

    Tried removing the “extends Model” from the test_model.php to be like this:
    class Test_model {

    Then ran it again and got this error:

    A PHP Error was encountered
    Severity: Notice
    Message: Undefined property: Test_model::$db
    Filename: models/test_model.php
    Line Number: 5

    Fatal error: Call to a member function query() on a non-object in /path/to/web/application/models/test_model.php on line 5

    However, If I call the model the original way in the controller, it works fine.

    $this->load->model(‘test_model’);
    $db_array = $this->test_model->getTest();

    Any ideas of what I’m doing wrong?

    • http://www.ellenaymedia.co.uk/ Andrew Cairns

      John, what i think is happening here is when you are extending the base model, it is not being found within your own models folder – which makes sence, since it shouldn’t be there. Then, once you remove the extension, the base model’s methods are not being found – which makes sence – because you are not extending the base model.

      … that doesnt help does it… :)

  • John Denis

    I’m posting this again, it seems the code I pasted it wrong.

    I would like to use #1 (specially for the auto-complete feature in the IDE and the simplicity), but is not working for me. I keep getting errors when running the page.

    I added the required code to the end of application/config/config.php

    function __autoload($class) {
    if (file_exists(APPPATH.”models/”.strtolower($class).EXT)) {
    include_once(APPPATH.”models/”.strtolower($class).EXT);
    } else if (file_exists(APPPATH.”controllers/”.strtolower($class).EXT)) {
    include_once(APPPATH.”controllers/”.strtolower($class).EXT);
    }
    }

    Then created a test controller: application/controllers/test.php

    Class Test extends Controller {

    function index() {
    $test_model = New Test_model;
    $db_array = $test_model->getTest();
    print_r($db_array);
    }
    }

    I then created a test model: application/models/test_model.php

    class Test_model extends Model {

    function getTest() {
    $query = $this->db->query(‘select * from table where PostStatus = 1′);

    if($query->num_rows() > 0) {

    foreach ($query->result() as $row) {
    $data[] = $row;
    }
    }
    return $data;
    }

    }

    When I run the URL: mysite.com/test/
    I get this message:

    Fatal error: Class ‘Model’ not found in /path/to/web/application/models/test_model.php on line 2

    Tried removing the “extends Model” from the test_model.php to be like this:
    class Test_model {

    Then ran it again and got this error:

    A PHP Error was encountered
    Severity: Notice
    Message: Undefined property: Test_model::$db
    Filename: models/test_model.php
    Line Number: 5

    Fatal error: Call to a member function query() on a non-object in /path/to/web/application/models/test_model.php on line 5

    However, If I call the model the original way in the controller, it works fine.

    $this->load->model(‘test_model’);
    $db_array = $this->test_model->getTest();

    Any ideas of what I’m doing wrong?

  • http://www.demogar.com demogar

    mmm. Really? for Masters?

    1,2,4,6: Basic stuff
    3: Really nice.
    7: Mmmm not a good idea.

    Anyways, it’s cool.

    • sloami

      spot on. just what i thought.

      By the way #4 is also a bad idea. Why would you use CI to run a cron job without the time limit.

      CI has a lot of overhead which you don’t get to see if it’s run as a web page. Try running it as a cron job that’s meant to last an hour and you’ll see massive memory usage and cpu cycles.

      My advice for a php cron job is to use vanilla php(without the bells & whistles). PHP in itself wasn’t meant to be kept running for more than 60 secs. Why test it’s limit by using CI for it?

  • Tim

    Nice Tut…would be nice to see Kohana being covered in equal depth to codeigniter on this site though.

  • bhasunjaya

    I think the word “master” on the title a little bit over use.. :)

  • http://steinerd.com Anthony Steiner

    …mmm I’m liking what is provided, however as someone else stated in the comments, a lot of the “hacks” are necessary if you know CI’s fully.

    The model loading 2nd parameter completely renders 1 & 2 useless. Simply get yourself in the swing of naming your models something like _modelname or even modelname_model, something that distinguishes the difference between the class controller and model, even if just an underscore before the name.

    Then when calling the model in the constructor function of the controller class you need it in,
    $this->load->model(‘_modelname’, ‘spiffy’);

    Will allow you to use $this->spiffy(); as the default initialized variable for the rest of the class (if called in the constructor).

    You can also make use of __CLASS__ which is of course being our magical php constant that fetches the current class we’re noodling in.

    Also, a good thing to know, using this method, you CAN have the second parameter be the name exact name as the class you’re working in without getting name-conflicts.

    You can argue up-and-down about connectivity to an IDE using the first method properly, however 90% of IDE’s use a “project include” source that you can load the entire CodeIgniter script-base and your own application data into, and have the IDE easily continue its intellisense. If you’re IDE doesn’t provide such connectivity, than just ignore everything I just wrote, it is ingenious no doubt… and works identically the same (if not for some cases better) than my proposal here.

    …As for the rest of the “hack”, I’m simply in-love, lol.

    Great Work! Seriously.

  • http://www.kacperos.pl kacperos

    very good tutorial
    Thanks

  • Natrium

    nice, specially the upload hack

  • Ümit Ünal

    Hi Burak.
    Nice tutorial.Expect the new CI tutorials :)

  • http://philsturgeon.co.uk/ Phil Sturgeon

    Loading models in the way mentioned in 1. loses most of the benefits of using models in the first place.

    1. The model when loaded will not be added to the CodeIgniter super-global unless you do $this->post = new Post; which will kill the shorter syntax.

    2. The model will need to be loaded in each model, library or method it is used.

    3. By not inheriting from Model you will have no access to loaded libraries without using $ci =& get_instance() which will make your models look ugly as sin.

    As for the CodeIgniter on the command line hack, it really is a dodgy hack. From the looks of it you will only get the first argument passed to it, why not pass them all? I wrote a page in the wiki ages ago how to get CodeIgniter running on the command line nicely, and released a library to get common CLI input, output, wait, beep etc working.

    http://codeigniter.com/wiki/CI_on_the_command_line/

    The article is very written well but functionally some of these ideas are misleading or badly thought through.

    • http://philsturgeon.co.uk/ Phil Sturgeon

      I noticed the one argument you pass to the command line is “controller/method/param”. Why not use the $_SERVER['argv'] variable to pass in each argument instead of concatenating into a single string?

      Also you should have covered adding the PHP installation path to your index.php file so they can be run without writing the full install path to each command.

      Eg:

      #!/usr/bin/php

      • http://www.steelesoftconsulting.com/ John Steele

        Here’s mine (that seems to work just fine):

        #!/usr/local/bin/php

  • David

    On #5 I would go an whole other way.

    Add the doctrine directory to libraries.
    Add a models directory as a doctrine directory child.
    Create a CI_Doctrine class to bootstrap Doctrine.
    Create a config/doctrine.php file for the database connections.
    And add the CI_Doctrine to the autoload.php libraries.

    The only hack then is to load the models from the doctrine/models directory.

  • http://www.flickr.com/photos/pachito86/ Pachito Marco Calabrese

    nice article … but it’s not exactly for masters … and some of them are not hacks (fortunally) we should take advantage from the framework and extend not hack!

  • http://sonergonul.com Soner Gönül

    Wow !

    Thank you !

    That’s great !

  • Josh

    awesome stuff!

  • http://www.michaelwales.info/ Michael Wales

    Well written article but I have to agree with the others – this is hardly “Masters” level work. Quite a few of these hacks are bastardizing the intent of the framework, making it work in the way you want it to rather than working in the way it prefers.

    Many of these are easily obtainable without hacking the core, the rest are flat-out dangerous.

    #3 is the only tip on this list worthy of being in a CodeIgniter application, the rest is irresponsible.

    • http://steinerd.com Anthony Steiner

      Completely Agreed!

      … and those who don’t know, Michael here is the CI community liaison… meaning he knows what he’s talking about, he works for the company who makes the framework.

      • http://codesanity.net trs21219

        Actually he is not the community chieftain anymore that has been passed on to Jamie Rumbelow, and they are volunteers not paid members of Ellislab. That however is just to get the facts straight, Michael is a great developer who does know what he is talking about. Any advice he gives is pretty solid.

    • http://mitchmckenna.com Mitchell McKenna

      Glad to see Michael’s comment here – I totally agree. I would not be impressed if I came across a co-workers code who decided to start using hack #1 when everyone else on the team is coding the project is following CodeIgniter’s standards.

  • http://www.evanbot.com Evan Byrne

    Doesn’t “hacking” CI defeat the purpose of using a framework in the first place?

  • http://adamgriffiths.co.uk/ Adam Griffiths

    It’s nice to see another CodeIgniter tutorial on Net.tuts+ as it’s nice to get more exposure for the framework, because it really is brilliant.

    However what this article does is mostly unnecessary cack.

    #1 – The only ‘benefit’ to using PHP5 autoloading is you get to say “Hey, I’m using PHP5 autoloading. Go team!” The best way to autoload models etc is to use the application/config/autoload.php file – as this is the way you’re supposed to autoload files into CodeIgniter.

    #2 – If you have a strong rule for naming conventions then you really don’t need to use this. Ever. You can even use routes to do this without any “hacking” of the core libraries.

    #3 – This can be done with a callback. Once again no “hacking” needed.

    #4 – There are much better ways to do this, as Phil Sturgeon pointed out.

    #5 – Why are you putting the doctrine files inside of application/plugins/? This is NOT a CodeIgniter plugin. This should be placed inside application/libraries/ and only the doctrine_pi.php file should be put into the plugins folder. Please, it seems like you need to read the user guide (http://www.codeigniter.com/user_guide/) – I might be a little pedantic about this but the whole point to having different directories for different files is to keep organised. You wouldn’t put a model inside a the controllers folder, would you?

    #6 – I have no idea why you did #6 this way. The user guide sets out a perfectly fine and workable solution to running multiple sites. Simply dump the system folder of your sites and used a shared folder in a non web-accessible folder. It’s the easiest way to do it.

    #7 – This isn’t a very good idea from a security standpoint, is it? The whole point to specifying which file types should be allowed is to stay as secure as possible.

    Overall this tutorial is rather useless. Especially when CodeIgniter can do half of the things laid out natively, without hacking the core to the point of disbelief.

    I think the future CodeIgniter tutorials should be done by more experienced CodeIgniter’s – or at least should follow the conventions CodeIgniter has in place instead of creating unnecessary and down-right ugly hacks.

  • http://jfoucher.fr Jonathan Foucher

    From my experience, hacking the core of a framework or of a CMS only brings rage and tears later on (e.g. upgrading) as you try and remember all the hacks in the old version to put them in the new one…

    #6, running multiple sites on one ‘system’ folder is very useful and I implement it, but it can hardly be called a hack, as this functionality is built into codeigniter… Any way, I first saw it on Ignite Your Code, and maybe so did you…

  • http://seangates.com Sean Gates

    #6 — You don’t need to do this “hack”. You can already move the application folders anywhere you want. This is NOT a good hack. Just look at the configuration your index.php file which runs somewhere in a web accessible path.

    I’ve moved my applications out of the system folder without doing this hack, BTW, and even renamed them. Here are their docs about it, “Relocating Your Application Folder”: http://codeigniter.com/user_guide/general/managing_apps.html

    You just need to know some basic pathing principles.

  • http://dianerianto.com Dian Erianto

    Thank you for the nice tutorial. :)

  • Usama Ahmed

    Cakephp has a built-in ORM. Infact, models inside cakephp are all ORM.

  • http://superdit.com aditia

    Nice article, but i’m wating for ACL best practice or maybe just some light in codeigniter

  • vcool

    Nice tutorial, looks like Ruby on Rails conventions …
    But im considering about the CI conventions .. it would break the CI conventions.
    The problem would occurs when you work with others CI developer

  • Scott

    Unique field validation is a great addition. I wrote an extension to do the same a while back. http://www.scottnelle.com/44/updating-unique-field-validation-for-ci-170/

    It’s consistently one of my most highly-trafficked pages, but I suspect that will change now. :-)

  • http://jmagnone.com Julian

    Hey, nice tutorial. Thanks.

    Just curious. Do you have a hack for doing the following?

    I want to use URLs like domain.com/1FhaSKiq where 1FhaSKiq is a key and point it to a particular controller/method. But, also I want to keep accessing my original controllers.

    In other words, I’d be interesting in having a “default” controller for those URL that do not match an existing controller. Any idea?

    • Cheese

      Julian,

      Is this for URL shortening or some kind of profile URL?

      To make things simple, I’d prefer domain.com/url/1FhaSKiq or any word (change “url”) that suits/match your needs and purpose.

  • Sulik

    in the uploading of all types, if you had trouble uploading in codeignigter. You can skip codegnigter and create your own in hardcode PHP… in thay way you have total control of validations of the uploading functionalities.

  • http://ebayappreview.com Mike

    You have a typo in hack 2

    $output .= “”.$this->CI->router->controller_name().”/”.$this->CI->router->fetch_method().”";

    Should be wrapped in ”

  • Rahi

    Thanks for sharing nice tuts.

    I am using hack #1 but I couldn’t get auto complete working in member functions of the class but it does in __construct.

    class Duration extends Controller{
    protected $durationObj;

    public function __construct($teamUserID=31){

    parent::__construct();

    $this->durationsObj = new Durations_Model();
    $this->durationObj->function_name();
    }
    public function check_auto(){
    $this->durationObj->function_name();
    }
    }

    $this->durationObj will show auto complete options in constructor but NOT in check_auto() function. It shows “no suggestions”.

    PS: I am using netbeans 6.2 M2

  • Eliseu Monar

    Thanks for the ‘unique’ validation solution! Great tuts for Code Igniter!