Jump to content

PHP/ MYSQLI problem

jameshumphries47

So again, im working on my admin site, but the code i have works but the problem with this is that when i select a photo to upload and click submit it will upload but then the problem that happens is when the page refreshes the entry gets added again. Any help with this would be excellent thanks :)

<?php
if(isset($_POST['uploadsub'])){
    //
   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'])));
      $file_ext=strtolower(pathinfo($_FILES['image']['name'], PATHINFO_EXTENSION));
      
      $expensions= array("jpeg","jpg","png");
      
      if(in_array($file_ext,$expensions)=== false){
         $errors[]="extension not allowed, please choose a JPEG or PNG file.";
      }
      
      if($file_size > 2097152){
         $errors[]='File size must be excately 2 MB';
      }
      
      if(empty($errors)==true){
        unset($_POST['uploadsub']);
         move_uploaded_file($file_tmp,"../img/gallery/gallery/".$file_name);

         echo "Success";
         //
      }else{
         print_r($errors);
      }
   }

   $con = mysqli_connect("localhost","cms","password","admin_0.1");
// Check connection
if (mysqli_connect_errno()){
  echo "Failed to connect to MySQL: " . mysqli_connect_error();
  }
 $sql = "INSERT INTO photos (name) VALUES ('$file_name')";
//
if ($con->query($sql) === TRUE) {
    unset($_POST['uploadsub']);
} else {
    echo "Error: " . $sql . "<br>" . $con->error;
}

$con->close();
}else{
    echo'error';
}
?>
<html>

   <body>
      
      <form action = "photo.php" method = "POST" enctype = "multipart/form-data">
         <br><input type = "file" name = "image" />
         <input type = "submit" name="uploadsub"/>
            <?php 
            if(isset ($_FILES['image']['name'] )){
                echo "
         <ul>
            Sent file:";echo $_FILES['image']['name'];"
            File size ";echo $_FILES['image']['size'];"<br>
            File type:";echo $_FILES['image']['type'];"<br>
         </ul> ";
     }else{
     }

         ?>
            
      </form>
   </body>
</html>  

 

Check out my current projects: Selling site (Click Here)

If($reply == "for me to see"){

   $action = "Quote me!";

}else{

   $action = "Leave me alone!";

}

Link to comment
Share on other sites

Link to post
Share on other sites

1 minute ago, thekeemo said:

What do you mean the entry gets added again?

okay so say i have a file called file.jpg that filename will get added to the database when i click submit, then for whatever reason i refresh the page the website will then add another row to my database with a filename of file.jpg

Check out my current projects: Selling site (Click Here)

If($reply == "for me to see"){

   $action = "Quote me!";

}else{

   $action = "Leave me alone!";

}

Link to comment
Share on other sites

Link to post
Share on other sites

1 minute ago, jameshumphries47 said:

okay so say i have a file called file.jpg that filename will get added to the database when i click submit, then for whatever reason i refresh the page the website will then add another row to my database with a filename of file.jpg

As far as I know, that will happen no matter what, unless you have AJAX. Since the code is put directly into the page, refreshing that will POST it again.

Spoiler

Everyday build:

CPU: Intel Core i7 5960x - GPU(s): 2x EVGA GTX 980 Ti Superclocked+ ACX2.0+ (SLI) - Cooler: be quiet! Dark Rock Pro 3 - Motherboard: ASUS Sabertooth X99 - RAM: 32GB Kingston HyperX Fury Black DDR4 4x8GB (2666MHz) - Storage: Intel 750 Series 1.2TB + 4TB WD Black - Case: Corsair 760T White - PSU: SeaSonic 1200W 80+ Platinum Certified - OS: Windows 10 Pro - Wireless Adapter: TP-Link Archer T9E - Monitor: Acer XB270HU bprz - Keyboard: Corsair K70 RGB - Mouse(s): Corsair Gaming M65 RGB + Logitech MX Master - Headphones: Sennheiser PC363D

http://pcpartpicker.com/p/WhyK99 https://linustechtips.com/main/topic/474247-r8-my-build/

 

Weekend build:

CPU: Intel Core i7 5930k - GPU(s): 2x EVGA GTX 980 Ti Classified ACX2.0+ (SLI) - Cooler: NZXT Kraken X61 - Motherboard: ASUS X99-Deluxe - RAM: 32GB Crucial Ballistix Sport LT DDR4 4x8GB (2666MHz) - Storage: Samsung 950 Pro 512GB m.2 & 2TB Samsung 850 Evo - Case: Phanteks Enthoo Evolv - PSU: SeaSonic SnowSilent 1050W 80+ Platinum Certified - OS: Windows 10 Home - Monitor: Dell S2716DG 144hz - Keyboard: Corsair STRAFE RGB - Mouse: Corsair Gaming M65 RGB - Headphones: Sennheiser PC363D

http://pcpartpicker.com/p/YYK93C

Link to comment
Share on other sites

Link to post
Share on other sites

Just now, cortexcortex said:

As far as I know, that will happen no matter what, unless you have AJAX. Since the code is put directly into the page, refreshing that will POST it again.

i am unfamiliar with AJAX how would i impliment this 

Check out my current projects: Selling site (Click Here)

If($reply == "for me to see"){

   $action = "Quote me!";

}else{

   $action = "Leave me alone!";

}

Link to comment
Share on other sites

Link to post
Share on other sites

1 minute ago, jameshumphries47 said:

i am unfamiliar with AJAX how would i impliment this 

Basically, you would need to use Javascript to make the "Submit" form use an external file, I guess? Google would be a much better teacher than I.

Spoiler

Everyday build:

CPU: Intel Core i7 5960x - GPU(s): 2x EVGA GTX 980 Ti Superclocked+ ACX2.0+ (SLI) - Cooler: be quiet! Dark Rock Pro 3 - Motherboard: ASUS Sabertooth X99 - RAM: 32GB Kingston HyperX Fury Black DDR4 4x8GB (2666MHz) - Storage: Intel 750 Series 1.2TB + 4TB WD Black - Case: Corsair 760T White - PSU: SeaSonic 1200W 80+ Platinum Certified - OS: Windows 10 Pro - Wireless Adapter: TP-Link Archer T9E - Monitor: Acer XB270HU bprz - Keyboard: Corsair K70 RGB - Mouse(s): Corsair Gaming M65 RGB + Logitech MX Master - Headphones: Sennheiser PC363D

http://pcpartpicker.com/p/WhyK99 https://linustechtips.com/main/topic/474247-r8-my-build/

 

Weekend build:

CPU: Intel Core i7 5930k - GPU(s): 2x EVGA GTX 980 Ti Classified ACX2.0+ (SLI) - Cooler: NZXT Kraken X61 - Motherboard: ASUS X99-Deluxe - RAM: 32GB Crucial Ballistix Sport LT DDR4 4x8GB (2666MHz) - Storage: Samsung 950 Pro 512GB m.2 & 2TB Samsung 850 Evo - Case: Phanteks Enthoo Evolv - PSU: SeaSonic SnowSilent 1050W 80+ Platinum Certified - OS: Windows 10 Home - Monitor: Dell S2716DG 144hz - Keyboard: Corsair STRAFE RGB - Mouse: Corsair Gaming M65 RGB - Headphones: Sennheiser PC363D

http://pcpartpicker.com/p/YYK93C

Link to comment
Share on other sites

Link to post
Share on other sites

i ended up doing it with a mysqli select to see if the file name already exists and some other stuff. heres the code if  you are interested.

<div class="container">
<?php
   if(isset($_POST['uploadsub'])){
        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'])));
      $file_ext=strtolower(pathinfo($_FILES['image']['name'], PATHINFO_EXTENSION));

      $expensions= array("jpeg","jpg","png");
      
      if(in_array($file_ext,$expensions)=== false){
         $errors[]="extension not allowed, please choose a JPEG or PNG file.";
      }
      
      if($file_size > 2097152){
         $errors[]='File size must be excately 2 MB';
      }
      
      if(empty($errors)==true){
        unset($_POST['uploadsub']);
         move_uploaded_file($file_tmp,"../img/gallery/gallery/".$file_name);

         echo "Success";
         //
      }else{
         print_r($errors);
      }
   }

   $con = mysqli_connect("localhost","cms","password","admin_0.1");
// Check connection
if (mysqli_connect_errno()){
  echo "Failed to connect to MySQL: " . mysqli_connect_error();
  }
 $sql = "INSERT INTO photos (name) VALUES ('$file_name')";

}else{
    echo'error';
}


 $con4 = mysqli_connect("localhost","cms","password","admin_0.1");
   $sql4 = "SELECT * from photos where `name` = '$file_name'"; // 0
   $result4 = mysqli_query($con4, $sql4);
   echo mysqli_num_rows($result4); //0
   if (mysqli_num_rows($result4) == 1) { 
    echo'data already in';
    } else {
        if(isset($sql)){
        if ($con->query($sql) === TRUE) {
} }else {
}
}
     
?>

 

Check out my current projects: Selling site (Click Here)

If($reply == "for me to see"){

   $action = "Quote me!";

}else{

   $action = "Leave me alone!";

}

Link to comment
Share on other sites

Link to post
Share on other sites

Just a few pointers with your code:

 

1) Really you should rename files when they are uploaded, people are likely to have different images with the same name. Renaming them fixes this issue.

2) You are still uploading the image even if the filename already exists

3) You are still adding an entry to the DB even if the file upload fails

4) $con and $con4 are connections to the same DB. You only need one.

 

Your code structure in general is quite messy, query strings are defined and used in a different order or never at all. Also please try and format the code a bit better with closing brackets on new lines and correct indentation, it would make it a lot easier to read.

 

On your original problem, this is due to the way browsers work. If a form submission gets you to a page a refresh of that page will prompt you to resubmit the form because without it you might see a different page.

 

You can get around this by using a PHP header to redirect the user at the end of the script but you cannot have any output (echo's) before this header.

Link to comment
Share on other sites

Link to post
Share on other sites

You cannot not receive submitted data by the script but you can easily ignore them by adding token to your form that is just random number generated and strored in form hidden input and $_SESSION variable, so after your form is sent you can check if session-token is the same as input-token if they're the same then your form was sent firs time, you should change session token just after you found out that tokens match. After the change, when you hit F5 your browser wil resend data with old input-token and as you changed session-token they wont match and data won't be accepted again. As @Brenz stated you should change file names for your own so they won't overwrite, and rather keep their original names as db field if you need it.

 

What I usually do is I hash files so if multiple users upload same file I won't end up with multiple copies of same data on my server. If user delets uploaded file from your server you can still keep control over it, and delete int only when last owner of the file deletes it (delete it when there is no reference in database to the file)

 

You can also use getimagesize to check mime type of image, so you will know that someone isn't just sending other type of file just by adding right extension.

Link to comment
Share on other sites

Link to post
Share on other sites

  • Sanitize your inputs. Never interpolate variables directly into a query string. Use prepared statements.
  • Learn how to use exceptions. Multiple unrelated, nested if statements are messy and error-prone. Exceptions allow error handling to be done by the appropriate part of your application.
  • Handle errors. In a production application, you will probably want to be more reticent about the errors that you display to the user. Try to recover from the error or at least perform cleanup and exit so that the application isn't left in a broken state.
  • Separate concerns.
    • Input validation should be handled in a separate file, preferably a class in some kind of object-relational model if you are going the OO route.
    • Business and presentation logic should be in separate places for readability, maintainability, extensibility, testablity, and other -abilities. There is nothing I hate more than a PHP app where every page is an HTML file with PHP crap up at the top.
  • Format your code. Use a real text editor that auto formats code as you type. No one wants to read code with inconsistent indentation and spacing.
  • Use clear variable names. "result4" is obtuse and unhelpful.
  • Use resources efficiently. You do not need to keep reconnecting to your database. Re-use the connection for the duration of the script.
  • Don't modify globals. You unset a key from $_POST. This is generally bad as it can lead to difficult to find bugs. Ideally, don't use globals. Store what you need from the post array at the entry point of your application and pass around the values as function parameters.

I mention all these things because if you do them, ultimately figuring out a simple issue like this will be much easier. Note that refreshing a POST request will re-submit the data. You may wish to have the form submission re-direct or be handled on a separate page.

Link to comment
Share on other sites

Link to post
Share on other sites

22 hours ago, Brenz said:

Just a few pointers with your code:

 

1) Really you should rename files when they are uploaded, people are likely to have different images with the same name. Renaming them fixes this issue.

2) You are still uploading the image even if the filename already exists

3) You are still adding an entry to the DB even if the file upload fails

4) $con and $con4 are connections to the same DB. You only need one.

 

Your code structure in general is quite messy, query strings are defined and used in a different order or never at all. Also please try and format the code a bit better with closing brackets on new lines and correct indentation, it would make it a lot easier to read.

 

On your original problem, this is due to the way browsers work. If a form submission gets you to a page a refresh of that page will prompt you to resubmit the form because without it you might see a different page.

 

You can get around this by using a PHP header to redirect the user at the end of the script but you cannot have any output (echo's) before this header.

thank you i have fixed 1-4 today, and there is only 1 person uploading a few photos into a tiny gallery im not worried about multiple names. 2, this is a problem but it just overwrites the current photo which i will have to look at. 3. fixed that. 4 yeah i know fixed this i was putting code from a few web pages together :)

i know im messy. when i coded the main part it was all formatted, but as i modify and add lines it tends to get messy quick. im going to tidy this up tomorrow.

17 hours ago, Mr_KoKa said:

You cannot not receive submitted data by the script but you can easily ignore them by adding token to your form that is just random number generated and strored in form hidden input and $_SESSION variable, so after your form is sent you can check if session-token is the same as input-token if they're the same then your form was sent firs time, you should change session token just after you found out that tokens match. After the change, when you hit F5 your browser wil resend data with old input-token and as you changed session-token they wont match and data won't be accepted again. As @Brenz stated you should change file names for your own so they won't overwrite, and rather keep their original names as db field if you need it.

 

What I usually do is I hash files so if multiple users upload same file I won't end up with multiple copies of same data on my server. If user delets uploaded file from your server you can still keep control over it, and delete int only when last owner of the file deletes it (delete it when there is no reference in database to the file)

 

You can also use getimagesize to check mime type of image, so you will know that someone isn't just sending other type of file just by adding right extension.

thanks ill look at this tomorrow.

 

16 hours ago, SSL said:
  • Sanitize your inputs. Never interpolate variables directly into a query string. Use prepared statements.
  • Learn how to use exceptions. Multiple unrelated, nested if statements are messy and error-prone. Exceptions allow error handling to be done by the appropriate part of your application.
  • Handle errors. In a production application, you will probably want to be more reticent about the errors that you display to the user. Try to recover from the error or at least perform cleanup and exit so that the application isn't left in a broken state.
  • Separate concerns.
    • Input validation should be handled in a separate file, preferably a class in some kind of object-relational model if you are going the OO route.
    • Business and presentation logic should be in separate places for readability, maintainability, extensibility, testablity, and other -abilities. There is nothing I hate more than a PHP app where every page is an HTML file with PHP crap up at the top.
  • Format your code. Use a real text editor that auto formats code as you type. No one wants to read code with inconsistent indentation and spacing.
  • Use clear variable names. "result4" is obtuse and unhelpful.
  • Use resources efficiently. You do not need to keep reconnecting to your database. Re-use the connection for the duration of the script.
  • Don't modify globals. You unset a key from $_POST. This is generally bad as it can lead to difficult to find bugs. Ideally, don't use globals. Store what you need from the post array at the entry point of your application and pass around the values as function parameters.

I mention all these things because if you do them, ultimately figuring out a simple issue like this will be much easier. Note that refreshing a POST request will re-submit the data. You may wish to have the form submission re-direct or be handled on a separate page.

yeah im using sublime text 2 at the moment, i am a messy coder but when somethings working i go back through and tidy it up. i plan in upgrading to 3 soon.

1) im not too worried on sanitizing inputs as its just so my parents can upload files to their website. although i will implement this when i have time.

2)  ill read up on this

3) hmm interesting ill also read up on this

4a/b) yeah i do plan on doing this i just needed to get it up and running then ill tidy it up

6) totally agree with you here. it was just while i was trying to get everything working i plan on renaming everything when i get time.

7) okay 

8) Oh right neat would make things easier to see where they come from

 

Thank you to everyone its really helped and now all working and when i get time i will try and implement everything you guys have told me. i really do need to work on my tidiness aha! 

Check out my current projects: Selling site (Click Here)

If($reply == "for me to see"){

   $action = "Quote me!";

}else{

   $action = "Leave me alone!";

}

Link to comment
Share on other sites

Link to post
Share on other sites

11 minutes ago, jameshumphries47 said:

1) im not too worried on sanitizing inputs as its just so my parents can upload files to their website. although i will implement this when i have time.

Always worry about sanitizing inputs. It doesn't matter who you expect to use it, for a start anyone could submit a form to your code above and it would run.

 

If you are using any code in a production environment it should be secure.

Link to comment
Share on other sites

Link to post
Share on other sites

19 minutes ago, Brenz said:

Always worry about sanitizing inputs. It doesn't matter who you expect to use it, for a start anyone could submit a form to your code above and it would run.

 

If you are using any code in a production environment it should be secure.

yes i mean my parents have a small site there is no way to access this code unless you have logged on so as far as im aware its near impossible to get into this page without being logged in with a certain user. but i'll impliment this at some point. i am pretty busy for the next week but hopefully do it after.

Check out my current projects: Selling site (Click Here)

If($reply == "for me to see"){

   $action = "Quote me!";

}else{

   $action = "Leave me alone!";

}

Link to comment
Share on other sites

Link to post
Share on other sites

Use prepared statements as it's much easier to handle (at least for me) when looking at sql queries and you're less likely be vulnerable to sql injection. More info can be obtained on the stackexchange networks or similar: https://stackoverflow.com/questions/134099/are-pdo-prepared-statements-sufficient-to-prevent-sql-injectionhttps://stackoverflow.com/questions/60174/how-can-i-prevent-sql-injection-in-php

Link to comment
Share on other sites

Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×