Basic Image Uploading
Let's build an image uploader. Not a theoretical example. Not a "hello world" toy. A real image uploader that resizes images and generates thumbnails automatically, using Trongate's Image module.
We'll use the following three-method pattern:
- Display the upload form
- Process the upload with validation
- Show the success page with image preview
Each method does one thing. Clean. Simple. Maintainable.
The Complete Controller
Create a simple_image_uploader directory with a controller file (name 'Simple_image_uploader.php') at:
modules/simple_image_uploader/Simple_image_uploader.php
Here's the code for the controller file:
<?php
class Simple_image_uploader extends Trongate {
/**
* 1. Display the upload form
*/
function index() {
$data['view_module'] = 'simple_image_uploader';
$data['view_file'] = 'upload_form';
$this->view('upload_form', $data);
}
/**
* 2. Process the image upload
*/
function submit_upload() {
// Validate first
$this->validation->set_rules(
'userfile',
'Image',
'required|max_size[5000]|max_width[3000]|max_height[3000]'
);
$result = $this->validation->run();
if ($result === true) {
// Configure image upload with automatic processing
$config = [
'destination' => 'uploads',
'upload_to_module' => true,
'max_width' => 800,
'max_height' => 800,
'thumbnail_dir' => 'uploads/thumbs',
'thumbnail_max_width' => 150,
'thumbnail_max_height' => 150,
'make_rand_name' => false
];
$file_info = $this->image->upload($config);
set_flashdata('Image uploaded successfully!');
redirect('simple_image_uploader/success/' . $file_info['file_name']);
} else {
$this->index();
}
}
/**
* 3. Display the success page
*/
function success() {
$data['filename'] = segment(3);
$data['view_module'] = 'simple_image_uploader';
$data['view_file'] = 'upload_success';
$this->view('upload_success', $data);
}
}
?>
That's the entire controller. Three methods. Zero complexity. Production-ready pattern.
The Image module automatically processes the first file uploaded in your form, regardless of its input field name. This makes it consistent with the File module.
Important: File Input Name
The name attribute of your file input field must match what you're validating. In this example, we use userfile consistently throughout:
- Form:
form_file_select('userfile', ...)
- Validation:
set_rules('userfile', 'File', ...)
The Upload Form View
Create a view file named 'upload_form.php' at the following location:
modules/simple_image_uploader/views/upload_form.php
Here's the code for the view file:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<link rel="stylesheet" href="simple_image_uploader_module/css/simple_image_uploader.css">
<title>Upload Image</title>
</head>
<body>
<h1>Upload Image</h1>
<?= validation_errors() ?>
<div class="info">
<p><strong>Allowed file types:</strong> JPEG, PNG, GIF, WEBP</p>
<p><strong>Maximum file size:</strong> 5 MB</p>
<p><strong>Maximum dimensions:</strong> 3000 x 3000 pixels</p>
<p><strong>Note:</strong> Images larger than 800x800px will be automatically resized. A 150x150px thumbnail will be generated.</p>
</div>
<?php
echo form_open_upload('simple_image_uploader/submit_upload');
echo form_label('Select Image:', ['for' => 'userfile']);
$select_attr = [
'id' => 'userfile',
'accept' => 'image/jpeg,image/png,image/gif,image/webp'
];
echo form_file_select('userfile', $select_attr);
echo form_submit('submit', 'Upload Image');
echo form_close();
?>
</body>
</html>
About the CSS file: The two view files mentioned on this page reference simple_image_uploader.css, which should be located at:
modules/simple_image_uploader/css/simple_image_uploader.css
Trongate's Module Asset Manager will automatically find and load this file when the views are rendered.
As a reminder, you can download the complete module (including the CSS file) from GitHub:
Simple Image Uploader Module
The Success Page View
Create a file named 'upload_success.php' and have it located at:
modules/simple_image_uploader/views/upload_success.php
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<link rel="stylesheet" href="simple_image_uploader_module/css/simple_image_uploader.css">
<title>Upload Complete</title>
</head>
<body>
<h1>Upload Complete!</h1>
<?= flashdata() ?>
<?php if (!empty($filename)) { ?>
<div class="image-info">
<h2>Your Uploaded Image</h2>
<p><strong>File Name:</strong> <code><?= out($filename) ?></code></p>
<div class="image-preview">
<h3>Full Size (max 800x800px)</h3>
<img src="<?= BASE_URL ?>simple_image_uploader_module/uploads/<?= $filename ?>"
alt="Uploaded image"
class="uploaded-image">
</div>
<div class="thumbnail-preview">
<h3>Thumbnail (150x150px)</h3>
<img src="<?= BASE_URL ?>simple_image_uploader_module/uploads/thumbs/<?= $filename ?>"
alt="Thumbnail"
class="thumbnail-image">
</div>
<div class="actions">
<?= anchor('simple_image_uploader', 'Upload Another Image', ['class' => 'button']) ?>
</div>
</div>
<?php } else { ?>
<div class="alert">
<p>No image information available.</p>
<p><?= anchor('simple_image_uploader', 'Upload an Image', ['class' => 'button']) ?></p>
</div>
<?php } ?>
</body>
</html>
Create the Upload Directories
Before uploading, create the directories where images and thumbnails will be stored:
# From your application root:
mkdir -p modules/simple_image_uploader/uploads/thumbs
chmod 755 modules/simple_image_uploader/uploads
chmod 755 modules/simple_image_uploader/uploads/thumbs
Or create them via PHP if you prefer:
// Run this once in a controller
$this->file->create_directory('uploads', 0755, true);
$this->file->create_directory('uploads/thumbs', 0755, true);
How It Works (The Flow)
- User visits
yoursite.com/simple_image_uploader
- Form displays with image file selection input
- User selects image and clicks "Upload Image"
- Browser POSTs to
yoursite.com/simple_image_uploader/submit_upload
- Trongate validates the image (required, type, size, dimensions)
- If valid:
- Uploads image to
modules/simple_image_uploader/uploads/
- Automatically resizes if larger than 800x800px
- Generates 150x150px thumbnail in
uploads/thumbs/
- Sets success message and redirects
- If invalid: Redisplays form with error messages
- Success page shows both full-size image and thumbnail
Key Concepts Explained
1. form_open_upload() vs form_open()
Use form_open_upload() for image uploads. It automatically adds:
<!-- form_open() -->
<form action="..." method="post">
<!-- form_open_upload() -->
<form action="..." method="post" enctype="multipart/form-data">
That enctype attribute is required for file uploads. Trongate adds it automatically.
2. The POST-Redirect-GET Pattern
Notice, we don't render the success page directly. Instead, when an upload is successful, we immediately redirect the user elsewhere:
// ❌ WRONG - causes "resubmit form?" on refresh
if ($result === true) {
$data['filename'] = $file_info['file_name'];
$this->view('upload_success', $data); // Don't do this!
}
// ✅ RIGHT - clean refresh, no duplicate uploads
if ($result === true) {
set_flashdata('Image uploaded successfully!');
redirect('simple_image_uploader/success/' . $file_info['file_name']);
}
POST (upload) → Process → Redirect → GET (success page)
3. Validation Before Upload
We always validate before uploading:
// ❌ WRONG - uploads then validates
$file_info = $this->image->upload($config);
$this->validation->set_rules(...); // Too late!
// ✅ RIGHT - validates then uploads
$this->validation->set_rules(...); // Validate first
if ($this->validation->run() === true) {
$file_info = $this->image->upload($config); // Upload only if valid
}
4. What Happens Automatically
When you call $this->image->upload($config), the Image module automatically:
- Validates MIME types (JPEG, PNG, GIF, WEBP only)
- Checks file signatures to prevent spoofed uploads
- Scans for embedded malicious content
- Resizes images that exceed max_width or max_height
- Maintains aspect ratios during resizing
- Generates thumbnails with specified dimensions
- Prevents filename conflicts (car.jpg → car_2.jpg → car_3.jpg)
All of this happens with zero configuration beyond the simple config array.
Try It Right Now
- Create the three files above
- Create the upload directories (uploads and uploads/thumbs)
- Visit:
yoursite.com/simple_image_uploader
- Upload an image (JPEG, PNG, GIF, or WEBP)
- See the resized image and thumbnail on the success page
Don't forget: You're welcome to download the code from GitHub.