= CodeIgniter Basics = [[http://www.codeigniter.com/|CodeIgniter]] is one of the more popular PHP-based MVC frameworks in use today. CodeIgniter lets you quickly build out simple web applications, and provides easy-to-use support for common needs such as displaying error pages. == CodeIgniter Structure == When you download CI, you'll find a couple folders & files: * **application**, which contains your application code. This is where you'll do all your work. * **system**, which contains all of CI's core libraries and scaffolding code. * **user_guide** and **license.txt**, both of which pretty much tell you what they are * **index.php**, the core 'front controller' which dispatches all requests. //NOTE: I prefer to [[#SecuringCodeIgniter|move this]] and [[http://codeigniter.com/wiki/mod_rewrite/|remove it from the URL]].// Inside the application folder, there are several sub-folders. Key items include: * **config**, which has site-specific configuration variables * **controllers**, which house all of your controllers (business logic) * **errors**, with common error pages * **models**, which contain your application specific data models (user, product, etc.) * **views**, which contains the presentation logic for your app == Writing Models, Views & Controllers == The controllers contain your business logic, and in the MVC world generally pull data from models and send it to views. displayHello(); } /* * displayHello(): display a hello page * */ public function displayHello() { $this->load->model('UserModel'); $this->UserModel->setName('David'); $data['name'] = $this->UserModel->getName(); $this->load->view('hello', $data); } } The views are your presentation layer, and contain HTML code for display. Hello World

Hello,

The models represent your data, and generally interact with your database. _name; } function setName($name) { $this->_name = $name; } } == Accessing the Database == Models like the above aren't terribly useful. What you really want to do is access your database to load and save data from your models. CodeIgniter allows you to do this yourself, or via its (somewhat loose) [[http://codeigniter.com/user_guide/database/active_record.html|active record class]]. Best practice seems to be to use the active record class; most CI developers I interviewed were doing that. == Best Practices for Models == There's an interesting question with CI models: do you code with private member variables, getters/setters and load/save functions, or does each function in the model talk to the database directly: function AddUser($insertData) function UpdateUser($userId, $updateData) function DeleteUser($userId) function GetUsers($limit, $offset)) The CodeIgniter docs aren't really clear on the point; their [[http://codeigniter.com/user_guide/general/models.html|example model uses both styles]]. Generally, most common practice I've seen is the latter - you should have one function for each of the CRUD operations, and avoid getters, setters, load & save functions. I'm not terribly comfortable with this approach, but when in Rome... ==== Model Validation ==== The question of data validation comes up: in a traditional model, you'd validate incoming data via the setters. With CI, best practice actually seems to be to not check it at all, because you [[http://codeigniter.com/user_guide/libraries/form_validation.html|should have checked it via the form validation functions]] in your controller. I **strongly** disagree with that philosophy, and recommend doing at least some basic sanity checks using PHP's built in validation functions (''is_int()'', ''!empty()'', ''filter_var()'', etc.). I would recommend putting these in a private validation function in each model, which uses CI's ''show_error()'' function to stop code execution. (Stopping code execution should be no problem, because you used CI's from validation rules earlier, so you'll never fail on this validation, right?) Shawn McCool has an interesting take on this, [[http://heybigname.com/2009/08/28/how-to-write-a-better-model-in-code-igniter/|recommending a _required() utility method]]. ==== Validating Result Sets ==== The next big question is how to validate result sets coming back from the database. If you make a query and don't get anything back, you probably need to do something about that. In the real world, you'd probably throw an exception and then optionally catch that exception if its OK that you didn't get any results back. With CI, you can't really do that, so you have three options: - Return a set of default values if you don't find a record in the database. - Use CI's show_error function to display a 'result not found' message and stop execution of your code. This //only// works if you never have a case where you might legitimately get back an empty result. - Return the empty set, and make your controller logic handle the error. This is what you'll probably have to do in most cases, and it just means a lot of extra code in your controllers. == Best Practices for Controllers == CI generally recommends that all data validation be done initially in the controller, which makes some sense. I recommend you do it when you're passing in user generated data (e.g. on a reg form) and need to display a pretty error message. I don't think its as critical if you're passing in computer generated data (e.g. the ID number of something in your database) because that should be validated at the model level. == Best Practices for Views == Your views will probably contain some standard stuff, such as a default header & footer. CodeIgniter allows you to queue a series of views up to be loaded, so you can do something like this: function index() { $data['page_title'] = 'Your title'; $this->load->view('header'); $this->load->view('menu'); $this->load->view('content', $data); $this->load->view('footer'); } == Using Helpers == Helpers are pretty much as they sound; a set of functions that help you do something specific. CodeIgniter comes with a bunch of built-in helpers in ''/system/helpers'', and you can add more via the ''/application/helpers'' folder. As with other CI functions, the load is done via: $this->load->helper('name'); Helpers do all sorts of things; some popular ones: * **[[http://codeigniter.com/user_guide/helpers/date_helper.html|Date Helper]]**: perform operations on dates, such as ''mysql_to_unix()'', ''unix_to_human()'' and ''standard_date()''. * **[[http://codeigniter.com/user_guide/helpers/file_helper.html|File Helper]]**: read/write/manage files with functions such as ''read_file()'', ''write_file()'' and ''get_file_info()'' * **[[http://codeigniter.com/user_guide/helpers/string_helper.html|String Helper]]**: work with strings using functions like ''random_string()'', ''reduce_double_slashes()'' and ''trim_slashes()'' == Using Libraries == Libraries are like helpers, but are a little bit more 'full featured'. Helpers are generally sets of quick one-off functions that do something specific; libraries have a variety of connected functionality. System libraries are in ''/system/libraries'' and you can add your own in ''/application/libraries''. There is occasionally some duplicative functions; for example the [[http://codeigniter.com/user_guide/helpers/email_helper.html|Email Helper]] and the [[http://codeigniter.com/user_guide/libraries/email.html|Email Class]] both have functions that allow you to send email, but the latter is **much** more comprehensive. Libraries are loaded in the standard way: $this->load->library('class name'); == Securing CodeIgniter == One of the best practices from a security standpoint is to keep your PHP code outside of the 'web root', which is served by apache. I do this with CI: * I move my ''index.php'' file to ''www/index.php'' and change the ''$system_path'' and ''$application_folder'' in that file. * I move all my images/JS/CSS into the ''www'' folder, and then have apache point to that folder.