CodeIgniter Framework Guide — Lightweight PHP MVC
CodeIgniter is a powerful PHP framework with a tiny footprint (~2MB) — designed for developers who need simplicity, speed, and minimal configuration without sacrificing features.
What You’ll Learn
By the end of this guide, you’ll understand CodeIgniter’s MVC structure, use the Query Builder for database access, validate forms, and build lightweight PHP applications.
Why CodeIgniter Matters
CodeIgniter excels where server resources are limited or you need maximum performance with minimum overhead. At DodaTech, we use CodeIgniter for lightweight API services that power DodaZIP’s cloud sync and Doda Browser’s bookmark sharing — cases where every millisecond of load time matters.
CodeIgniter Architecture
flowchart LR
A[Request] --> B[Router]
B --> C[Controller]
C --> D{Model?}
D -->|Yes| E[Query Builder]
D -->|No| F[View]
E --> F
F --> G[Response]
Key Features
Query Builder
// app/Controllers/Products.php
class Products extends BaseController
{
public function index()
{
$data['products'] = $this->db->table('products')
->where('stock >', 0)
->orderBy('name', 'asc')
->get()
->getResult();
return view('products/index', $data);
}
public function view($id = null)
{
$product = $this->db->table('products')
->where('id', $id)
->get()
->getRow();
return view('products/view', ['product' => $product]);
}
}Form Validation
$validation = \Config\Services::validation();
$validation->setRules([
'name' => 'required|min_length[3]|max_length[100]',
'email' => 'required|valid_email',
'price' => 'required|numeric'
]);CodeIgniter 4 brings modern PHP features (namespaces, PSR-4 autoloading) while keeping the simplicity of earlier versions. Its tiny footprint makes it ideal for shared hosting and resource-constrained environments.
Session Management
CodeIgniter provides a session library that supports file-based, database, and Redis storage:
$session = session();
// Set session values
$session->set('user_id', 42);
$session->set('role', 'admin');
// Retrieve values
$userId = session('user_id');
if ($userId && session('role') === 'admin') {
echo 'Welcome, admin user!';
}
// Flash data — available for only the next request
session()->setFlashdata('message', 'Product saved successfully!');
// Read and remove flash data
echo session()->getFlashdata('message');Expected output after the flash data example:
Product saved successfully!Built-in Security
CodeIgniter ships with CSRF protection, XSS filtering, and secure password hashing:
// Enable CSRF protection in app/Config/Security.php
// public $csrfProtection = 'cookie';
// In your form view, include the CSRF token:
// <input type="hidden" name="<?= csrf_token() ?>" value="<?= csrf_hash() ?>">
// XSS filtering with esc()
$cleanHtml = esc($userInput, 'html'); // <script>alert('xss')</script>
$cleanUrl = esc($userInput, 'url'); // URL-encoded
$cleanAttr = esc($userInput, 'attr'); // Safe for HTML attributes
// Password hashing using PHP's built-in bcrypt
$hash = password_hash($userPassword, PASSWORD_BCRYPT);
if (password_verify($inputPassword, $hash)) {
// Proceed with login
}The esc() function is your first defense against XSS. Always pass user-generated content through it before rendering in views.
How CodeIgniter Works Under the Hood
Every CodeIgniter request follows a well-defined lifecycle:
flowchart TD
A[index.php] --> B[Initialize Environment]
B --> C[Load Config + Helpers]
C --> D[Router: Parse URL]
D --> E[Security Check]
E --> F[Dispatch Controller]
F --> G[Execute Method]
G --> H{Render?}
H -->|Yes| I[Load View]
H -->|No| J[Return String]
I --> K[Send Response]
J --> K
- index.php — the single entry point. Sets the environment path and boots the system.
- Environment setup — error reporting, timezone, locale are configured from
app/Config/. - Routing — the
IncomingRequestis matched against route definitions. Parameters are extracted. - Security — CSRF tokens are verified, input is filtered, and XSS checks run.
- Controller dispatch — the matched controller is instantiated via the Services class and its method is called.
- View rendering — the controller optionally loads view files, passing data with
return view('name', $data). - Response — the final output is sent to the client.
The Services class (\Config\Services) is the heart of CodeIgniter’s dependency management. It lazy-loads core services: Services::db() returns a database connection on first call, then caches it for subsequent calls. This means you never pay for services you don’t use.
RESTful API Example
Here’s a complete JSON API controller using CodeIgniter’s ResourceController:
namespace App\Controllers\Api;
use CodeIgniter\RESTful\ResourceController;
class Products extends ResourceController
{
protected $modelName = 'App\Models\ProductModel';
protected $format = 'json';
public function index()
{
$products = $this->model->orderBy('name', 'asc')->findAll();
return $this->respond($products, 200);
}
public function show($id = null)
{
$product = $this->model->find($id);
return $product
? $this->respond($product, 200)
: $this->failNotFound('Product not found');
}
public function create()
{
$data = $this->request->getJSON(true);
if ($this->model->insert($data)) {
return $this->respondCreated($data);
}
return $this->failValidationErrors($this->model->errors());
}
public function update($id = null)
{
$data = $this->request->getJSON(true);
if ($this->model->update($id, $data)) {
return $this->respond($data, 200);
}
return $this->failValidationErrors($this->model->errors());
}
public function delete($id = null)
{
if ($this->model->delete($id)) {
return $this->respondDeleted(['id' => (int)$id]);
}
return $this->failNotFound('Product not found');
}
}Register the route in app/Config/Routes.php:
$routes->resource('api/products');Expected output — GET /api/products:
[
{"id": 1, "name": "Widget", "price": 9.99, "stock": 42},
{"id": 2, "name": "Gadget", "price": 14.99, "stock": 18}
]Expected output — POST /api/products with body {"name": "New Item", "price": 5.99}:
{
"name": "New Item",
"price": 5.99
}The ResourceController maps HTTP verbs to controller methods automatically: GET → index()/show(), POST → create(), PUT/PATCH → update(), DELETE → delete(). This convention eliminates boilerplate routing code.
Common Mistakes
1. Not escaping output — Always use CodeIgniter’s esc() function to prevent XSS.
2. Using auto-connection for every request — For APIs, use manual database connections to improve performance.
3. Ignoring the Security class — CodeIgniter provides CSRF protection, XSS filtering, and password hashing — use them.
Practice Questions
1. How do you get a single row with Query Builder?
$this->db->table('products')->where('id', $id)->get()->getRow()
2. What’s CodeIgniter’s main advantage over larger frameworks?
Small footprint (~2MB), minimal server requirements, simple setup — ideal for shared hosting and simple applications.
3. How do you prevent SQL injection in CodeIgniter?
Query Builder automatically parameterizes queries. Never use raw SQL with concatenated input.
FAQ
{< faq >}
- What is Codeigniter?
- Codeigniter refers to the core concepts and practices used to build and manage modern web applications. Understanding it is essential for web developers.
- Do I need prior experience to learn Codeigniter?
- Basic familiarity with web development concepts helps, but Codeigniter can be learned step by step even as a beginner.
- How long does it take to learn Codeigniter?
- With consistent practice, you can grasp the fundamentals in a few days to a week. Mastery takes ongoing practice and real-world projects.
- Where can I use Codeigniter in real projects?
- Codeigniter is used in a wide range of applications — from simple websites to complex enterprise systems, depending on the specific tools and technologies involved.
- What are common tools used with Codeigniter?
- The specific tools depend on the technology stack, but version control (Git), package managers, and testing frameworks are commonly used alongside most development topics.
{< /faq >}
Real-World Task: Product Search with Pagination
Build a search endpoint for an e-commerce product catalog. This is the same pattern DodaTech uses in DodaZIP’s file search and Durga Antivirus Pro’s threat lookup.
Step 1: Create a route in app/Config/Routes.php:
$routes->get('api/products/search/(:segment)', 'Api\Products::search/$1');Step 2: Add a search method to ProductModel:
namespace App\Models;
use CodeIgniter\Model;
class ProductModel extends Model
{
protected $table = 'products';
protected $allowedFields = ['name', 'description', 'price', 'stock', 'category_id'];
public function search(string $term, int $limit = 20, int $offset = 0): array
{
$this->like('name', $term)
->orLike('description', $term)
->where('stock >', 0);
$total = $this->countAllResults(false);
$results = $this->orderBy('name', 'asc')
->findAll($limit, $offset);
return [
'results' => $results,
'total' => $total,
'limit' => $limit,
'offset' => $offset
];
}
}Step 3: Add the search action to your API controller:
public function search($term = null)
{
if (!$term) {
return $this->fail('Search term required');
}
$limit = $this->request->getGet('limit') ?? 20;
$offset = $this->request->getGet('offset') ?? 0;
$data = $this->model->search($term, (int)$limit, (int)$offset);
return $this->respond($data, 200);
}Expected output — GET /api/products/search/widget?limit=5:
{
"results": [
{"id": 1, "name": "Widget", "price": 9.99, "stock": 42},
{"id": 5, "name": "Super Widget", "price": 19.99, "stock": 7}
],
"total": 2,
"limit": 5,
"offset": 0
}Challenge: Add category filtering — accept a ?category=electronics query parameter and join with the categories table.
What’s Next
| Lesson | Description |
|---|---|
| https://tutorials.dodatech.com/backend/php/laravel/ | Full-featured framework |
| https://tutorials.dodatech.com/backend/php/cakephp/ | Conventions-based framework |
| https://tutorials.dodatech.com/backend/php/php-advanced/ | Advanced PHP concepts |
| PHP | Core PHP language |
| MySQL | Database queries |
What’s Next
Congratulations on completing this Codeigniter tutorial! Here’s where to go from here:
- Practice daily — Consistency is more important than long study sessions
- Build a project — Apply what you learned by building something real
- Explore related topics — Check out other tutorials in the same category
- Join the community — Discuss with other learners and share your progress
Remember: every expert was once a beginner. Keep coding!
Built by the developers of DodaTech
Doda Browser, DodaZIP & Durga Antivirus Pro