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:

  • <?php echo $form->labelTag('Image/images', 'Image:' );?>
    <?php echo $html->file('Image/filedata');?>


But we want the ability to upload multiple images at once, so let’s adjust our view accordingly:
  • <?php echo $form->labelTag('Image/images', 'Image 1:' );?>
    <?php echo $html->file('Image/filedata1');?>
  • <?php echo $form->labelTag('Image/images', 'Image 2:' );?>
    <?php echo $html->file('Image/filedata2');?>
  • <?php echo $form->labelTag('Image/images', 'Image 3:' );?>
    <?php echo $html->file('Image/filedata3');?>


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("",$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.