Jump to content

Allow empty image upload.


slove05

Recommended Posts

I have a form that adds an event to my database. It collects some basic information as well as allows me to upload an image/pdf. This works flawlessly as long as there is an image/pdf to upload but I would also like it to allow the image fields to be left null if there is no image. I am just beginning in mysqli and think the solution is something along the lines of an if else statement but am unfamiliar enough to not be sure where this should occur. Below is the code I am using.

if (isset($_POST['create'])) {
                
                $title = $_POST['title'];
                $date = $_POST['date'];
                $time = $_POST['time'];
				$desc = $_POST['desc'];
				$presenter = $_POST['business'];
				$picname = $_POST['picname'];
				$size = $_POST['size'];
				$type = $_POST['type'];
				$path = $_POST['path'];
				
                
				if(isset($_FILES['image'])){
      $errors= array();
      $file_name = $_FILES['image']['name'];
      $file_size =$_FILES['image']['size'];
      $file_tmp =$_FILES['image']['tmp_name'];
      $file_type=$_FILES['image']['type'];
      $file_ext=strtolower(end(explode('.',$_FILES['image']['name'])));
      
      $expensions= array("jpeg","jpg","pdf");
      
      if(in_array($file_ext,$expensions)=== false){
         $errors[]="extension not allowed, please choose a JPEG or pdf file.";
      }
      
      if($file_size > 2097152){
         $errors[]='File size must be under 2 MB';
      }
      
      if(empty($errors)==true){
         move_uploaded_file($file_tmp,"upload/".$file_name);
         
      }else{
         print_r($errors);
      }
   
 
}
				
				
                $sql = "INSERT INTO events VALUES(id, '{$title}', '{$date}', '{$time}', '{$desc}', '{$presenter}', '{$file_name}', '{$file_size}', '{$file_type}')";
				                
				mysqli_query($con, $sql) or die (mysqli_error($con)); 
				echo "Success";
		 
    }

I would think after the last { I would create an else statement similar to what I am posting below. 

}
	 else{ 
	 
	 $sql2 = "INSERT INTO events VALUES(id, '{$title}', '{$date}', '{$time}', '{$desc}', '{$presenter}', 'NULL', 'NULL', 'NULL')";
				                
				mysqli_query($con, $sql2) or die (mysqli_error($con)); 
				echo "Success";
	 }

However I know this returns an error relating to the first error check in the file upload. Do I just need to switch the statements around? Any guidance would be appreciated. 

Link to comment
Share on other sites

1. The first piece of code doesn't have any SQL stuff in it. It doesn't make sense to me that the second piece should go with it. Surely there's more code somewhere else that also does an INSERT? You should be modifying that so it can support an empty image, rather than making a whole new INSERT just for that one case.

 

2. The first piece of code doesn't support an empty image. I think it will complain about an invalid extension. You need to use the upload "error" status (a) period, because you can't just assume that the upload was successful, and (b) to tell if no file was uploaded.

$file_error = $_FILES['image']['error'];
switch($file_error) {
	case UPLOAD_ERR_OK:
		// okay
		break;
	case UPLOAD_ERR_INI_SIZE:
	case UPLOAD_ERR_FORM_SIZE:
		// file is too large
		break;
	case UPLOAD_ERR_PARTIAL:
		// file upload did not complete
		break;
	case UPLOAD_ERR_NO_FILE:
		// no file was uploaded
		break;
	case UPLOAD_ERR_NO_TMP_DIR:
	case UPLOAD_ERR_CANT_WRITE:
	case UPLOAD_ERR_EXTENSION:
	default:
		// system error preventing the file from being uploaded
		break;
}
Link to comment
Share on other sites

1. The insert happens on line 46.

 

2. You are correct that I receive an error about an invalid extension when the upload is left blank. 

 

I assumed (because I have little experience with mysqli and php) this would be an if else statement. If there is 

if(isset($_FILES['image'])){

then run 

$sql

if not run 

$sql2

from your statement I see that this is not the case at all. So to clarify my question could I have some guidance as to how I would modify the code to accept an empty upload.

Link to comment
Share on other sites

1. The insert happens on line 46.

Huh. How did I miss that? I even scrolled down to see the rest of the if block...

 

 

Okay. There's two things that need to change: supporting empty uploads, of course, but there's a larger problem of SQL injection where apostrophes in any of the fields (for example) will cause your INSERT to fail. At best; a malicious user could instead do damage to your database. Fixing that problem will also change how you deal with the empty uploads so you should do that first.

 

The solution is with prepared statements. Instead of

$sql = "INSERT INTO events VALUES(id, '{$title}', '{$date}', '{$time}', '{$desc}', '{$presenter}', '{$file_name}', '{$file_size}', '{$file_type}')";
mysqli_query($con, $sql) or die (mysqli_error($con)); 
echo "Success";
you do

$sql = "INSERT INTO events VALUES(id, ?, ?, ?, ?, ?, ?, ?, ?)";
$stmt = mysqli_prepare($con, $sql);
mysqli_stmt_bind_param($stmt, "ssssssss", $title, $date, $time, $desc, $presenter, $file_name, $file_size, $file_type);
// probably should be more like
// $stmt->bind_param("ssssssis", $title, $date, $time, $desc, $presenter, $file_name, $file_size, $file_type);
// because $file_size and whatever the column in the events table is are both numbers and not strings

mysqli_stmt_execute($stmt);
With that changed, all you have to do for an empty upload is set $file_name, $file_size, and $file_type to null. (And make sure the table supports NULL in those three columns.) So modify the upload logic to look something like

switch (error status) {
	case successful:
		do the rest of the upload handling, including error checking;
		break;

	case no file uploaded:
		set those three variables to null;
		break;

	other cases:...
}
(which references the switch I posted earlier) Edited by requinix
Link to comment
Share on other sites

Ah yes and now I am back in "I have no idea what you are talking about land." I have not used switch before and have no idea where I would even put the code. I would assume I would add...

$file_error = $_FILES['image']['error'];

to the following... or does it replace that completely with the rest of the code you suggested. 

$errors= array();
      $file_name = $_FILES['image']['name'];
      $file_size =$_FILES['image']['size'];
      $file_tmp =$_FILES['image']['tmp_name'];
      $file_type=$_FILES['image']['type'];
      $file_ext=strtolower(end(explode('.',$_FILES['image']['name'])));
Edited by slove05
Link to comment
Share on other sites

Oh my land after HOURS of reading it totally clicked and I have the code working flawlessly. Thank you so much requinix for pointing me in the correct direction, showing me the value of prepared statements. I would not have done any of that without your urging. 

Link to comment
Share on other sites

This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.