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

Add Comment

Discussion 97 Comments

Comment Page 1 of 21 2
  1. Max says:

    thx for the tut! Will read it now!

  2. Nice tips :)

    Specially the doctrine tip… Pretty neat.

    Congratz ;)

  3. Paul du Long says:

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

  4. Sid says:

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

  5. Sergio says:

    CI from command line sounds interesting…

  6. Michael says:

    Just started learning CodeIgniter, these will be helpful thanks.

    Michael
    http://www.realizetheweb.com

  7. 130db says:

    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.

  8. NssY says:

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

    Thanks man.

  9. ShadowAssassin says:

    7 Hacks for the masters ;)

  10. Latavish says:

    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.

  11. Eric B. says:

    Cool tips.

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

  12. alan says:

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

    • JP says:

      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. :)

      • Paul Chater says:

        Because CodeIgniter rocks! :)

      • Pjerky says:

        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

  13. Kelly T says:

    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.

  14. DesigNIL says:

    The title actually has to be ’7 Hacks’.

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

  15. Taimur says:

    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.

  16. Dayton says:

    #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 says:

      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 says:

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

    • Bretticus says:

      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 ;) )

    • Burak says:
      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.

  17. Mannyatico says:

    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…

  18. Miami-software says:

    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?

  19. 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/

  20. Andi says:

    I love Codeigniter tuts!

  21. John Denis says:

    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?

    • 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… :)

  22. John Denis says:

    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?

  23. demogar says:

    mmm. Really? for Masters?

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

    Anyways, it’s cool.

    • sloami says:

      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?

  24. Tim says:

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

  25. bhasunjaya says:

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

  26. …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.

  27. kacperos says:

    very good tutorial
    Thanks

  28. Natrium says:

    nice, specially the upload hack

  29. Ümit Ünal says:

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

  30. 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.

    • 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

  31. David says:

    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.

  32. 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!

  33. Wow !

    Thank you !

    That’s great !

  34. Josh says:

    awesome stuff!

  35. 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.

    • 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.

      • trs21219 says:

        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.

    • 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.

  36. Evan Byrne says:

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

  37. 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.

  38. 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…

  39. Sean Gates says:

    #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.

  40. Dian Erianto says:

    Thank you for the nice tutorial. :)

  41. Usama Ahmed says:

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

  42. aditia says:

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

  43. vcool says:

    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

  44. Scott says:

    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. :-)

  45. Julian says:

    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 says:

      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.

  46. Sulik says:

    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.

  47. Mike says:

    You have a typo in hack 2

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

    Should be wrapped in ”

  48. Rahi says:

    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

  49. Eliseu Monar says:

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

Comment Page 1 of 21 2

Add a Comment

To add a code snippet to your comment, please wrap your code like so: <pre name="code" class="html">YOUR CODE</pre>. You can replace the class name with "js," "css," "sql," or "php." If there are any "<" or ">" within your code, please search and replace them with: &lt; and &gt; respectively.