title: How to upload image and insert data into a MySQL database
body: <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>