0

I am trying to create a function where a user can edit a preexisting post. When the user is taken to edit.php, they are presented with a form that shows them the existing data associated with that post. They can then make changes to any of the fields (description, category, add additional images, etc.) and, upon hitting a submit button, the updated information will show on the post page.

My issue with this is actually getting it to update the information. The form will show up with the preexisting info, and I can make changes to any of the fields. However, when I press submit, I am taken to the list of posts, yet the changes I made have not been updated in the SQL table.

There aren't any errors that are being returned upon hitting submit. Everything is running smoothly except for the fact things aren't actually being updated in the database.

I have been looking on several different sites for help on the matter, and I have tried several variations of my UPDATE query thinking that maybe I am calling it incorrectly. This is the iteration I am currently working with after attempting several other examples I found:

if($title && $price && $description && $category){
    $editquery = "UPDATE post SET title='$title', price='$price', description='$description', category='$category' WHERE post_id='$id'";
    $edquery = $db->prepare($editquery);
    $edquery->bind_result("ssss", $title, $price, $description, $category);
    $edquery->execute();
    if($edquery){
      echo "Updated!";
    }else{
      echo "error";
    }
  }else{
    echo "missing data";
  }

I am fairly new to PHP, so it is very possible that I am making simple syntax errors that I am not noticing. Or it could be some other portion of my code that I am not executing properly. If anyone could have a look at my code and help point me in the right direction, I would greatly appreciate it.

Also, I would like to add that yes, I know my code is vulnerable to injection. My only concern right now is getting this function to work. Any security measures I will deal with after getting this to work.

PHP

<?php

if(!isset($_GET['id'])){
  header('Location: modify.php');
  exit();
}else{
  $id = $_GET['id'];
}

include('../includes/db_connect.php');

if(!is_numeric($id)){
  header('Location: inventory.php');
}

if(isset($_POST['submit'])){

  $title = $_POST['title'];
  $price = $_POST['price']; 
  $description = $_POST['description'];
  $category = $_POST['category'];
  $title = $db->real_escape_string($title);
  $price = $db->real_escape_string($price);
  $description = $db->real_escape_string($description);

     if($title && $price && $description && $category){
    $editquery = "UPDATE post SET title='$title', price='$price', description='$description', category='$category' WHERE post_id='$id'";
    $edquery = $db->prepare($editquery);
    $edquery->bind_result("ssss", $title, $price, $description, $category);
    $edquery->execute();
    if($edquery){
      echo "Updated!";
    }else{
      echo "error";
    }
  }else{
    echo "missing data";
  }

    $postid = $db->insert_id;

  for($i=0; $i<count($_FILES["images"]["name"]); $i++)
  {
   $filetmp = $_FILES["images"]["tmp_name"][$i];
   $filename = $_FILES["images"]["name"][$i];
   $filetype = $_FILES["images"]["type"][$i];
   $filepath = "images/".$filename;

   move_uploaded_file($filetmp, $filepath);

   $sql = "INSERT INTO images (img_name, img_path, img_type, post_id) VALUES 
   ('$filename', '$filepath', '$filetype', '$postid')";
   $result = mysqli_query($db, $sql);
  }
 }        


?>

The HTML form This is the only portion of the HTML that pertains to this function.

        <form action="<?php echo $_SERVER['PHP_SELF']?>" method="POST" enctype="multipart/form-data">
              <?php

              $editsql = "SELECT * FROM post INNER JOIN categories ON categories.category_id=post.category_id WHERE post_id=' ".$id." '";
              $editquery = $db->query($editsql);
              if($editquery->num_rows !=1){
                header('Location: inventory.php');
                exit();
              }

              $editrow = $editquery->fetch_object();

              echo "<div class='form-group'>";
                  echo "<label>Title*</label>";
                  echo "<input type='text' name='title' class='form-control' value='".$editrow->title."' required>";
              echo "</div>";
              echo "<div class='form-group'>";
                  echo "<label>Price*</label>";
                  echo "<input type='text' name='price' class='form-control' value='".$editrow->price."'required>";
              echo "</div>";
              echo "<div class='form-group'>";
                  echo "<label>Category</label>";
                  echo "<select name='category' class='form-control'>";
                                echo "<option value='".$editrow->category_id."'>".$editrow->category."</option>";
                                $catquery = $db->query("SELECT * FROM categories");
                                while($row = $catquery->fetch_object()){
                                  echo "<option value='".$row->category_id."'>".$row->category."</option>";
                                }             
                   echo "</select>";
              echo "</div>";

              echo "<div class='form-group'>";
                  echo "<label>Description*</label>";
                  echo "<textarea type='textarea' name='description' class='form-control' required>".$editrow->description."</textarea>";
              echo "</div>";
              echo "<div class='form-group'>";
                  echo "<label>Image(s)</label>";
                  echo "<input type='hidden' name='size' value='1000000'>";
                  echo "<input multiple='multiple' name='images[]' type='file'/>";
              echo "</div>";
              echo "<div class='required'>";
                  echo "* indicates a required field";
              echo "</div>";
              echo "<button type='submit' name='submit' value='submit' class='btn btn-default'>EDIT POST</button>"
              ?>
        </form>

EDIT

Whatever is happening with my code, I am unable to see any of the echoed statements after I press 'submit':

    if($query){
      echo "product updated";
    }else{
      echo "error";
    }
  }else{
    echo "missing data";
  }

Could it be possible that this is causing an issue?

if(!isset($_GET['id'])){
  header('Location: modify.php');
  exit();
}else{
  $id = $_GET['id'];
}

Or that I need to use a hidden input along with this?

echo "<button type='submit' name='submit' value='submit' class='btn btn-default'>EDIT POST</button>"

EDIT 2

I've separated this into two files (edit.php and submitedit.php) to keep the $_GET and $_POST separated from one another. However, I am still experiencing the same issue where the database will not update.

edit.php I'm only showing the PHP and relevant HTML form

<?php
session_start();
$msg = "";

if(!isset($_GET['id'])){
  header('Location: delete.php');
  exit();
}else{
  $id = $_GET['id'];
}

include('../includes/db_connect.php');

if (!isset($_SESSION['user_id'])) {
  header('Location: login.php');
  exit();
}

if(!is_numeric($id)){
  header('Location: inventory.php');
}

?>

<!-- WHERE THE HTML STARTS -->

 <form action="submitedit.php" method="POST" enctype="multipart/form-data">
                  <?php

                  $editsql = "SELECT * FROM post INNER JOIN categories ON categories.category_id=post.category_id WHERE post_id='$id'";
                  $editquery = $db->query($editsql);
                  if($editquery->num_rows !=1){
                    header('Location: inventory.php');
                    exit();
                  }

                  $editrow = $editquery->fetch_object();

                  echo "<div class='form-group'>";
                      echo "<label>Title*</label>";
                      echo "<input type='text' name='title' class='form-control' value='".$editrow->title."' required>";
                  echo "</div>";
                  echo "<div class='form-group'>";
                      echo "<label>Price*</label>";
                      echo "<input type='text' name='price' class='form-control' value='".$editrow->price."'required>";
                  echo "</div>";
                  echo "<div class='form-group'>";
                      echo "<label>Category</label>";
                      echo "<select name='category' class='form-control'>";
                                    echo "<option value='".$editrow->category_id."'>".$editrow->category."</option>";
                                    $catquery = $db->query("SELECT * FROM categories");
                                    while($row = $catquery->fetch_object()){
                                      echo "<option value='".$row->category_id."'>".$row->category."</option>";
                                    }             
                       echo "</select>";
                  echo "</div>";

                  echo "<div class='form-group'>";
                      echo "<label>Description*</label>";
                      echo "<textarea type='textarea' name='description' class='form-control' required>".$editrow->description."</textarea>";
                  echo "</div>";
                  echo "<div class='form-group'>";
                      echo "<label>Image(s)</label>";
                      echo "<input type='hidden' name='size' value='1000000'>";
                      echo "<input multiple='multiple' name='images[]' type='file'/>";
                  echo "</div>";
                  echo "<div class='required'>";
                      echo "* indicates a required field";
                  echo "</div>";
                  echo "<button type='submit' name='submit' value='submit' class='btn btn-default'>EDIT POST</button>"
                  ?>


                </form>

submitedit.php

<?php


if(!isset($_POST['id'])){
  header('Location: delete.php');
  exit();
}else{
  $id = $_POST['id'];

include('../includes/db_connect.php');


if(isset($_POST['submit'])){

  $title = $_POST['title'];
  $price = $_POST['price']; 
  $description = $_POST['description'];
  $category = $_POST['category'];
  $title = $db->real_escape_string($title);
  $price = $db->real_escape_string($price);
  $description = $db->real_escape_string($description);



     if($title && $price && $description && $category){
    $editquery = "UPDATE post SET title='$title', price='$price', description='$description', category='$category' WHERE post_id='$id'";
    $edquery = $db->prepare($editquery);
    $edquery->bind_result("ssss", $title, $price, $description, $category);
    $edquery->execute();
    if($edquery){
      echo "Updated!";
    }else{
      echo "error";
    }
  }else{
    echo "missing data";
  }

  $postid = $db->insert_id;

  for($i=0; $i<count($_FILES["images"]["name"]); $i++)
  {
    $filetmp = $_FILES["images"]["tmp_name"][$i];
    $filename = $_FILES["images"]["name"][$i];
    $filetype = $_FILES["images"]["type"][$i];
    $filepath = "images/".$filename;

    move_uploaded_file($filetmp, $filepath);

    $sql = "INSERT INTO images (img_name, img_path, img_type, post_id) VALUES ('$filename', '$filepath', '$filetype', '$postid')";
    $result = mysqli_query($db, $sql);
  }
}        

?>
Vel
  • 69
  • 7
  • 1
    Are you sure the `id` you are using in the where clause is correct? Try removing the where clause as a test, please note this will update all records for testing purposes – Tjaart van der Walt Feb 14 '18 at 05:26
  • 2
    use parameterized query to prevent SQL injection. That will help you to make more secure query – Pankaj Makwana Feb 14 '18 at 05:30
  • change your update query with this one and try. $query = $db->query("UPDATE post SET `title`='$title', `price`='$price', `description`='$description', `category`='$category' WHERE `post_id`='$id'"); – Priyank Feb 14 '18 at 05:51
  • @TjaartvanderWalt Thanks for catching that. I tried removing it and still no luck with actually getting anything to update. – Vel Feb 14 '18 at 05:58
  • @Priyank I updated the query with `$id` rather than `$post_id` and I am still running into the same issue of nothing actually updating. – Vel Feb 14 '18 at 05:59
  • did you add tilt in all the fields ? or remove only description from your query and check – Priyank Feb 14 '18 at 06:01
  • @Priyank Tilt? I'm unfamiliar with that. Unless it was a typo for 'title', which in that case, I only have 'title' in the field for the title. `echo "";` If that's what you mean. And I tried removing only the description from the query without any luck. – Vel Feb 14 '18 at 06:13
  • i have added tilt here but somehow it is not visible here ( tilt is first key and below the esc key ) – Priyank Feb 14 '18 at 06:18
  • @Priyank oh! Okay! So the squiggle (tilde) character then? I don't have that character in any of my fields. – Vel Feb 14 '18 at 06:27
  • post_id='$id'"; should be this post_id=' ".$id." ' "; – briskovich Feb 14 '18 at 18:55
  • @briskovich Alright, I changed that. I'm not sure if it has any immediate effect on my function since it still isn't updating. – Vel Feb 14 '18 at 18:59
  • Well that would cause your query to return nothing. – briskovich Feb 14 '18 at 19:07
  • change this line too - $editsql = "SELECT * FROM post INNER JOIN categories ON categories.category_id=post.category_id WHERE post_id='$id'"; to ...ERE post_id=' ".$id."'"; – briskovich Feb 14 '18 at 19:09
  • @briskovich Okay, I will go ahead and change that one as well. – Vel Feb 14 '18 at 19:15
  • 2
    Not your answer, but very important: Your code is vulnerable to [SQL Injection](https://stackoverflow.com/questions/332365/how-does-the-sql-injection-from-the-bobby-tables-xkcd-comic-work). Please fix it by using [prepared statements](http://php.net/manual/pt_BR/mysqli.quickstart.prepared-statements.php) – Elias Soares Feb 14 '18 at 20:47

1 Answers1

1

You send your form with POST method while you try to read id from GET array. Change it to $_POST['id'], and you're all set

ob-ivan
  • 785
  • 1
  • 8
  • 17
  • I changed it to `$_POST['id]` and if I do that, I cannot even access the page with the form. The `$_GET['id]` on the edit.php is there because to link to the edit page from each individual post, I am using `EDIT THIS POST'?> ` on the list of posts on another page. Unless I am misunderstanding on how this works, which is entirely possible. – Vel Feb 14 '18 at 21:36
  • Is there a reason to mix displaying the form and processing its submission in a single piece of code? Put those two disconnected take into two separate files, use `$_GET` in one and `$_POST` in another. – ob-ivan Feb 14 '18 at 22:01
  • I created two separate files to disconnect the `$_GET` and `$_POST` so they weren't existing in the same space. I updated my question with both of those under **EDIT 2**. I am still running into the same issue where the database is not being updated. Am I calling something incorrectly or missing anything? – Vel Feb 14 '18 at 22:33
  • 1
    Please have a closer look at the manual on prepared statements: http://php.net/manual/en/mysqli.quickstart.prepared-statements.php --- To prevent SQL injection you either escape all parameter values, or you use prepared statements, but not the both, or your input will end up double-escaped. To use prepared statements, you replace variable substitution (literal `$category`) with placeholders (like `:category`) in your query. Also please note the difference between `bind_param` and `bind_result`. The naming is similar, but the effect is quite the opposite! – ob-ivan Feb 15 '18 at 08:21