Jump to content


Photo

Problem with "strange" but simple issue... simpel for some, not me :)


  • Please log in to reply
18 replies to this topic

#1 ApplicationError

ApplicationError

    Newbie

  • New Members
  • Pip
  • 9 posts

Posted 21 January 2013 - 07:28 PM

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 by ApplicationError, 21 January 2013 - 07:29 PM.


#2 requinix

requinix

    Transforming Moderator

  • Moderators
  • 6,136 posts
  • LocationWA

Posted 21 January 2013 - 07:39 PM

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.

#3 TOA

TOA

    Devil's Advocate

  • Members
  • PipPipPip
  • 621 posts
  • LocationMinnesota, U.S.A

Posted 21 January 2013 - 07:44 PM

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 by TOA, 21 January 2013 - 07:45 PM.

Ordo Ab Chao
Insanity: doing the same thing over and over again and expecting different results - Einstein

#4 requinix

requinix

    Transforming Moderator

  • Moderators
  • 6,136 posts
  • LocationWA

Posted 21 January 2013 - 08:16 PM

$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.

#5 ApplicationError

ApplicationError

    Newbie

  • New Members
  • Pip
  • 9 posts

Posted 22 January 2013 - 08:07 AM

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>


#6 PFMaBiSmAd

PFMaBiSmAd

    Advanced Member

  • Staff Alumni
  • 16,767 posts
  • LocationColorado, U.S.A.

Posted 22 January 2013 - 08:50 AM

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.
Signature: (not a comment about anything you posted unless specifically indicated)
Debugging step #1: To get past the garbage-out equals garbage-in stage in your code, you must check that the inputs to your code are what you expect.

Programming is just problem solving, but it is done in another language. You must learn enough of the programming language you are using to be able to read and write code.

#7 ApplicationError

ApplicationError

    Newbie

  • New Members
  • Pip
  • 9 posts

Posted 22 January 2013 - 08:52 PM

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>


#8 dodgeitorelse3

dodgeitorelse3

    Advanced Member

  • Members
  • PipPipPip
  • 44 posts

Posted 23 January 2013 - 07:08 AM

$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 by dodgeitorelse3, 23 January 2013 - 07:10 AM.


#9 Jessica

Jessica

    This is not my name.

  • Gurus
  • 8,982 posts
  • LocationDallas, TX
  • Age:26

Posted 23 January 2013 - 07:42 AM

That's fine, it's a string. There's absolutely no problem with that.
My goal in replying to posts is to help you become a better programmer, including learning how to debug your own code and research problems. For that reason, rather than posting the solution, I reply with tips and hints on how to find the solution yourself. See below for useful links when you get stuck.

How to Get Good Help: How to Ask Questions | Don't be a help vampire
Debugging Your Code: Debugging your SQL | What does a php function do? | What does a term mean? | Don't see any errors?
Things You Should Do: Normalize Your Data | use print_r() or var_dump()
Lulz: "Functions should not have side effects." - trq

Please take a look at my new PHP/Web Dev blog: The Web Mason - Thanks!!

#10 ApplicationError

ApplicationError

    Newbie

  • New Members
  • Pip
  • 9 posts

Posted 23 January 2013 - 02:25 PM

This problem is killing me. I could post to yet another PHP file and I think it would work.

#11 Jessica

Jessica

    This is not my name.

  • Gurus
  • 8,982 posts
  • LocationDallas, TX
  • Age:26

Posted 23 January 2013 - 02:33 PM

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.
My goal in replying to posts is to help you become a better programmer, including learning how to debug your own code and research problems. For that reason, rather than posting the solution, I reply with tips and hints on how to find the solution yourself. See below for useful links when you get stuck.

How to Get Good Help: How to Ask Questions | Don't be a help vampire
Debugging Your Code: Debugging your SQL | What does a php function do? | What does a term mean? | Don't see any errors?
Things You Should Do: Normalize Your Data | use print_r() or var_dump()
Lulz: "Functions should not have side effects." - trq

Please take a look at my new PHP/Web Dev blog: The Web Mason - Thanks!!

#12 ApplicationError

ApplicationError

    Newbie

  • New Members
  • Pip
  • 9 posts

Posted 24 January 2013 - 06:55 AM

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.

#13 Christian F.

Christian F.

    Advanced Member

  • Staff Alumni
  • 3,106 posts
  • LocationNorway

Posted 24 January 2013 - 07:29 AM

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>

Keeping it simple.

#14 ApplicationError

ApplicationError

    Newbie

  • New Members
  • Pip
  • 9 posts

Posted 24 January 2013 - 07:40 AM

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>


#15 ApplicationError

ApplicationError

    Newbie

  • New Members
  • Pip
  • 9 posts

Posted 24 January 2013 - 07:43 AM

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!!!



#16 ApplicationError

ApplicationError

    Newbie

  • New Members
  • Pip
  • 9 posts

Posted 24 January 2013 - 07:47 AM

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;

#17 Christian F.

Christian F.

    Advanced Member

  • Staff Alumni
  • 3,106 posts
  • LocationNorway

Posted 24 January 2013 - 08:02 AM

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.
Keeping it simple.

#18 ApplicationError

ApplicationError

    Newbie

  • New Members
  • Pip
  • 9 posts

Posted 24 January 2013 - 08:08 AM

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 :)

#19 Christian F.

Christian F.

    Advanced Member

  • Staff Alumni
  • 3,106 posts
  • LocationNorway

Posted 24 January 2013 - 08:22 AM

You're welcome, glad I could help. :)
Keeping it simple.




0 user(s) are reading this topic

0 members, 0 guests, 0 anonymous users

Cheap Linux VPS from $5
SSD Storage, 30 day Guarantee
1 TB of BW, 100% Network Uptime

AlphaBit.com