Multiple Image Uploads Into Single MySQL Table (CakePHP)
The impossible has been done - uploading multiple images in CakePHP. Find out how easy it is, and why it was never really impossible to begin with.
There have been updates to this article. Please make sure you note any changes before commenting.
This article assumes you use the CakePHP image upload component I covered a while back. If you’re not using it, you should be.
The goal of this article is to explain how to upload multiple photos in CakePHP using a single MySQL table. The images will be uploaded into an uploads folder, while the image names will be stored in a single MySQL table.
Pretext
I’ll assume your upload form is placed in /app/views/images/upload.thtml and your images component sits at /app/controllers/images_controller.php. If you need an example of either file, download the complete package and follow along.
Configure Your View
In order to upload a single image via CakePHP, our view upload.thtml would consist of a single upload field:
<ul>
<li>
<?php echo $form->labelTag('Image/images', 'Image:' );?>
<?php echo $html->file('Image/filedata');?>
</li>
</ul>
But we want the ability to upload multiple images at once, so let’s adjust our view accordingly:
<ul>
<li>
<?php echo $form->labelTag('Image/images', 'Image 1:' );?>
<?php echo $html->file('Image/filedata1');?>
</li>
<li>
<?php echo $form->labelTag('Image/images', 'Image 2:' );?>
<?php echo $html->file('Image/filedata2');?>
</li>
<li>
<?php echo $form->labelTag('Image/images', 'Image 3:' );?>
<?php echo $html->file('Image/filedata3');?>
</li>
</ul>
All we’ve done is added more upload fields to our form. Of course we also named them accordingly: filedata followed by a number.
Dressing Up The Controller
Next we need to modify our controller (/app/controllers/images_controller.php) to handle the multiple files.
The tricky part comes when we need to store each file name in a single MySQL table called images. We’ll do this by creating an array of each file name, implode the array, then store the resulting string in MySQL. Sounds confusing, but it’s not. Read on.
// set the upload destination folder
$destination = realpath('../../app/webroot/img/uploads/') . '/';
// number of file form fields
$num = 3;
/* take care of image uploads */
$array = "";
// loop through each image field
for ($i=1; $i<=$num; $i++)
{
$file = $this->data['Image']['filedata'.$i];
if (!$file['name']) continue;
// upload image
$result = $this->Upload->upload($file, $destination, null, array('type' => 'resizecrop', 'size' => array('100', '100'), 'output' => 'jpg'));
// error check
if($result || !empty($this->Upload->errors)) {
// there's been an error, delete any uploaded images
if(is_array($array) && count($array) >= 1) {
foreach($array as $file) { // delete each file
unlink($destination.$file);
}
}
// display error
$errors = $this->Upload->errors;
// piece together errors
if(is_array($errors)){ $errors = implode("<br />",$errors); }
$this->Session->setFlash($errors);
$this->redirect('/images/upload');
exit();
}
// add the image filename to the $array
if(!is_array($array)){
$array = array();
array_push($array, $this->Upload->result);
} else {
array_push($array, $this->Upload->result);
}
}
The for loop above makes sure each form field is properly addressed. The script attempts to upload the data and displays a proper error message if it fails.
The above images_controller.php example is only partially complete. For a complete example, download the complete package below.
Download The Package
You can download a working CakePHP example of the files described in this article. The MySQL file needed to create the example images table is included.
Download the complete ‘Multiple Image Uploads (CakePHP)’ package here.
Let me know if I’ve missed anything, or if you need help.
Updates
Nov 8th, 2007: The uploads component (upload.php) has been fixed to correctly handle filetypes.

[...] Next we’ll slap the necessary code in place to handle a single image upload. (To upload multiple images at once, check out this article.) [...]
[...] Multiple Image Uploads Into Single MySQL Table (CakePHP) [...]
Thanks again for providing help with multiple uploads. I do have one “problem”. If I use the new upload component (upload.php) that you provide in the complete ‘Multiple Images Uploads Package’ you posted here, I can’t upload any images. I keep receiving the ‘File type not allowed.’ message, although they are .jpg and those types are allowed. But when I use the old upload component from a while back it works excellent. Did I do something wrong or is there something wrong with the new upload component(upload.php) you made?
Moelle, the filetype error was my mistake. All fixed!
So the multiple upload works GREAT but it would be better for me if each image had it’s own record in MySQL instead of one recorde with multiple images. I tried it myself to modify the controller but i couldn’t get it to work. Can you help me with that?
I totally agree with the comment above, would love to see this adding its own record for each file upload, instead of imploding them all into the same record.
Great work though.
[...] files via CakePHP has been covered a few times on Labs. Based on the feedback, it’s safe to assume bridging the gap between file [...]
Releod, that worked for me ;O)
Hi,
First off, thanks for posting these components. I removed a bunch of the code so I could use them for general file uploads rather then just images.
I ran into a few things on the way I thought I should share.
The
upload()function does not always return true or false depending on if the upload succeeds. This is important because in the code the $result is relied on in the image controller. I moved some things around, but at the bottom of the function I added this line which should take care of the issue:Also in the upload function, you go through the effort of adding an ending slash to the
$directoryvariable being passed in, and assign it to$this->_destination. However, a few lines later when you need to use the slash appended directory, you use the$directoryvariable again rather then the freshly appended$this->_destinationThe last thing I found, this may not be a big issue for some people, but in the uniquename function, and in the upload function, you hard code the “/” to separate directories. This is not a problem if you are on *nix, but windows has a problem with this. To get around this problem, just replace the slash with PHP constant DIRECTORY_SEPARATOR.
Thanks again for the work!
very nice
If you want multiple sql records for each images try this:
Remove the implode array line and then do a foreach,
very important to set the id to null or in each loop it will overwrite the date from the previous one and only add the last one.
When i download and execute this code im getting this error….
Class ‘AppController’ not found in C:\wamp\www\multipleimage\multiple-uploads-11062007\app\controllers\images_controller.php on line 2
Send me a reply and send this function
Your code kind of sucks, why use a fixed amount of file-uploads in combination with a manual numbering?
You could more easier use a array for storing multiple file-uploads. So instead of using
$html->file(or$form->filein cake 1.2), create a custom element:In the controller you can use:
Consider the controller code pseudo, since the array does not yet have the required structure for a valid insert into our Image table. Also there is no file handling implemented yet.