How to upload image and insert data into a MySQL database
<p>I have a PHP form on "add-category.php" that enables the admin to add a product category and in the process upload an image to a predetermined folder and insert its file name and relevant data into the database. The script worked well with mysql_, but now it stopped working after I upgraded my "functions.php" to PDO. The main issue is that adding a category fails because the image cannot upload. Help me to fix it, so the image can upload. I want to include the security benefits of PDO prepared statements.</p>

<p>This is the error message:</p>

<pre><code>Warning: imagejpeg(/home/ script-directory/products/images/category/ec27a92192042fdc049e54477649fb30.jpg): failed to open stream: No such file or directory in /home/script-directory/includes/functions.php on line 385
</code></pre>

<p>This following is the "add-category.php":</p>

<pre><code>&lt;?php

require_once '../../includes/config.php';

if(isset($_POST['txtName']))

{
    $categoryName = $_POST['txtName'];

    $categoryMtitle = $_POST['metaTitle'];

    $categoryMkey = $_POST['metaKey'];

    $categoryMdes = $_POST['metaDesc']; 

    $categoryDesc = $_POST['mtxDesc'];


    $imgName   = $_FILES['fleImage']['name'];

    $tmpName   = $_FILES['fleImage']['tmp_name'];

    // we need to rename the image name just to avoid
    // duplicate file names
    // first get the file extension
    $ext = strrchr($imgName, ".");

    // then create a new random name
    $newName = md5(rand() * time()) . $ext;

    // the category image will be saved here
    $imgPath = ALBUM_IMG_DIR . $newName;

    // resize all category image
    $result = createThumbnail($tmpName, $imgPath, THUMBNAIL_WIDTH, THUMBNAIL_HEIGHT);

    if (!$result) {
        echo "Error uploading file";
        exit;

    } 

    //$query = "INSERT INTO prod_cat (cat_name, cat_metatitle, cat_metakeywords, cat_metadescription, cat_description, cat_image, cat_date) 

    //        VALUES ('$categoryName', '$categoryMtitle', '$categoryMkey', '$categoryMdes', '$categoryDesc', '$newName', NOW())"; 

    if(!$query = "INSERT INTO prod_cat (cat_name, cat_metatitle, cat_metakeywords, cat_metadescription, cat_description, cat_image, cat_date) 

              VALUES (:categoryName, :categoryMtitle, :categoryMkey, :categoryMdes, :categoryDesc, :newName, NOW())")

    {

        adminapologize("Error, adding product category failed.");         

    }

    $params = array(':categoryName' =&gt; $categoryName, ':categoryMtitle' =&gt; $categoryMtitle, ':categoryMkey' =&gt; $categoryMkey, ':categoryMdes' =&gt; $categoryMdes, ':categoryDesc' =&gt; $categoryDesc, ':newName' =&gt; $newName);

        var_dump($params);
        exit;        

    // the category is saved, go to the category list 

    echo "&lt;script&gt;window.location.href='index.php?page=list-category';&lt;/script&gt;";

    exit;

}

    // include add category template

    include("templates/add-category_template.php");


?&gt;
</code></pre>

<p>I did</p>

<pre><code>var_dump($params);
exit;
</code></pre>

<p>and it outputs "no file or directory error and this code, bearing the data I entered into the form:</p>

<pre><code>array (size=6)
  ':categoryName' =&gt; string 'Balls' (length=5)
  ':categoryMtitle' =&gt; string 'Corporate Gift balls' (length=20)
  ':categoryMkey' =&gt; string 'ball, balls' (length=11)
  ':categoryMdes' =&gt; string 'Buy corporate gift items like balls' (length=35)
  ':categoryDesc' =&gt; string '&lt;p&gt;Buy corporate gift items like balls&lt;/p&gt;' (length=42)
  ':newName' =&gt; string '8da973c4e2b0dd801d55c3dae56f89d7.jpg' (length=36)
</code></pre>

<p>In the "config.php", the image location is stated:</p>

<pre><code>// APP_ROOT will always be set to 2 directorys up from the location of this file
    define('APP_ROOT', dirname(dirname(__FILE__)) . '/');
    // a category can have an image used as thumbnail
    // we save the category image here
    define('ALBUM_IMG_DIR', APP_ROOT . 'products/images/category/');
// all images inside an category are stored here
define('GALLERY_IMG_DIR', APP_ROOT . 'products/images/gallery/');
</code></pre>

<p>In the "functions.php", I have this code regarding PDO and image upload:</p>

<pre><code>    /**
    * Executes SQL statement, possibly with parameters, returning
    * a pdo statement object on success, handling and halting execution on error.
    */
    function query($sql, $parameters = null)
    {
        static $pdo; // define the var as static so that it will persist between function calls
    try
    {
        // if no db connection, make one
        if (!isset($pdo))
        {
            // connect to database
            // you should set the character encoding for the connection
            $pdo = new PDO("mysql:dbname=" . DB_NAME . ";host=" . DB_SERVER, DB_USERNAME, DB_PASSWORD);
            $pdo-&gt;setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); // set the error mode to exceptions
            $pdo-&gt;setAttribute(PDO::ATTR_EMULATE_PREPARES,false); // turn emulated prepares off
            $pdo-&gt;setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE,PDO::FETCH_ASSOC); // set default fetch mode to assoc so that you don't have to explicitly list the fetch mode every place
        }
        if(empty($parameters)){
            // no bound inputs
            $stmt = $pdo-&gt;query($sql);
        } else {
            // has bound inputs
            $stmt = $pdo-&gt;prepare($sql);
             // you should use explicit bindValue() statements to bind any inputs, instead of supplying them as a parameter to the -&gt;execute() method. the comments posted in your thread lists the reasons why.
            $stmt-&gt;execute($parameters);
        }
        }
        catch (Exception $e)
        {
            // all errors with the connection, query, prepare, and execute will be handled here
            // you should also use the line, file, and backtrace information to produce a detailed error message
            // if the error is due to a query, you should also include the $sql statement as part of the error message
            // if $pdo ($handle in your code) is set, it means that the connection was successful and the error is due to a query. you can use this to include the $sql in the error message.
            trigger_error($e-&gt;getMessage(), E_USER_ERROR);
            //exit; // note: E_USER_ERROR causes an exit, so you don't need an exit; here.
        }
            return $stmt; // if the query ran without any errors, return the pdo statement object to the calling code
        }
/*
    Upload an image and create the thumbnail. The thumbnail is stored 
    under the thumbnail sub-directory of $uploadDir.
    Return the uploaded image name and the thumbnail also.
*/
function uploadImage($inputName, $uploadDir)
{
    $image     = $_FILES[$inputName];
    $imagePath = '';
    $thumbnailPath = '';
    // if a file is given
    if (trim($image['tmp_name']) != '') {
        $ext = substr(strrchr($image['name'], "."), 1); 
        // generate a random new file name to avoid name conflict
        // then save the image under the new file name
        $imagePath = md5(rand() * time()) . ".$ext";
        $result    = move_uploaded_file($image['tmp_name'], $uploadDir . $imagePath);
        if ($result) {
            // create thumbnail
            $thumbnailPath =  md5(rand() * time()) . ".$ext";
            $result = createThumbnail($uploadDir . $imagePath, $uploadDir . 'thumbnail/' . $thumbnailPath, THUMBNAIL_WIDTH);
            // create thumbnail failed, delete the image
            if (!$result) {
                unlink($uploadDir . $imagePath);
                $imagePath = $thumbnailPath = '';
            } else {
                $thumbnailPath = $result;
            }   
        } else {
            // the image cannot be uploaded
            $imagePath = $thumbnailPath = '';
        }
    }
    return array('image' =&gt; $imagePath, 'thumbnail' =&gt; $thumbnailPath);
}
/*
    Create a thumbnail of $srcFile and save it to $destFile.
    The thumbnail will be $width pixels.
*/
function createThumbnail($srcFile, $destFile, $width, $quality = 75)
{
    $thumbnail = '';
    if (file_exists($srcFile)  &amp;&amp; isset($destFile))
    {
        $size        = getimagesize($srcFile);
        $w           = number_format($width, 0, ',', '');
        $h           = number_format(($size[1] / $size[0]) * $width, 0, ',', '');
        $thumbnail =  copyImage($srcFile, $destFile, $w, $h, $quality);
    }
    // return the thumbnail file name on sucess or blank on fail
    return basename($thumbnail);
}
/*
    Copy an image to a destination file. The destination
    image size will be $w X $h pixels
*/
function copyImage($srcFile, $destFile, $w, $h, $quality = 75)
{
    $tmpSrc     = pathinfo(strtolower($srcFile));
    $tmpDest    = pathinfo(strtolower($destFile));
    $size       = getimagesize($srcFile);
    if ($tmpDest['extension'] == "gif" || $tmpDest['extension'] == "jpg")
    {
       $destFile  = substr_replace($destFile, 'jpg', -3);
       $dest      = imagecreatetruecolor($w, $h);
       //imageantialias($dest, TRUE);
    } elseif ($tmpDest['extension'] == "png") {
       $dest = imagecreatetruecolor($w, $h);
       //imageantialias($dest, TRUE);
    } else {
      return false;
    }
    switch($size[2])
    {
       case 1:       //GIF
           $src = imagecreatefromgif($srcFile);
           break;
       case 2:       //JPEG
           $src = imagecreatefromjpeg($srcFile);
           break;
       case 3:       //PNG
           $src = imagecreatefrompng($srcFile);
           break;
       default:
           return false;
           break;
    }
    imagecopyresampled($dest, $src, 0, 0, 0, 0, $w, $h, $size[0], $size[1]);
    switch($size[2])
    {
       case 1:
       case 2:
           imagejpeg($dest,$destFile, $quality);
           break;
       case 3:
           imagepng($dest,$destFile);
    }
    return $destFile;
}
</code></pre>