EllisLab text mark
Advanced Search
1 of 9
1
   
Starting with CodeIgniter setup: suggestions & best practices
Posted: 08 August 2009 02:59 PM   [ Ignore ]
Avatar
Joined: 2007-03-10
451 posts

In August 2009 I had been programming with CodeIgniter a little over 2 years, in that time I learned a lot of things which would have been good to know when I began. I made a list of stuff I considered best practices for programming in CodeIgniter, which I have kept up to date. But as I have since moved on to another framework this is it, the final update was on: March 2nd, 2012
These 2 posts I licensed under MIT so do with it as you please as long as you give proper acknowledgement about the origin.

RT(F)M: Read the User Guide & watch tutorials
Clear and simple, don’t ask questions before you looked into the awesome thing that makes CI stand out among frameworks: The CodeIgniter User Guide. There’s a lot of references in this article to the user guide, but those are highlights for specific topics - the whole thing should be read!

Also to get started you can find some video tutorials on nettuts+ or view the (very dated) video tutorials on the CodeIgniter website. The latter is using an older version but when you take that into consideration it’s still a nice place to start understanding the basics of using CI.

MVC programming
If you don’t know the MVC pattern read up on it! You’ll learn soon the value of putting the data-access in models, the application logic in controllers and the visuals in views. But if you haven’t done programming in such a pattern before it might take a while to sink in, give it the chance to sink in!
A good guideline is to put as little as possible into your controller. Adhere to the DRY principle: Don’t Repeat Yourself. When functionality is needed in more than one place, create a library, helper or model (depending on what kind of functionality it is). You’ll notice that once you start to grasp the MVC basics this will become habitual and you’ll start to reap the benifits that good clean MVC code bring.

You can read up on MVC in the CI User Guide: MVC, Flow chart, Models, Views & Controllers.
Or external sources like Wikipedia.

Error reporting and debugging
One of the most often made mistakes is to forget to turn off PHP errors or Database errors, both of which are gigantic security riscs. It’s a security risk because you allow an attacker to debug his hacking using the displayed warnings.
Codeigniter offers environment settings to help with this. On any public site error_reporting should be set to 0 (or at most E_ERROR), database setting db_debug should be set to false and just for extra measure I tend to do a ini_set(‘display_errors’, ‘Off’).
At the same time you should debug your application with error_reporting set to -1 (this will show E_ALL and E_STRICT, E_ALL doesn’t include E_STRICT warnings), and solve every notice and warning before making your application public. You tend to spot “invisible” bugs sooner and thus write better code. (more on the error reporting levels on php.net)

One way to make all of this easy has been for me to set the db_debug value (in the application/config/database.php config file) to a constant I declare MP_DB_DEBUG. And add the following code to the top of the main index.php to replace the error_reporting() declaration when the site is live (will disable all errors):

ini_set('display_errors''Off');
error_reporting(0);
define('MP_DB_DEBUG'false); 

But when in production or testing phase I’d suggest:

ini_set('display_errors''On');
error_reporting(-1);
define('MP_DB_DEBUG'true); 

For even better error reporting Dan Horrigan ported a great error reporting script to CI which you can find on Github. This must never be switched on in a live-site environment but is a huge help during production and has probably saved me hours already.

Application & System directory placement

An absolute best practice is to put the system & application directories outside the webroot. If your main index.php is in your FTP in a directory like /public_html/ try if you can upload the system directory to the root as /system/. That way no one can access your PHP files except through the index.php.

Don’t forget to change the values $system_folder and $application_folder in the main index.php file. $system_folder should be relative to the index.php file, $application_folder should be relative to the system folder.

 Signature 

Starting with CodeIgniter setup
Senior dev of FuelPHP

 
Posted: 08 August 2009 02:59 PM   [ Ignore ]   [ # 1 ]   [ Rating: 0 ]
Avatar
Joined: 2007-03-10
451 posts

Security

Read up on SQL injection, XSS (CSS), CSRF (XSRF) and understand them before you decide if you need measures against them or not. Also read up in the CI user guide on the security guidelines and XSS filtering from the Input class. Probably the most important guidline is to validate and check all the input from users before any kind of interaction with your database, filesystem, etc.
There’s a pretty good overview of all the issues and some solutions Writing secure PHP.

SQL Injection
Using CI’s Active Record should take care of this problem.

XSS
Be aware which parts of your site are vulnerable to attacks of this kind and be sure to filter all user input when you can’t be a 100% sure the user is to be trusted.

CSRF
As of CI2.0 support for tokens is built in, this is explained on the bottom of the Security class docs. To learn more you can do a google search on “CSRF tokens” for protecting simple form submissions and actions done by URL. Or for AJAX operations search Google for “double cookie submission”.

SPAM
Always protect your email forms, comment forms and any other kind of free user submitted data against spamming. The easy way is to only allow each IP/User agent to submit once every minute, while that doesn’t protect against hackers & bots it does protect you against the usual internet trolls.
The best way is to use Captcha like reCAPTCHA to protect email & comment forms on your website. You can search the forums on how to intergrate reCAPTCHA with CI. CI2 also provides a CAPTCHA helper.

Performance
Write good clean code and understand your code, don’t just copy paste the stuff others wrote and always look for ways to improve your code. Just never ever sacrifice security for performance. The PHP Style guide from the CodeIgniter manual is a very good place to learn to write better code.

DRY
Don’t Repeat Yourself. Put shared code where it belongs: in libraries, helpers or models, but not in controllers. Definite rule of thumb: when you’re copy-pasting code, you probably just put it in the wrong place for a second time.

Caching
Caching is a pretty good way to improve performance, especially the ammount of database operations needed can be scaled back easily by using cache. Take a look into page caching & database caching, and Caching drivers.

HTTP headers
On the client side you can improve performance by sending HTTP headers along that instruct the browser to keep your stuff in it’s cache. This is also good to read up on when using AJAX because you’ll need to disable browser-cache for those operations. Google it!

Example for AJAX return data (that shouldn’t be browser-cached at all):

$this->output->set_header("Last-Modified: " gmdate("D, d M Y H:i:s") . " GMT");
$this->output->set_header("Cache-Control: no-store, no-cache, must-revalidate");
$this->output->set_header("Cache-Control: post-check=0, pre-check=0"false);
$this->output->set_header("Pragma: no-cache"); 

Example for things that should be kept for a long time (like css, javascripts):

$this->output->set_header('Cache-Control: private, pre-check=0, post-check=0, max-age=2592000');
$this->output->set_header('Expires: ' gmstrftime("%a, %d %b %Y %H:%M:%S GMT"time() + 2592000));
$this->output->set_header('Last-Modified: ' gmstrftime("%a, %d %b %Y %H:%M:%S GMT"time() - 20)); 

Database access & ORM
CodeIgniter has a library called Active Record (AR) that can help you write your queries without writing any SQL. It’s pretty powerful and the better way to go when you’re no SQL expert or aren’t sure how to protect your queries against SQL injections.

When you need more power an Object Relational Mapper (ORM) might be the thing for you, and while CI doesn’t come with an ORM there are some options out there that are all very good.
The most populair is probably DataMapper OverZealous Edition (DMZ). Others are Doctrine (there’s a tutorial on PHP and stuff) and RapidDataMapper.

User auth & ACL
A very much debated topic since it doesn’t come with CI and there are as many who think it should, as there are who think the opposite. All I can advise you on this is to search the forums and look for a system that’s still active, has good security and that intergrates easily into your application. Or research the examples and write your own.

At this point I would recommend Ion Auth, it’s very well written and probably alot better than you’d write on your first try. And if you are planning on writing your own, read through it for inspiration.

Anything else?
Search the forums and the wiki, and if you can’t find it you can always ask.

Did I forget anything or get anything wrong? Reply and I’ll look into into it.

 Signature 

Starting with CodeIgniter setup
Senior dev of FuelPHP

 
Posted: 08 August 2009 09:38 PM   [ Ignore ]   [ # 2 ]   [ Rating: 0 ]
Joined: 2003-10-22
209 posts

You couldn’t have posted this 3 months ago grin

Nice job and great contribution.

 Signature 

Template Driven PHP Shopping Cart Software

 
Posted: 09 August 2009 05:43 PM   [ Ignore ]   [ # 3 ]   [ Rating: 0 ]
Avatar
Joined: 2009-06-30
32 posts

Thanks for taking the time in making this, nice contribution to the forums.

 Signature 

Programmer. Designer. Thinker.

 
Posted: 23 September 2009 08:03 AM   [ Ignore ]   [ # 4 ]   [ Rating: 0 ]
Avatar
Joined: 2007-03-10
451 posts

Someone mentioned an inconsistancy to me about error reporting. It used to say:

On any public site error_reporting should be set to E_ERROR

And then I went on to set error reporting to 0 instead of E_ERROR.

E_ERROR essentially means 1 and is as such one level more reporting than 0 (none at all). According to php.net, setting error reporting to E_ERROR means:

Fatal run-time errors. These indicate errors that can not be recovered from, such as a memory allocation problem. Execution of the script is halted.

My view is that in a live site any error should be either written by me (the programmer) or not shown at all. The users shouldn’t know what went wrong except when I explicitly told the system what it should tell the user. Which is why in the example code error reporting is set to 0 and not to E_ERROR.

Which is why I’ve changed the suggested error reporting to 0 instead of E_ERROR for any live site. I’ve corrected the comment explanation of the levels in the error reporting switch code because in the PHP code 1 means fatal errors & DB errors (instead of only DB errors) and 2 means compiler errors & db errors (instead of fatal & db errors). Also I’ve added a link to the error reporting pre-defined constants on php.net (http://nl2.php.net/manual/en/errorfunc.constants.php).

 Signature 

Starting with CodeIgniter setup
Senior dev of FuelPHP

 
Posted: 08 November 2009 11:46 PM   [ Ignore ]   [ # 5 ]   [ Rating: 0 ]
Avatar
Joined: 2007-03-09
25 posts

Just wanted to say thanks for putting this together, very nice one stop, quick start guide to get people up to speed, and doing things correctly from the start. CI has some damn good forum members!

Thanks,

marinaccio

 Signature 

-
Joseph Marinaccio
.(JavaScript must be enabled to view this email address) | web dev

 
Posted: 09 November 2009 08:13 AM   [ Ignore ]   [ # 6 ]   [ Rating: 0 ]
Joined: 2009-04-28
8 posts

Very nice.
Thx for the trouble !

 
Posted: 18 November 2009 10:33 AM   [ Ignore ]   [ # 7 ]   [ Rating: 0 ]
Avatar
Joined: 2007-03-10
451 posts

Some small edits:
- location of the db_debug setting in the first post
- better structure in the bit on performance
- some HTTP headers examples
- removed link to the security presentation that went offline (pitty, was very good)

 Signature 

Starting with CodeIgniter setup
Senior dev of FuelPHP

 
Posted: 16 January 2010 06:59 AM   [ Ignore ]   [ # 8 ]   [ Rating: 0 ]
Avatar
Joined: 2010-01-15
7 posts

It helped me
Thanks

 Signature 
 
Posted: 16 January 2010 10:17 AM   [ Ignore ]   [ # 9 ]   [ Rating: 0 ]
Avatar
Joined: 2008-02-24
614 posts

This is really helpful - thanks for posting it! I’m making it sticky so more people will hopefully read it smile

 Signature 

THE CODEIGNITER HANDBOOK - A new CI book for everybody!
—-
Freelance Web Developer - @jamierumbelow - http://jamieonsoftware.com

 
Posted: 16 January 2010 10:15 PM   [ Ignore ]   [ # 10 ]   [ Rating: 0 ]
Joined: 2009-10-14
42 posts

Great learning path…and so true…RT(F)M!

 
Posted: 17 January 2010 11:55 PM   [ Ignore ]   [ # 11 ]   [ Rating: 0 ]
Avatar
Joined: 2009-12-28
51 posts

That’s a really good POST! Damn I LOVE IT!

Great Job Buddy!

 Signature 

Alejandro Ñañez Ortiz
Twitter
Mi Blog

 
Posted: 18 January 2010 07:05 PM   [ Ignore ]   [ # 12 ]   [ Rating: 0 ]
Avatar
Joined: 2009-10-18
334 posts

Thanks a lot

My personal best practices (you can take em or leave em =P):
_Write everything in camelCase when possible
_Always set up a main controller in the libraries directory, from which all your other controllers extends.
_Everything that can be output, make it a view. Eg: error messages.
_JS files in /js. Call them through a view.
_Always follow the same naming pattern, like getComments, getSomething. Wrong: findComments, fetchSomething, giveMeTheStuff.
_I can say the same about database tables and columns. If the primary key is the table’s id, name it just id. If it has-a-thing, make a column named thingId, or thing_id. But stick to the one you choose.
_Try to make your methods for general purpose reusable when possible.
_Never hardcode. Make a custom config file and use it (it’s clear in the userguide)
_Avoid using include/require. Only use it to add functionality to your codeigniter, but do it inside a library.

If something else comes to my mind ill write it later

 Signature 

Wallpapers and Images Site: Desktop Wallpapers

 
Posted: 20 January 2010 11:04 PM   [ Ignore ]   [ # 13 ]   [ Rating: 0 ]
Joined: 2010-01-06
4 posts

Thanks for this post. Very straight forward.

 
Posted: 24 January 2010 05:19 PM   [ Ignore ]   [ # 14 ]   [ Rating: 0 ]
Joined: 2010-01-24
1 posts

Useful post I like this. thanks

 
Posted: 04 February 2010 01:10 PM   [ Ignore ]   [ # 15 ]   [ Rating: 0 ]
Avatar
Joined: 2009-03-27
67 posts

Nice post.. Thanks smile

 Signature 

Download CodeIgniter 2.0 Cheat Sheet http://www.mmyo.me/30

More CodeIgniter Related Resources : http://www.memeyo.com/groups/codeigniter

 
1 of 9
1