-1

I am very new to the subject of PHP and SQL working together and I have been fine so far except for updating a database row on my SQL database. I'm using parts of my lecturers code and doing exercises and my own tasks to modify the webpages and behaviour.

The purpose of this code is to update an article that I have set up, so I can edit the title or the code then click confirm but when I do this I get my failed return message telling me that it failed to bind my parameters. I have often had trouble passing parameters in other languages and I have been looking and testing this for hours that I am hoping to receive some information and guidance on the subject.

All I want to do is update the articletext and articletitle fields. On the database there is another 3 fields blogID, blogtime, blogposter which don't need changing.

If you look at RESULT at the bottom you will see that the variables do have information but are not being updated to the database instead the process crashes during the bind_param section.


My EDIT ARTICLE code section:

<?php
$db=createConnection();
// get the first two articles
$sql = "select blogID,articletitle,articletext,blogtime,
                    blogposter,username,userid 
        from blogarticle 
            join registerdemo on blogposter = userid where blogID=?";

$stmt = $db->prepare($sql);
$stmt->bind_param(i,$article);
$stmt->execute();
$stmt->store_result();
$stmt->bind_result($articleid,$articletitle,$articletext,$blogtime,
                    $blogposter,$username,$userid);

//build article html
while($stmt->fetch()) {
 echo "<article id='a$articleid'>
   <h1>$articletitle</h1>
   <p>".nl2br($articletext)."</p>
   
   
   <footer><p>Posted on <time datetime='$blogtime'>$blogtime</time> by <em>$username</em></p></footer>";

 // if user is logged in and not suspended add comment button
 if($currentuser['userlevel']>2 || ($currentuser['userid']==$userid && $currentuser['userlevel']>1)) {
  ?> <form method='post' action='applychanges.php'>
   <input type="hidden" name="articleid" id="articleid" size="30" value="<?php echo $articleid; ?>"/><br />
   <input type="text" name="articletitle" id="articletitle" size="30" required value="<?php echo $articletitle; ?>"/><br />
   <textarea name="articletext" id="articletext" cols="60" rows="5"><?php echo $articletext; ?></textarea></br>
   <button type="submit">Confirm</button>
   </form> 
  <?php
 }
 echo "</article>";
}
$stmt->close();
$db->close();

?>

My APPLY CHANGES code:

This is where the parameters fail

<!doctype html>
<html lang="en-gb" dir="ltr">
<head>
</head>
<body>
<?php
ini_set('display_errors', 'On'); ini_set('html_errors', 0); error_reporting(-1);
print_r($_POST);
include('php/functions.php');
if(isset($_POST['articleid']) && isset($_POST['articletitle'])  && isset($_POST['articletext'])) {
 $db=createConnection();
 
 $articleid=$_POST['articleid'];
 $articletitle=$_POST['articletitle'];
 $articletext=$_POST['articletext'];

$updatesql = "UPDATE blogarticle SET articletitle=?, articletext=? WHERE articleid=?";
 $doupdate=$db->prepare($updatesql);

 $doupdate->bind_param("ssi",$articletitle, $articletext, $articleid);
 $doupdate->execute();
 $doupdate->close();
  
 $db->close();
 header("location: index.php");
} else {
 echo "<p>Some parameters are missing, cannot update database</p>";
 print_r($_POST);
}
?>
</body>
</html>

Result:

Fatal error: Call to a member function bind_param() on boolean in /home/16018142/public_html/Assessment/applychanges.php on line 18

when I use print_r($_POST) it displays these -

Array ( [articleid] => 9 
        [articletitle] => THIS IS A TEST 
        [articletext] => Test Test Test Test Test Test Test Test Test Test Test Test Test Test Test Test Test Test Test Test Test Test Test Test Test Test Test Test Test Test Test Test Test Test Test Test Test Test ).
RiggsFolly
  • 89,708
  • 20
  • 100
  • 143
  • You need to add error handling to your database calls. And to start, you need to replace the injected variables with placeholders: `... SET articletitle = ?, ...`. – jeroen Jan 26 '17 at 07:43
  • Could you give me an example of what you mean? – user3361789 Jan 26 '17 at 08:11
  • See the answer below. – jeroen Jan 26 '17 at 08:11
  • Oh and dont ask the same question twice! – RiggsFolly Jan 26 '17 at 09:37
  • The prepare() method must have failed to generate a prepared statement. As it looks like you're using some kind of wrapper class instead of raw PDO I can't really comment further as to anything else that might be wrong, but when calling methods that might fail you must always be prepared to handle failure (if the method doesn't return the expected result or throws an exception depending on how failure is handled in the method) – GordonM Jan 26 '17 at 09:56

4 Answers4

3

According to http://php.net/manual/en/mysqli-stmt.prepare.php you should put your parameters as ? .

So, line

     $updatesql="UPDATE blogarticle SET articletitle='$articletitle', articletext='$articletext' WHERE articleid='$articleid'";

should become

 $updatesql="UPDATE blogarticle SET articletitle=?, articletext=? WHERE articleid=?";

UPDATE Also the error may depend on your query. Check the return value of

    $db->prepare

as discussed in

Fatal error: Call to a member function bind_param() on boolean

Community
  • 1
  • 1
Massimo Petrus
  • 1,873
  • 2
  • 12
  • 26
  • 1
    The OP is not using PDO but mysqli; `bind_param()` is a mysqli method and does not exist in PDO. Nor do named placeholders. – jeroen Jan 26 '17 at 07:55
  • oops i did'nt consider that..sure it was PDO..sorry – Massimo Petrus Jan 26 '17 at 08:04
  • I have done this, I actually orginally done this but changed it just to "experiment". Though the problem still persists, it is always the bind_param line that fails, even on similar code it works but just not for this article. – user3361789 Jan 26 '17 at 08:16
  • can you print out the values of your variables (exspecially $articleid) – Massimo Petrus Jan 26 '17 at 08:18
  • Yes, when I use print_r($_POST) it displays these - Array ( [articleid] => 9 [articletitle] => THIS IS A TEST [articletext] => Test Test Test Test Test Test Test Test Test Test Test Test Test Test Test Test Test Test Test Test Test Test Test Test Test Test Test Test Test Test Test Test Test Test Test Test Test Test ). As far as I am aware, this is correct as the variables are filled. This is correct right? – user3361789 Jan 26 '17 at 08:23
  • Any idea what the problem could be? I don't see an issue. – user3361789 Jan 26 '17 at 08:35
  • did you try the reviewed answer or the first version (the one with PDO) ? Can you post your updated code ? – Massimo Petrus Jan 26 '17 at 08:39
  • Yes I have reviewed the answer, I'll get my current code uploaded now. 1 moment. – user3361789 Jan 26 '17 at 09:04
2

You still dont appear to be setting a value for $article before using it to replace the ? in the query using bind_param()

Also the datatype parameter in bind_param need to be in quotes

Also some error checking would be good.

<?php
$db=createConnection();
// get the first two articles
$sql = "select blogID,articletitle,articletext,
                blogtime,blogposter,username,userid 
        from blogarticle 
            join registerdemo on blogposter = userid 
        where blogID=?";

$stmt = $db->prepare($sql);
if (!$stmt) {
    echo $stmt->error;
    exit;
}

// need to give $article a value before you try and use it
// also the datatype parameter need to be in quotes
$stmt->bind_param('i',$article);

$stmt->execute();
if (!$stmt) {
    echo $stmt->error;
    exit;
}

Also add some error checking in this code, basically if the bind is failing with boolean error the prepare failed, so you probably have a SQL syntax error

<?php
// set full debugability on for testing
ini_set('display_errors', 1); 
ini_set('log_errors',1); 
error_reporting(E_ALL); 
// next line makes MYSQLI generate exceptions on error
mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);

print_r($_POST);

include('php/functions.php');
if( isset($_POST['articleid']) && 
    isset($_POST['articletitle']) && 
    isset($_POST['articletext'])) 
{
    $db=createConnection();

    $updatesql = "UPDATE blogarticle 
                    SET articletitle=?, articletext=? 
                  WHERE articleid=?";

    $doupdate=$db->prepare($updatesql);
    if (!$doupdate) {
        echo $doupdate->error;
        exit;
    }

    $doupdate->bind_param("ssi",$_POST['articletitle'],
                                $_POST['articletext']
                                $_POST['articleid']);
    $doupdate->execute();
    if (!$doupdate) {
        echo $doupdate->error;
        exit;
    }

    header("location: index.php");
    // exit after a header as header does no stop
    // the script processing it just send a HTTP header
    exit;       
} else {
    echo "<p>Some parameters are missing, cannot update database</p>";
    print_r($_POST);
}
RiggsFolly
  • 89,708
  • 20
  • 100
  • 143
  • Hey RiggsFolly, thanks for answering. I do have a value set for this variable as I didn't add the whole code just the part that communicates with applychanges.php as that is where the issue lays. I have this set for $article '$article=$_GET['aID'];'. When I select edit on the article, it allows me to edit it, resubmitting it doesn't seem to work. – user3361789 Jan 26 '17 at 09:33
  • I have posted full code on this website before and was told not to do it again so this is why I did it this way. Are you saying I should post the entire code pages? – user3361789 Jan 26 '17 at 09:36
  • Not necessarily the full code but [Minimal, Complete and Verifiable example](http://stackoverflow.com/help/mcve) – RiggsFolly Jan 26 '17 at 09:38
1

Call to a member function bind_param() on boolean

I am guessing that line 18 is this:

$doupdate->bind_param("ssi",$articletitle, $articletext, $articleid);

Which means that $doupdate is boolean. Its value is set in the preceding line:

$doupdate=$db->prepare($updatesql);

The code you ave presented reveals nothing about the the database integration, nor have you provided any explanation in your code, but the method names look like mysqli, hence you might want to insert:

if ($db->error) {
    die ($db->error);
}

The error might be a bad password, network issue, or due to not selecting a DB / specifying it in the query.

symcbean
  • 46,644
  • 6
  • 56
  • 89
  • I love you, it was an error on my part. I'll be sure to post things with more detail next time. As for this problem, it was database headers and integration. – user3361789 Jan 26 '17 at 10:04
  • Not necessarily *more* detail - you just need to be more systematic about your analysis and reduce your code down to the minimum necessary to reproduce the fault. – symcbean Jan 26 '17 at 12:59
0

Thanks to everyone for posting. This was eventually figured this out by the recommendations of everyone that posted to look at how values were set and passed.

Please also note that this would have been resolved earlier by users if I posted more details and information about the database I was using.

I was looking at $articleid and passing it back to the database as this variable but $articleid has a set value from blogID from the database. articleid does not exist as a column on the database.

To resolve this I simply added the following two lines of code:

$blogID=$_POST['blogID'];
$blogID=$articleid;

Then changed:

'WHERE articleid=?;' to 'WHERE blogID=?;'.