ApplicationError Posted January 22, 2013 Share Posted January 22, 2013 (edited) I have a list of news items in a database, and have a form to add/edit the comment. It all works fine.... loads the existing comment, saves a new comment (of changed comment), but it throws a really strange error message. I am sure it isn't strange for most here Fatal error: Call to a member function fetch_object() on a non-object in C:\wamp\www\NewsToolv1\GetEmAll_Comment.php on line 39 GetEmAll_Comment.php <?php $id = filter_input(INPUT_POST, 'id', FILTER_SANITIZE_STRING); $comment = filter_input(INPUT_POST, 'comment', FILTER_SANITIZE_STRING); $existing_comment = ''; // Check if the comment was set (posted) if(isset($comment)){ addComment($id, $comment); echo "record should be added"; } elseif (empty($comment)) { $existing_comment = checkForComment($id); } // Update the database with the new comment function addComment($id, $comment){ $db = new mysqli('localhost', 'root', '', 'newstoolv1'); $sql = "UPDATE tbl_news SET clmn_comment='".$comment."' WHERE id=".$id; $db->query($sql); $db->close(); // Go back to page $callingPage = $_SERVER['HTTP_REFERER']; header('location:' . $callingPage); } function checkForComment($id){ $db = new mysqli('localhost', 'root', '', 'newstoolv1'); $sql = "SELECT * FROM tbl_news WHERE id=".$id; $results = $db->query($sql); $db->close(); $r = ''; while($output_item = $results->fetch_object()){ $r = $output_item->clmn_comment; } return $r; } ?> <form class="form" method="POST" action="GetEmAll_Comment.php"> <input type="hidden" name="id" value="<?PHP echo $id;?>"> <textarea rows="1" cols="60" name="comment"><?PHP echo $existing_comment;?></textarea> <input type="submit" value="Submit"> </form> Edited January 22, 2013 by ApplicationError Quote Link to comment Share on other sites More sharing options...
requinix Posted January 22, 2013 Share Posted January 22, 2013 The only possible way I see that query failing is if the $id doesn't contain the right value. Echo out the $sql and see what's wrong. Quote Link to comment Share on other sites More sharing options...
TOA Posted January 22, 2013 Share Posted January 22, 2013 (edited) Yeah, you're query is failing. $id needs to be in wrapped in single quotes if used as a value in the WHERE...that's my guess. Edited January 22, 2013 by TOA Quote Link to comment Share on other sites More sharing options...
requinix Posted January 22, 2013 Share Posted January 22, 2013 $id needs to be in wrapped in single quotes if used as a value in the WHERE... Not if it's a number it doesn't. Numbers should never get quotes. Quote Link to comment Share on other sites More sharing options...
ApplicationError Posted January 22, 2013 Author Share Posted January 22, 2013 Interesting. Thanks for the feedback... (a) I don't understand why the addComment() function is called when I submit the form, as the $comment should be set - but maybe it isn't, but if it isn't then why does it update the value in the database (B) it looks like when I submit the form, indeed, the $id and $comment are not set... but if they are not set, then how is the new comment added/updated (it is infact updated in the database). Here a little code update... just tried to unset the $comment in one part, hoping it would help to not call addComment(). <?php $id = filter_input(INPUT_POST, 'id', FILTER_SANITIZE_STRING); $comment = filter_input(INPUT_POST, 'comment', FILTER_SANITIZE_STRING); echo $id; echo $comment; echo "----"; $existing_comment = ''; // Check if the comment was set (posted) if(isset($comment)){ addComment($id, $comment); echo "record should be added"; } elseif (empty($comment)) { $existing_comment = checkForComment($id); } // Update the database with the new comment function addComment($id, $comment){ $db = new mysqli('localhost', 'root', '', 'newstoolv1'); $sql = "UPDATE tbl_news SET clmn_comment='".$comment."' WHERE id=".$id; $db->query($sql); $db->close(); unset($comment); // Go back to page $callingPage = $_SERVER['HTTP_REFERER']; header('location:' . $callingPage); } function checkForComment($id){ $db = new mysqli('localhost', 'root', '', 'newstoolv1'); $sql = "SELECT * FROM tbl_news WHERE id=".$id; $results = $db->query($sql); $db->close(); $r = ''; while($output_item = $results->fetch_object()){ $r = $output_item->clmn_comment; } return $r; } ?> <form class="form" method="POST" action="GetEmAll_Comment.php"> <input type="hidden" name="id" value="<?PHP echo $id;?>"> <textarea rows="1" cols="60" name="comment"><?PHP echo $existing_comment;?></textarea> <input type="submit" value="Submit"> </form> Quote Link to comment Share on other sites More sharing options...
PFMaBiSmAd Posted January 22, 2013 Share Posted January 22, 2013 Your logic makes no sense. If $comment is not set (the point where your elesif test is at), I can guarantee that it will be empty, because the only way it can be non-empty is if it isset. I recommend that separate your form processing logic so that it is a distinct block of code and the only thing the form processing logic does is process any form data. Any other logic to get and display content on the page should be separate and distinct from your form processing logic. Quote Link to comment Share on other sites More sharing options...
ApplicationError Posted January 23, 2013 Author Share Posted January 23, 2013 Thank you for the help. Interesting, it seems as though the form post doesn't work, or the POST values are not captured. They show up as empty, in which case the SQL quey can't run correctly. I've tried to seperate the form code a bit. <?php $id = filter_input(INPUT_POST, 'id', FILTER_SANITIZE_STRING); // Gets passed in from GetEmAll.php via form POST // Gets passed form this file "GetEmAll_Comment.php" via form POST $id_form = filter_input(INPUT_POST, 'id_form', FILTER_SANITIZE_STRING); $comment_form = filter_input(INPUT_POST, 'comment_form', FILTER_SANITIZE_STRING); echo "id: ".$id."<br/>"; // echo "comment: ".$comment."<br/>"; echo "id_form: ".$id_form."<br/>"; echo "comment_form: ".$comment_form."<br/>"; // Check if the comment was set (posted) if(isset($comment_form) && isset($id_form)){ // if both $comment_form and $id_form are set it must be submitted from the form // if it is submitted from the form, update the database record addComment($id_form, $comment_form); echo "added: ".$comment_form." to ".$id."<br />"; } else { $existing_comment = checkForComment($id); } // Update the database with the new comment function addComment($id, $comment){ $db = new mysqli('localhost', 'root', '', 'newstoolv1'); $sql = "UPDATE tbl_news SET clmn_comment='".$comment."' WHERE id=".$id; $db->query($sql); $db->close(); // Go back to page $callingPage = $_SERVER['HTTP_REFERER']; header('location:' . $callingPage); } function checkForComment($id){ echo "checkForComment() Function<br/>"; echo "id: ".$id."<br/>"; $db = new mysqli('localhost', 'root', '', 'newstoolv1'); $sql = "SELECT * FROM tbl_news WHERE id=".$id; $results = $db->query($sql); $db->close(); echo "The SQL statement:<br/>"; echo "sql var: ".$sql."<br/>"; var_dump($results); $r = ''; while($output_item = $results->fetch_object()){ // $r = $output_item->clmn_comment; echo "Output from DB".$output_item->clmn_comment."<br/>"; } /* return $r; */ } ?> <form class="form" method="POST" action="GetEmAll_Comment.php"> <input type="hidden" name="id_form" value="<?PHP echo $id;?>"> <textarea rows="1" cols="60" name="comment_form"><?PHP echo $existing_comment;?></textarea> <input type="submit" value="Submit"> </form> Quote Link to comment Share on other sites More sharing options...
dodgeitorelse3 Posted January 23, 2013 Share Posted January 23, 2013 (edited) $sql = "UPDATE tbl_news SET clmn_comment='".$comment."' WHERE id=".$id; seems to me that the where clause has a beginning ". but no ending ." and sql statement starts with " and has no closing " Edited January 23, 2013 by dodgeitorelse3 Quote Link to comment Share on other sites More sharing options...
Jessica Posted January 23, 2013 Share Posted January 23, 2013 That's fine, it's a string. There's absolutely no problem with that. Quote Link to comment Share on other sites More sharing options...
ApplicationError Posted January 23, 2013 Author Share Posted January 23, 2013 This problem is killing me. I could post to yet another PHP file and I think it would work. Quote Link to comment Share on other sites More sharing options...
Jessica Posted January 23, 2013 Share Posted January 23, 2013 Does it work if you just use $_POST without filtering it? Start simple and then add stuff, one bit at a time, until it breaks. Quote Link to comment Share on other sites More sharing options...
ApplicationError Posted January 24, 2013 Author Share Posted January 24, 2013 Does it work if you just use $_POST without filtering it? Start simple and then add stuff, one bit at a time, until it breaks. Thanks, no luck. It is a problem with posting to itself somehow. Really strange, but probably just a logic problem. Quote Link to comment Share on other sites More sharing options...
Christian F. Posted January 24, 2013 Share Posted January 24, 2013 I've cleaned up your code a bit, to make it easier to read and flow better. In addition to adding some comments on stuff that I've changed, and stuff you need to change yourself. <?php // CF: Connect to the DB outside of the functions, and do not manually // close the connection. PHP does that just fine on its own. $db = new mysqli ('localhost', 'root', '', 'newstoolv1'); // Gets passed in from GetEmAll.php via form POST $id = filter_input (INPUT_POST, 'id', FILTER_SANITIZE_STRING); // Gets passed form this file "GetEmAll_Comment.php" via form POST $id_form = filter_input (INPUT_POST, 'id_form', FILTER_SANITIZE_STRING); $comment_form = filter_input (INPUT_POST, 'comment_form', FILTER_SANITIZE_STRING); echo "id: " . $id . "<br/>"; // echo "comment: ".$comment."<br/>"; echo "id_form: " . $id_form . "<br/>"; echo "comment_form: " . $comment_form . "<br/>"; // Check if the comment was set (posted) // CF: These will _always_ be set, as you just set them above. Use empty () instead. if (isset ($comment_form) && isset ($id_form)) { // if both $comment_form and $id_form are set it must be submitted from the form // if it is submitted from the form, update the database record addComment ($db, $id_form, $comment_form); // CF: You won't see this, because of the redirect in the function. echo "added: " . $comment_form . " to " . $id . "<br />"; } else { $existing_comment = checkForComment ($db, $id); echo $existing_comment; } // Update the database with the new comment function addComment ($db, $id, $comment) { // TODO: Add output escaping to prevent against SQL injections. $sql = "UPDATE tbl_news SET clmn_comment='" . $comment . "' WHERE id=" . $id; // TODO: Check for SQL errors. $db->query ($sql); // Go back to page // TODO: This won't work for users who don't set the referrer, which many doesn't. // You already know what the previous page is, as you've structured the code, // so set address manually. $callingPage = $_SERVER['HTTP_REFERER']; header ('location:' . $callingPage); // CF: Always use die after a header redirect. die (); } function checkForComment ($db, $id) { $output = "checkForComment() Function<br/>"; $output .= "id: " . $id . "<br/>"; // TODO: Typecast $id to an integer, to prevent SQL injections. $sql = "SELECT * FROM tbl_news WHERE id=" . $id; // TODO: Check for SQL errors. $results = $db->query ($sql); $output .= "The SQL statement:<br/>"; $output .= "sql var: " . $sql . "<br/>"; var_dump ($results); while ($output_item = $results->fetch_object ()) { // $r = $output_item->clmn_comment; $output .= "Output from DB" . $output_item->clmn_comment . "<br/>"; } return $output; } ?> <form class="form" method="POST" action=""> <input type="hidden" name="id_form" value="<?php echo $id; ?>"> <textarea rows="1" cols="60" name="comment_form"> <?php echo $existing_comment; ?> </textarea> <input type="submit" value="Submit"> </form> Quote Link to comment Share on other sites More sharing options...
ApplicationError Posted January 24, 2013 Author Share Posted January 24, 2013 Finally, I got it to work. It was this code that caused the problem: // Go back to page $callingPage = $_SERVER['HTTP_REFERER']; header('location:' . $callingPage); Having figured it out, it makes sense. After GetEmAll_comment.php posted to itself to add the comment, it went back to GetEmAll_comment.php, but at that time there was nothing to post. The code was supposed to push it back to GetEmAll.php. So here is the working code <?php // Gets passed in from GetEmAll.php via form POST $id = filter_input(INPUT_POST, 'id', FILTER_SANITIZE_STRING); // Gets passed form this file "GetEmAll_Comment.php" via form POST $id_form = filter_input(INPUT_POST, 'id_form', FILTER_SANITIZE_STRING); $comment_form = filter_input(INPUT_POST, 'comment_form', FILTER_SANITIZE_STRING); $callingPage = filter_input(INPUT_POST, 'callingPage_form', FILTER_SANITIZE_STRING); // Output for debugging problem echo "id from GetEmAll.pgp: ".$id."<br/><br/>"; echo "id_form set from this file: ".$id_form."<br/>"; echo "comment_form set from this file: ".$comment_form."<br/>"; $existing_comment = ''; // needs to be defined atleast. // Check if the comment was set (posted) if(isset($comment_form) && isset($id_form)){ // if both $comment_form and $id_form are set it must be submitted from the form // if it is submitted from the form, update the database record addComment($id_form, $comment_form, $callingPage); echo "added: ".$comment_form." to ".$id."<br />"; } elseif (isset($id)) { $existing_comment = checkForComment($id); $callingPage = $_SERVER['HTTP_REFERER']; } elseif (empty($id_form)) { echo 'id_form is empty <br/>'; } // Update the database with the new comment function addComment($id, $comment, $callingPage){ $db = new mysqli('localhost', 'root', '', 'newstoolv1'); $sql = "UPDATE tbl_news SET clmn_comment='".$comment."' WHERE id=".$id; $db->query($sql); $db->close(); // Go back to page header('location:' . $callingPage); } function checkForComment($id){ echo "<br/><br/>checkForComment() Function<br/>"; echo "id: ".$id."<br/><br/>"; $db = new mysqli('localhost', 'root', '', 'newstoolv1'); $sql = "SELECT * FROM tbl_news WHERE id=".$id; $results = $db->query($sql); $db->close(); echo "The SQL statement:<br/>"; echo "sql var: ".$sql."<br/>"; // var_dump($results); $r = ''; while($output_item = $results->fetch_object()){ $r = $output_item->clmn_comment; // echo "Output from DB".$output_item->clmn_comment."<br/>"; } return $r; } ?> <form class="form" method="POST" action="GetEmAll_Comment.php"> <input type="hidden" name="id_form" value="<?PHP echo $id;?>"> <input type="hidden" name="callingPage_form" value="<?PHP echo $callingPage;?>"> <textarea rows="1" cols="60" name="comment_form"><?PHP echo $existing_comment;?></textarea> <input type="submit" value="Submit"> </form> Quote Link to comment Share on other sites More sharing options...
ApplicationError Posted January 24, 2013 Author Share Posted January 24, 2013 I've cleaned up your code a bit, to make it easier to read and flow better. In addition to adding some comments on stuff that I've changed, and stuff you need to change yourself. Wow, this is great. Thank you. I posted right before/after you, I've got it to work... but all your comments are awesome. I am going to do that right now!!! Thank you!!! Quote Link to comment Share on other sites More sharing options...
ApplicationError Posted January 24, 2013 Author Share Posted January 24, 2013 Quick question.... when I move the $db out of the function.... I get an error. Notice: Undefined variable: db... Same when I try to set it to a global... global $db; Quote Link to comment Share on other sites More sharing options...
Christian F. Posted January 24, 2013 Share Posted January 24, 2013 Notice that I pass the $db variable when calling the functions, and that I've defined it as a parameter in the function definition. You'll need to do both. Though the name internally in the function can be something completely different than what it is outside of the function, I've decided to keep the same name since it describes the contents the best. (Also, didn't have to rename the variables inside of the function either.) You do not want to use the global keyword inside your functions. In all my years (12+, btw) of programming, there's only been one instance where I found it useful. The rest of the time it was just creating issues, by hiding the dependencies between functions and the data. Quote Link to comment Share on other sites More sharing options...
ApplicationError Posted January 24, 2013 Author Share Posted January 24, 2013 Notice that I pass the $db variable when calling the functions, and that I've defined it as a parameter in the function definition. You'll need to do both. Though the name internally in the function can be something completely different than what it is outside of the function, I've decided to keep the same name since it describes the contents the best. (Also, didn't have to rename the variables inside of the function either.) You do not want to use the global keyword inside your functions. In all my years (12+, btw) of programming, there's only been one instance where I found it useful. The rest of the time it was just creating issues, by hiding the dependencies between functions and the data. Ah yes, sorry, I missed that. Thank you... now to do that to all my code Quote Link to comment Share on other sites More sharing options...
Christian F. Posted January 24, 2013 Share Posted January 24, 2013 You're welcome, glad I could help. Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.