Jump to content

Having a bit of delima with this image upload statement.


mannyson

Recommended Posts

Here's the deal.  I am getting into uploading multiple images with  a record details.  Image file paths are stored in "images" table and records are stored in "records" table.  They both work fine separately.  I am just having issue using both of them together since "foreach loop" is involved.  I want to make sure the image is uploaded and check for errors before inserting the image and record details.  Since this for uploading "multiple files", all this checking for errors is inside "foreach loop".  It will insert the images fine, but it will also insert the record details multiple times(depending on the images attached) in the records table.  If I insert the record details outside the loop, it'll insert only once but then it'll insert the data with or without the images attached.

 

Here's a basic set up of what I am talking about . I removed the extra code.  I just would like to know where I can place the insert into records code relative to the foreach loop so that It checks the errors for file uploads and inserts details in to the database after that.

if(isset($_POST['submit']) {
	
		$record_name		 = trim($_POST['record_name']);
		$record_details		 = trim($_POST['record_details']);
		$record_type		 = trim($_POST['record_type']);
		$date				 =	date('Y-m-d H:i:s');
		
		if(empty($record_name)) {
							
			echo 'record name is required!';
			
		} else if(empty($record_details)) {
		
			$error = 'record details are required!';
		
		} else if(empty($record_type)) {
		
			$error = 'Type is required!';
		
		} else {
			  
			if(isset($_FILES['files'])){
			
				$userdir	= $_SERVER['DOCUMENT_ROOT'] .'/comp/images/';
				
				if(!is_dir($userdir)){

					mkdir($userdir, 0775, true);
					
				}
			
				foreach($_FILES['files']['tmp_name'] as $key => $tmp_name ){
				
					if(is_uploaded_file($_FILES['files']['tmp_name'][$key])) {
				
						if(in_array($type, $allowed)) {
							
							try {
										
								$insert_image = $db->prepare("INSERT INTO images(record_id, image_path, date) VALUES(:record_id, :image_path, :date)");
								$insert_image->bindParam(':record_id', $record_id);
								$insert_image->bindParam(':image_path', $image_path);
								$insert_image->bindParam(':date', $date_added);
								$result_image = $insert_image->execute();
								if($result_image == false) {
								
									echo 'There was a problem!';
								
								} else {
								
									move_uploaded_file($temp, $file_path);
									
									echo 'Your image has been saved.';
									
									
								}
								
								$insert_record = $db->prepare("INSERT INTO records(record_name, record_type, record_details, date) 
								VALUES(:record_name, :record_type, :record_details, :date)");
								$insert_record->bindParam(':record_name', $record_name);
								$insert_record->bindParam(':record_type', $record_type);
								$insert_record->bindParam(':record_details', $record_details );
								$insert_record->bindParam(':date', $date);
								$result_record = $insert_record->execute();
								if($result_record == true) {
									
									echo 'Your record has been saved.';	
								
							
								} else {
									$error = 'record not added!';
								}
								
								
								
							} catch(Exception $e) {
								$error = die($e->getMessage());
							}
							
						} else {
							
							echo 'You have uploaded a forbidden extension!';
							
						}
					} else {
							
						echo 'File is empty!';
						
					}	
				}
			}
				
		}	
	
	}
Link to comment
Share on other sites

After if(in_array($type, $allowed)) {

save them as an array

end loop

check for not an empty array

build your sql query statement using implode() from the array

 

You could also build an array the failed ones and any error messages.

 

I noticed you use die(), if you do that the loop will stop and not do anything else.

Edited by QuickOldCar
Link to comment
Share on other sites

After if(in_array($type, $allowed)) {

save them as an array

end loop

check for not an empty array

build your sql query statement using implode() from the array

 

You could also build an array the failed ones and any error messages.

 

I noticed you use die(), if you do that the loop will stop and not do anything else.

 

Can you provide an example with the array? It would really help.  Thanks.

Link to comment
Share on other sites

Just to clarify something, you're inserting 1 record and multiple images correct? If so, you would insert into the records table first to obtain the record id and then insert the multiple images using the for loop. If my assumption is correct then your $insert_record section should be moved to before the "if(isset($_FILES['files'])){" part. $record_id would come from the id of the record that was inserted using $insert_record-lastInsertId() after the $insert_record->execute() statement.

Link to comment
Share on other sites

Just to clarify something, you're inserting 1 record and multiple images correct? If so, you would insert into the records table first to obtain the record id and then insert the multiple images using the for loop. If my assumption is correct then your $insert_record section should be moved to before the "if(isset($_FILES['files'])){" part. $record_id would come from the id of the record that was inserted using $insert_record-lastInsertId() after the $insert_record->execute() statement.

 

Yes I can do that and I have done it.  But that's not the solution I am looking for it.  I am inserting 1 record with option to choose multiple images.  The record will insert if I have it outside the loop.  And the images will insert if I have selected them. The issue is that if the selected image(s) gives an error, the record itself will insert anyways  I just want to make sure that if errors are produced by the selected images, that to not insert the record data into the table.  That's all.

Edited by mannyson
Link to comment
Share on other sites

validation of the form data and using the form data are two different concerns and have to be separated. you have to validate the form data first, then use the resulting error information to determine what the rest of the code should do.

 

if you use an array to hold your validation errors, your logic will be easier to write. create an array to hold the errors - $errors = array(); to added errors to the array - $errors[] = "some validation error message"; to test if there are not or are errors at any point in your program flow - if(empty($errors)){} - no errors or - if(!empty($errors)){} - there are errors.

Edited by mac_gyver
Link to comment
Share on other sites

Yes I can do that and I have done it.  But that's not the solution I am looking for it.  I am inserting 1 record with option to choose multiple images.  The record will insert if I have it outside the loop.  And the images will insert if I have selected them. The issue is that if the selected image(s) gives an error, the record itself will insert anyways  I just want to make sure that if errors are produced by the selected images, that to not insert the record data into the table.  That's all.

 

Ah ha, you could make good use of transactions for this issue.

 

I have taken mac_gyver's suggestion of using $errors along with using PDO's transaction system to keep track of errors and choosing whether or not to commit to the database or rollBack.

 

Making use of $errors allows you to collect all possible errors that occurred with the form, display that to the user so that they could potentially fix all problems with a single form submission. You're original script would mean they would continuously have to resubmit the form checking every field individually which is very annoying if you run into it in real life.

<?php
if (isset($_POST['submit']) {

    $record_name		 = trim($_POST['record_name']);
    $record_details		 = trim($_POST['record_details']);
    $record_type		 = trim($_POST['record_type']);
    $date				 =	date('Y-m-d H:i:s');

    $errors = array();

    if (empty($record_name)) {
        $errors[] = 'record name is required!';
    }

    if (empty($record_details)) {
        $errors[] = 'record details are required!';
    }

    if (empty($record_type)) {
        $errors[] = 'Type is required!';
    }

    $db->beginTransaction();

    $insert_record = $db->prepare("INSERT INTO records(record_name, record_type, record_details, date)
                            VALUES(:record_name, :record_type, :record_details, :date)");
    $insert_record->bindParam(':record_name', $record_name);
    $insert_record->bindParam(':record_type', $record_type);
    $insert_record->bindParam(':record_details', $record_details );
    $insert_record->bindParam(':date', $date);
    if (!$insert_record->execute()) {
        $errors[] = 'record not added!';
    }

    $record_id = $db->lastInsertId();

    if (!empty($_FILES['files'])) {

        $userdir = $_SERVER['DOCUMENT_ROOT'] . '/comp/images/';

        if (!is_dir($userdir)){
            mkdir($userdir, 0775, true);
        }

        foreach($_FILES['files']['tmp_name'] as $key => $tmp_name ){
            $file_path = $userdir . $tmp_name;

            if (is_uploaded_file($_FILES['files']['tmp_name'][$key])) {

                if (in_array($type, $allowed)) {

                    try {
                        $insert_image = $db->prepare("INSERT INTO images(record_id, image_path, date) VALUES(:record_id, :image_path, :date)");
                        $insert_image->bindParam(':record_id', $record_id);
                        $insert_image->bindParam(':image_path', $file_path);
                        $insert_image->bindParam(':date', $date);
                        if (!$insert_image->execute()) {
                            $errors[] = 'There was a problem!';
                        } else {
                            move_uploaded_file($tmp_name, $file_path);
                            echo 'Your image has been saved.';
                        }

                    } catch(Exception $e) {
                        $error[] = die($e->getMessage());
                    }

                } else {
                    $errors[] = 'You have uploaded a forbidden extension!';
                }
            } else {
                $errors[] = 'File is empty!';
            }
        }
    } else {
        $errors[] = 'No files supplied';
    }

    # If the errors array is empty then commit all of the changes we've made above, to the database.
    # Otherwise rollback all changes/inserts and undo everything we just did.
    if (empty($errors)) {
        $db->commit();
    } else {
        $db->rollBack();
    }
}
Edited by iarp
Link to comment
Share on other sites

 

Ah ha, you could make good use of transactions for this issue.

 

I have taken mac_gyver's suggestion of using $errors along with using PDO's transaction system to keep track of errors and choosing whether or not to commit to the database or rollBack.

 

Making use of $errors allows you to collect all possible errors that occurred with the form, display that to the user so that they could potentially fix all problems with a single form submission. You're original script would mean they would continuously have to resubmit the form checking every field individually which is very annoying if you run into it in real life.

<?php
if (isset($_POST['submit']) {

    $record_name		 = trim($_POST['record_name']);
    $record_details		 = trim($_POST['record_details']);
    $record_type		 = trim($_POST['record_type']);
    $date				 =	date('Y-m-d H:i:s');

    $errors = array();

    if (empty($record_name)) {
        $errors[] = 'record name is required!';
    }

    if (empty($record_details)) {
        $errors[] = 'record details are required!';
    }

    if (empty($record_type)) {
        $errors[] = 'Type is required!';
    }

    $db->beginTransaction();

    $insert_record = $db->prepare("INSERT INTO records(record_name, record_type, record_details, date)
                            VALUES(:record_name, :record_type, :record_details, :date)");
    $insert_record->bindParam(':record_name', $record_name);
    $insert_record->bindParam(':record_type', $record_type);
    $insert_record->bindParam(':record_details', $record_details );
    $insert_record->bindParam(':date', $date);
    if (!$insert_record->execute()) {
        $errors[] = 'record not added!';
    }

    $record_id = $db->lastInsertId();

    if (!empty($_FILES['files'])) {

        $userdir = $_SERVER['DOCUMENT_ROOT'] . '/comp/images/';

        if (!is_dir($userdir)){
            mkdir($userdir, 0775, true);
        }

        foreach($_FILES['files']['tmp_name'] as $key => $tmp_name ){
            $file_path = $userdir . $tmp_name;

            if (is_uploaded_file($_FILES['files']['tmp_name'][$key])) {

                if (in_array($type, $allowed)) {

                    try {
                        $insert_image = $db->prepare("INSERT INTO images(record_id, image_path, date) VALUES(:record_id, :image_path, :date)");
                        $insert_image->bindParam(':record_id', $record_id);
                        $insert_image->bindParam(':image_path', $file_path);
                        $insert_image->bindParam(':date', $date);
                        if (!$insert_image->execute()) {
                            $errors[] = 'There was a problem!';
                        } else {
                            move_uploaded_file($tmp_name, $file_path);
                            echo 'Your image has been saved.';
                        }

                    } catch(Exception $e) {
                        $error[] = die($e->getMessage());
                    }

                } else {
                    $errors[] = 'You have uploaded a forbidden extension!';
                }
            } else {
                $errors[] = 'File is empty!';
            }
        }
    } else {
        $errors[] = 'No files supplied';
    }

    # If the errors array is empty then commit all of the changes we've made above, to the database.
    # Otherwise rollback all changes/inserts and undo everything we just did.
    if (empty($errors)) {
        $db->commit();
    } else {
        $db->rollBack();
    }
}

 

 

Yes that does seem to work.  Now the only issue I have is the "f (is_uploaded_file($_FILES['files']['tmp_name'][$key]))".  Despite having a file selected, it will return the "else(file is empty)" error.  It won't process beyond that. 

 

Now if I remove that check, it'll process. But then it'll go to the next error "You have uploaded a forbidden extension!" on submit, even if a file is not selected. I think the check "if (!empty($_FILES['files'])) " is not really doing it's job.

Edited by mannyson
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.