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.
In a hurry? Head over to GitHub and download the Simple Image Uploader module:
https://github.com/trongate/Trongate-v2---Simple-Image-Uploader
The code demonstrates basic image uploading concepts with automatic resizing and thumbnail generation.
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.phpHere'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.phpHere'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/thumbsOr 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
- Uploads image to
- 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 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.
We're continually improving the Trongate documentation. If anything is incorrect, unclear, incomplete, or could be better, we'd genuinely appreciate your input.
Share your thoughts in the Documentation Feedback.