1

For school I'm working on creating a website that sells animals. We're required to have an adminpage that enables owners to add, edit and delete animals on the site. We've made it possible to add animals, but I can't seem to get editing the existing ones working. I'm also not really experienced in PHP. I've added a couple of checks to see if the statement is being executed, and once i fill in the form and click submit it tells me 'donedone', which should mean it worked - but the table remains the same. Could someone shed some light on what might be the problem I'm facing? This is the first time I've asked something via SO.

edit1: Instead of the "where animal_id = ':animal_id'" i tried it with only animal no. 33, and instead of the values i entered in my form, it replaces all the values with ':class' and ':price' etc. So something must be wrong in binding the form values to the 'insert into' stmt.

This is the database connection

<?php

$server = 'localhost';
username = 'username';
$password = '*********';
$database = 'databasename';

$conn = new PDO("mysql:host=$server;dbname=$database;", $username,  $password);

?>

and this is the edit_animal file:

<?php

session_start();

if( isset($_SESSION['user']) ){
  header("Location: /");
}

ini_set('display_errors', '0');   
error_reporting(E_ALL | E_STRICT);

require 'database.php';

$message = '';

 if(!empty($_POST['animal_name']) && !empty($_POST['official_name']) &&    !empty($_POST['average_lifespan']) && !empty($_POST['length']) && !empty($_POST['class']) && !empty($_POST['housing']) && !empty($_POST['animal_price']) && !empty($_POST['diet']) && !empty($_POST['description'])):

$sql = "UPDATE animal_test SET animal_name =':animal_name', animal_price =  ':animal_price', official_name =':official_name', average_lifespan = ':average_lifespan' , length =':length' , class =':class', housing = ':housing',  description=':description', diet =':diet' WHERE animal_id =':animal_id'";
  $stmt = $conn->prepare($sql);

  $stmt->bindParam(':animal_id', $_POST['animal_id']);
  $stmt->bindParam(':animal_name', $_POST['animal_name']);
  $stmt->bindParam(':official_name', $_POST['official_name']);
  $stmt->bindParam(':average_lifespan', $_POST['average_lifespan']);
  $stmt->bindParam(':length', $_POST['length']);
  $stmt->bindParam(':class', $_POST['class']);
  $stmt->bindParam(':housing', $_POST['housing']);
  $stmt->bindParam(':animal_price', $_POST['animal_price']);
  $stmt->bindParam(':description', $_POST['description']);
  $stmt->bindParam(':diet', $_POST['diet']);
  $result = $stmt->execute();

  if (!$stmt) {
    echo "Jammer";
  }
  if( $stmt){
   echo "done";
 }
 if ($result) {
  echo "done";
 }
  else{
    $message = 'Sorry there must have been an issue with editing your  animale';

}

endif;

?>

<!DOCTYPE html>
<html>
    <head>
        <title>Admin - Exotic Animal Shop</title>
        <link rel="stylesheet" type="text/css" href="admin_page.css">
    </head>
    <body>         

        <h2>Add a product</h2>

        <form action="<?php echo $_SERVER['PHP_SELF']; ?>"method="POST">



          <div class=add_product_div>

            <div id=animal_name_div>
              <p>Animal name</p>
              <input id=animal_name type="text" placeholder="Animal name" name="animal_name">
            </div>

            <div id=animal_id_div>
              <p>Animal ID</p>
              <input id=animal_id type="number" placeholder="Animal ID" name="animal_id" min="0">
            </div>

            <div id=price_div>
              <p>Price</p>
              <input id=animal_price type="number" placeholder="Price" name="animal_price" min="0">
            </div>

            <div id=official_name_div>
              <p>Official name</p>
              <input id=official_name type="text" placeholder="Official name" name="official_name">
            </div>

            <div id=current_age_div>
              <p>Average lifespan</p>
              <input id=average_lifespan type="text" placeholder="Average lifespan" name="average_lifespan">
            </div>
          </div>


          <div class=add_product_div>

            <div id=length_div>
              <p>Max length</p>
              <input id=length type="text" placeholder="Max length" name="length">
            </div>

            <div id=class_div>
              <p>Class</p>
              <input id=class type="text" placeholder="Class" name="class">
            </div>

            <div id=housing_div>
              <p>Housing</p>
              <input id=housing type="text" placeholder="Housing" name="housing">
            </div>

            <div id=animal_diet>
              <p>Diet</p>
              <input id=diet type="text" placeholder="Diet" name="diet">
            </div>
          </div>

            <div class=add_product_div>
              <p>Description</p>
              <textarea placeholder="Description" id="description" name="description" rows="20" cols="40"></textarea>
            </div>


            <div id=submit_div>
              <input id=submit type="submit" value="Submit">
            </div>

        </form>
        <form action="upload.php" method="post" enctype="multipart/form-data">
          <p>Select image to upload</p>
          <input type="file" name="userfile" id="userfile">
          <input type="submit" value="Upload Image" name="submit">
        </form>
</body>

Engelbert
  • 19
  • 3
  • 1
    PDO doesn't throw exceptions by default, you need to configure it explicitly. – Álvaro González Jan 27 '17 at 12:54
  • 1
    not sure, but remove the quotes around `WHERE animal_id =':animal_id'` so it will become `WHERE animal_id =:animal_id` – marmeladze Jan 27 '17 at 12:56
  • You don't need to add single quotes in your query (`$sql`), and it looks you added too much spaces sometimes. Also, preparing with `value = :myvalue` let you execute by using an array. Theses advices will just clear and lighten your code – AymDev Jan 27 '17 at 12:58
  • @marmeladze I tried that, but sadly it doesn't work and I also only receive one echo with 'done', which I guess mean the stmt isnt executed. – Engelbert Jan 27 '17 at 13:10
  • $stmt will not be false unless you set it to, so if($stmt) will always be held, i believe (need to check). btw, have you set $conn to null? – marmeladze Jan 27 '17 at 13:18
  • @marmeladze thanks for responding. I tried to $conn = null, but this didn't alter my output. Could you elaborate the $stmt will always be held part? – Engelbert Jan 27 '17 at 13:27
  • 1
    PDO Error handling read here-> https://phpdelusions.net/pdo#errors – Masivuye Cokile Jan 27 '17 at 13:41
  • what does your error log says? – Masivuye Cokile Jan 27 '17 at 13:41
  • look the last line of that paste. as you are masking errors, you are not aware of that, $stmt is always boolean true, regardless the query executed or not. http://pastebin.com/SBxaSYdN – marmeladze Jan 27 '17 at 13:49
  • No `exit;` after header redirect. – Daniel W. Jan 27 '17 at 15:37
  • @Englebert I've added an answer for you to refer to. Classes are your friend with PDO I strongly suggest using them and getting used to them as they're extremely helpful! – Option Jan 27 '17 at 15:43

1 Answers1

0

Your prepared statement shouldn't have "'" marks around the replacement fields.

See reference here.

Change it to something akin to this:

$sql = "UPDATE animal_test SET animal_name =:animal_name, 
  animal_price =  :animal_price, official_name =:official_name, 
  average_lifespan = :average_lifespan , length =:length,
  class =:class, housing = :housing,  description=:description,
  diet =:diet WHERE animal_id =:animal_id";

Another solution would be to use positional placeholders ("?") and bindParam by number. See reference here.

$sql = "UPDATE animal_test SET animal_name =?, 
  animal_price =  ?, official_name =?, 
  average_lifespan = ?, length =?,
  class =?, housing = ?,  description=?,
  diet = ? WHERE animal_id = ?";

$stmt->bindParam(1, $_POST['animal_name']);
$stmt->bindParam(2, $_POST['animal_price']);

... and so on
ethrbunny
  • 10,379
  • 9
  • 69
  • 131
  • Thanks for your respond. When i try this, I only get one 'done', so the $stmt isn't being executed. However, when I don't do this, i get the values ':class', ':value' etc. in my table instead of the user-submitted info from the forms. So somehow the info which is put in the text fields is not saved.. I'll try your second solution right now, didn't see it at first. – Engelbert Jan 27 '17 at 14:05
  • Change one of the 'done' prints to something else - hard to know which you are seeing. Also - $stmt will always be 'true' - not really a useful test. Also (again) - do a var_dump($_POST) to make sure you are sending valid values from your form. – ethrbunny Jan 27 '17 at 14:18
  • Your second solution; changing the :values to '?' and ordering the bindparams seemed to have worked. Thanks so much, you're a legend. – Engelbert Jan 27 '17 at 14:21
  • k. Last step(s) - accept the answer...and be well. – ethrbunny Jan 27 '17 at 14:50