Jump to content

Warning: mysqli_stmt_execute() expects parameter 1 to be mysqli_stmt, boolean given in ... on line 42


phpsane

Recommended Posts

Fellow Php Professionals,

 

 

Looking at this code, is it not very clear that the $email, $account_activation_code, $userActivationState and $stmt_two been defined ?


If so, then why do I get these following errors ?

 

Notice: Undefined variable: email in /home/user/public_html/e-id/activate_account.php on line 11

NULL

Notice: Undefined variable: account_activation_code in /home/user/public_html/e-id/activate_account.php on line 14

NULL

 

Notice: Undefined variable: userActivationState in /home/user/public_html/e-id/activate_account.php on line 23

NULL int(0) int(0)

Notice: Undefined variable: stmt_two in /home/user/public_html/e-id/activate_account.php on line 38

NULL


 


 
<?php
include 'config.php';
if (!isset($_GET["email"], $_GET["account_activation_code"]) === true){
    $_SESSION['error'] = "Invalid Email Address! Invalid Account Activation Link! This email is not registered! Try registering an account if you do not already have one! <a href=\"register.php\">Register here!</a>";
    exit();

else 
{
var_dump($email, $account_activation_code, $stmt_one, $userActivationState, $stmt_two);
$email = htmlspecialchars($_GET['email']);
$account_activation_code = htmlspecialchars($_GET['account_activation_code']);
$stmt_one = mysqli_prepare($conn, "SELECT usernames, accounts_activations FROM users WHERE emails = ? AND accounts_activations_codes = ?");
mysqli_stmt_bind_param($stmt_one, 'si', $email,  $account_activation_code);
mysqli_stmt_bind_result($stmt_one, $username, $userActivationState);
if (mysqli_stmt_execute($stmt_one) && mysqli_stmt_fetch($stmt_one))
{
if ($userActivationState != 0)
{
echo "Since your account is already activated, why are you trying to activate it again ? Do not do that again and just login from <a href=\"login.php\">this webpage</a> next time! Make a note of that webpage, ok ?";
exit;
}
   
$userActivationState = 1;
 
 
$stmt_two = mysqli_prepare($conn, "UPDATE users SET accounts_activations = ? WHERE usernames = ?");
mysqli_stmt_bind_param($stmt_two, 'is', $userActivationState, $username);
 
if (mysqli_stmt_execute($stmt_two))
{
echo "<h3 style='text-align:center'>Thank you for your confirming your email and activating your account.<br /> Redirecting you to the login page ...</h3>";
$_SESSION["user"] = $username;
header("location:home.php");
exit;
}

else 
{
echo "FAILURE to UPDATE db";
exit;
}
}
 

 


I don't have any boolean on the $stmt_one variable atall.

But I get these errors:

 

Warning: mysqli_stmt_bind_param() expects parameter 1 to be mysqli_stmt, boolean given in /home/user/public_html/e-id/activate_account.php on line 40

 

Warning: mysqli_stmt_execute() expects parameter 1 to be mysqli_stmt, boolean given in /home/user/public_html/e-id/activate_account.php on line 42**

 


 

The config.php looks like this:

 


 
<?php
/*
ERROR HANDLING
*/
declare(strict_types=1);
ini_set('display_errors', '1');
ini_set('display_startup_errors', '1');
error_reporting(E_ALL);
mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
// session start
if(!session_start()) {
session_start();
}
// include files
include 'conn.php';
include 'site_details.php';
// include functions
include 'functions.php';
?>
 

Link to comment
Share on other sites

I am not familiar with your IF statement syntax.  Can you explain what this does:

 

if (!isset($_GET["email"], $_GET["account_activation_code"]) === true)

 

And if you are going to show us your error messages (which is good) perhaps you could show us the line numbers as well?  I would guess that the

messages should show up much earlier than whatever line 11 is, so maybe you could tell us exactly where they are coming from? 

 

 

And in your config module - If your call to session_start fails, why the heck would you do it again?  Are you thinking logically when you code?

 

And I agree with Barand's succinct and entirely well-directed statement.  Read the manual to learn how to program properly with PHP.

Link to comment
Share on other sites

I am not familiar with your IF statement syntax.  Can you explain what this does:

if (!isset($_GET["email"], $_GET["account_activation_code"]) === true)

And if you are going to show us your error messages (which is good) perhaps you could show us the line numbers as well?  I would guess that the

messages should show up much earlier than whatever line 11 is, so maybe you could tell us exactly where they are coming from? 

 

 

And in your config module - If your call to session_start fails, why the heck would you do it again?  Are you thinking logically when you code?

 

And I agree with Barand's succinct and entirely well-directed statement.  Read the manual to learn how to program properly with PHP.

 

I am actually working on somebody else's work as that person did not have the time to test the script and finish it. he is no longer available now.

I guess he coded it so the session does not start a 2nd time if the session is already active.

 

This following part means IF NOT SET email and account_activation_code, then do this:

 
if (!isset($_GET["email"], $_GET["account_activation_code"]) === true)
 

My update looks like this:

 
<?php
 
include 'config.php';
 
if (!isset($_GET["email"], $_GET["account_activation_code"]) === true){
    $_SESSION['error'] = "Invalid Email Address! Invalid Account Activation Link! This email is not registered! Try registering an account if you do not already have one! <a href=\"register.php\">Register here!</a>";
    exit();
} 
else 
{ 
$email = htmlspecialchars($_GET['email']); 
$account_activation_code = htmlspecialchars($_GET['account_activation_code']); 
$stmt_one = mysqli_prepare($conn, "SELECT usernames, accounts_activations FROM users WHERE emails = ? AND accounts_activations_codes = ?"); 
mysqli_stmt_bind_param($stmt_one, 'si', $email,  $account_activation_code); 
mysqli_stmt_bind_result($stmt_one, $username, $userActivationState); 
var_dump($email, $account_activation_code, $stmt_one, $userActivationState); 
if (mysqli_stmt_execute($stmt_one) && mysqli_stmt_fetch($stmt_one))
{ 
if ($userActivationState != 0)
{ 
echo "Since your account is already activated, why are you trying to activate it again ? Do not do that again and just login from <a href=\"login.php\">this webpage</a> next time! Make a note of that webpage, ok ?";
exit;
}
 
$userActivationState = 1; 
$stmt_two = mysqli_prepare($conn, "UPDATE users SET accounts_activations = ? WHERE usernames = ?");
mysqli_stmt_bind_param($stmt_two, 'is', $userActivationState, $username); 
var_dump($stmt_two, $userActivationState, $username); 
if (mysqli_stmt_execute($stmt_two))
{
echo "<h3 style='text-align:center'>Thank you for your confirming your email and activating your account.<br /> Redirecting you to the login page ...</h3>";
$_SESSION["user"] = $username;
header("location:home.php");
exit;
}
} 
else 
{
echo "FAILURE to UPDATE db";
exit;
}
}
 
And this time round, I am shown this:
 
string(23) "EDITED@EDITED.com" string(40) "472b07b9fcf2c2451e8781e944bf5f77cd8457c8" object(mysqli_stmt)#2 (10) { ["affected_rows"]=> int(0) ["insert_id"]=> int(0) ["num_rows"]=> int(0) ["param_count"]=> int(2) ["field_count"]=> int(2) ["errno"]=> int(0) ["error"]=> string(0) "" ["error_list"]=> array(0) { } ["sqlstate"]=> string(5) "00000" ["id"]=> int(1) } NULL 
Warning: mysqli_stmt_bind_param() expects parameter 1 to be mysqli_stmt, boolean given in /home/EDITED (User)/public_html/e-id/activate_account.php on line 27
**bool(false)** int(1) string( 8) "EDITED (User)" 
Warning: mysqli_stmt_execute() expects parameter 1 to be mysqli_stmt, boolean given in /home/EDITED (User)/public_html/e-id/activate_account.php on line 29
 
Note the **bool(false)** in the first warning. Regarding line 27.
Line 27:
 
 
mysqli_stmt_bind_param($stmt_two, 'is', $userActivationState, $username);
 
 
$stmt_two (line 26) looks like this:
 
 
$stmt_two = mysqli_prepare($conn, "UPDATE users SET accounts_activations = ? WHERE usernames = ?");
 
 
Q3. Am I right that this line ($stmt_two) is getting found as FALSE ?
If so, then I don't understand why. Don't understand what is wrong with that line:
 
 
$stmt_two = mysqli_prepare($conn, "UPDATE users SET accounts_activations = ? WHERE usernames = ?");
 
 
There does exist a "users" tbl with columns "accounts_activations" and "usernames". And so, I don't understand why $stmt_two is coming out as FALSE boolean. I have not got the sql query syntax wrong in any way. Right ?
 
 
Q4. One other question. Is the following part of the code is correct or not:
 
 
if (!isset($_GET["email"], $_GET["account_activation_code"]) **=== true**)
 
 
That part was added by another programmer in another forum. He's not available in the forum anymore. And so, can't ask him to explain it.
 
Can it be changed to any of these:
 
 
if (!isset($_GET["email"], $_GET["account_activation_code"]))
 
 
 
if (isset($_GET["email"], $_GET["account_activation_code"]) === false)
 
Link to comment
Share on other sites

You miss the point of my question.  Your session start fails.  Your if statement says to try again.  Really?

 

As for the If syntax, my research in the php manual shows this:

 

IF (condition) 

    handle true

else

   handle false.

 

This syntax is also used with AND as well as OR connectors to join them.  If does not show any use of multiple conditions separated by a comma, so that is why I questioned it.  Of course if you have a resource that shows that, please enlighten me.

 

 

PS - are you getting all of this input data from a user form?  If so, why are you using GET instead of POST?

Link to comment
Share on other sites

There are no comma-separated conditions. The commas are for the arguments of the isset() function, which is perfectly valid. Of course the === true comparison is nonsensical, because isset() already is a boolean function which either returns true or false. You cannot make a boolean “more boolean”.

 

As to the original problem: Something is very wrong here. The mysqli_report() call enables mysqli exceptions, which means PHP should abort the script in case of a mysqli error and not return false. Since you do get false, you're either looking at the wrong code, or the code you've posted isn't the one you're actually using.

Link to comment
Share on other sites

the OP is probably getting a 'commands out of sync' error at the prepare() call for the update query (or this isn't the actual code where the errors are at.)

 

as to why he is not seeing the actual error - some code in one of the other included files could be modifying the mysqli error reporting mode or there is custom error handling being used and it is not actually handling the error type being generated.

 

what is the content of the other three included files (less any sensitive data values in them)?

Link to comment
Share on other sites

You miss the point of my question.  Your session start fails.  Your if statement says to try again.  Really?

 

As for the If syntax, my research in the php manual shows this:

 

IF (condition) 

    handle true

else

   handle false.

 

This syntax is also used with AND as well as OR connectors to join them.  If does not show any use of multiple conditions separated by a comma, so that is why I questioned it.  Of course if you have a resource that shows that, please enlighten me.

 

 

PS - are you getting all of this input data from a user form?  If so, why are you using GET instead of POST?

 

register.php gathers the user data via POST. Then emails the user with the account activation link which he must click to confirm his email.

That confirmation click is dealt with this script you see account_activation.php.

It grabs the email and account activation code via GET and then checks the mysql tbl for matches (both). When it finds matches, it then grabs the username from the matched row and the 'account activation' status. If it finds the account activation status as zero then it replaces that with 1. 0 means pending reg and 1 means reg activated. If it finds 1 and not 0 during the check then it gives alert asking why user is wanting to activate acc which has already been activated.

At the end, the script redirects the user to the login page and auto logs him in with his session name (session name = username) so that he does not have to type user credentials.

That is all there is to this script.

 

Thank you for your concerns, helps, questions and willingnesses to help.

Link to comment
Share on other sites

Mac Guyver,

 

Here are the full contents:

 

config.php

 

 

<?php
 
/*
ERROR HANDLING
*/
declare(strict_types=1);
ini_set('display_errors', '1');
ini_set('display_startup_errors', '1');
error_reporting(E_ALL);
 
mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
 
// session start
if(!session_start()) {
session_start();
}
 
// include files
include 'conn.php';
include 'site_details.php';
 
// include functions
include 'functions.php';
 
?>

config.php

conn.php

register_editing.php

activate_account_edited.php

activate_account_edited_KICKEN.php

Link to comment
Share on other sites

Mac Guyver,

 

Attached are the files you requested.

Anybody welcome to download them.

 

config.php

functions.php

conn.php

 

register_edited.php

account_activation_edited.php (original file that contains NO PREPARED STATEMENTS)

account_activation_KICKEN.php (new file that contains PREPARED STATEMENTS. Currently stuck on this file)

 

 

@Jinergm,

 

The first 3 files might answer your questions.

 

@everyone

I've only with-held the site_details.php which contain nothing more than my site details such as domain name, social network name, site name, webmaster email.

It is not that important.

With-held the login.php too as that is not finished.

 

You need to check this file to get a hunch how to account_activation file functions. Unfortunately, it does not have PREP STMTS to prevent sql injection. And so, am adding the PREP STMTS onto this new version: account_activation_KICKEN.php

The latter file was edited by another programmer. It was built by hi, on the skeleton of my file: account_activation_edited.php

 

When testing the files on your end, do remember to rename the files so no "_edited" or "_KICKEN" exist.

 

Thank you for your help everybody who are involved.

 

 

 

 

config.php

conn.php

functions.php

register_editing.php

activate_account_edited.php

activate_account_edited_KICKEN.php

Link to comment
Share on other sites

Since you're now juggling with three or four different versions and no longer seem to know what those scripts even contain (you claim that the older versions have no prepared statements, but all scripts do), I suggest you stop it, move all current code outside of the document root and start over with an empty directory. We cannot debug a moving target where you're constantly coming up with new _edited and _edited_edited_edited versions.

 

When you have the empty directory, create a minimal example of a working database connection with a proper error configuration. That is, invalid prepared statements must trigger an exception. I strongly recommend you give up mysqli and switch to the much more programmer-friendly PDO. But if you think it's too late now, well, then you're stuck with mysqli.

 

Once again: I want a single script with a database connection and an invalid prepared statement which triggers an exception. When this works, then we can talk about more complex code.

Link to comment
Share on other sites

  • 2 weeks later...

RTFM

 

Come-on Mod! You're a Mod! And the very first thing you do in my very first thread in your forum is use bad language. Is that going to encourage me (someone young enough to be your children's age) to ask more questions in your forum ?

How-about behaving mildy towards your guests instead of roughly ?

Link to comment
Share on other sites

@Jacques1, @jinergm & @mac_guyver,

 

 

The script is working now. I really don't know why I was getting that boolean error. I just copied a few lines from the manual and the errors faded.

Comparing my original code in my original post and my update below, can anyone spot which part of the code in the update got rid of the error as that way I can hone in on that part and try figuring-out what was causing the error so it does not happen again ?

Here is my update ...

 

 

activate_account.php

 

 
<?php
 
include 'config.php';
 
if (!isset($_GET["email"], $_GET["account_activation_code"]) === true)
{
    $_SESSION['error'] = "Invalid Email Address! Invalid Account Activation Link! This email is not registered! Try registering an account if you do not already have one! <a href=\"register.php\">Register here!</a>";
    exit();
} 
else 
{
$email = htmlspecialchars($_GET['email']);
$account_activation_code = htmlspecialchars($_GET['account_activation_code']);
 
$stmt_one = mysqli_stmt_init($conn);
if (mysqli_stmt_prepare($stmt_one, "SELECT usernames, accounts_activations FROM users WHERE emails = ? AND accounts_activations_codes = ?"))
{
mysqli_stmt_bind_param($stmt_one, 'si', $email,  $account_activation_code);
mysqli_stmt_execute($stmt_one);
mysqli_stmt_bind_result($stmt_one, $username, $account_activation_state);
mysqli_stmt_fetch($stmt_one);
mysqli_stmt_close($stmt_one);
   
if ($account_activation_state != 0)
{
echo "Since your account is already activated, why are you trying to activate it again ? Do not do that again and just login from <a href=\"login.php\">this webpage</a> next time! Make a note of that webpage, ok ?";
exit;
}
else
{
$account_activation_state = 1;
 
$stmt_two = mysqli_stmt_init($conn);
if(mysqli_stmt_prepare($stmt_two, "UPDATE users SET accounts_activations = ? WHERE usernames = ?"))
{
mysqli_stmt_bind_param($stmt_two, 'is', $account_activation_state, $username);
mysqli_stmt_execute($stmt_two);
mysqli_stmt_fetch($stmt_two);
mysqli_stmt_close($stmt_two);
 
echo "Account Activation State: $account_activation_state";?><br>
<?php
echo "Username: $username";
 
echo "<h3 style='text-align:center'>Thank you for your confirming your email and activating your account.<br /> You may now try logging into your account.</h3>";
$_SESSION["user"] = $username;
}
else
{
echo 'Failure: Something is wrong. Unable to activate your account! Contact Site Admin.';
echo 'Failure: Mysqli_stmt_prepare($stmt_two)';
exit;
}
}
}
else
{
echo 'Failure: This account activation link is invalid or has expired. Try <a href="register.php">registering</a> for an account now.';
echo 'Failure: Mysqli_stmt_prepare($stmt_one)';
exit;
}
}
 
?>
 

 

 

So, I have now solved the issue mentioned in this forum and thread:

http://forums.devshed.com/php-development/977810-improvements-regsitration-site-reg-php-post2978305.html#post2978305

On that forum, notice that the thread was opened by UniqueIdeaMan.

Original script had no sql prevention method and so Kicken (a member there) responded and added it. But Kicken did not test his update and it was showing following errors. 

 

Notice: A session had already been started - ignoring session_start() in /home/user/public_html/id/config.php on line 21

Warning: mysqli_stmt_bind_param() expects parameter 1 to be mysqli_stmt, boolean given in /home/user/public_html/id/activate_account.php on line 22

Warning: mysqli_stmt_execute() expects parameter 1 to be mysqli_stmt, boolean given in /home/user/public_html/id/activate_account.php on line 23

 

 

So now you know where the "===true" part came from. Came from Kicken's update:

 

if (!isset($_GET["email"], $_GET["account_activation_code"]) === true)

 

I found it odd, like you people, about the "=== true)" too but I am a new student and Kicken over there looked like an expert and so I just copied his code and wanted to see if I can see it get finished properly here.

 

Anyway, do you people see any problems with my own update ?

Link to comment
Share on other sites

My reply to your very first post told you exactly why you were getting the error message about the boolean value (a direct quote from the manual, which, as suggested, you should read when you have a problem with a PHP function).

 

Actually, my point was that, I still do not understand why the mysqli_prepare was returning false. What error was causing it to go false.

I want to see if anyone can enlighten me to what my mistake actually was that was making it return false.

Link to comment
Share on other sites

The prepare will fail if the query is not formed properly.  Any invalid column names, any missing parms ie, a mismatch in the number of values and fields.  It's up to you to debug it.  Remember that you cannot use a parm for the table name.

Link to comment
Share on other sites

Show us the complete sql statement that is being 'prepared'.  I don't want to have to search for it.

 

This was failing:

$stmt_one = mysqli_prepare($conn, "SELECT usernames, accounts_activations FROM users WHERE emails = ? AND accounts_activations_codes = ?");
mysqli_stmt_bind_param($stmt_one, 'si', $email,  $account_activation_code);
mysqli_stmt_bind_result($stmt_one, $username, $userActivationState);
if (mysqli_stmt_execute($stmt_one) && mysqli_stmt_fetch($stmt_one))

Now, this is the fixed. I just copied the lines from the manual. Therefore, do not really realize how this became the fix.

$stmt_one = mysqli_stmt_init($conn);
if (mysqli_stmt_prepare($stmt_one, "SELECT usernames, accounts_activations FROM users WHERE emails = ? AND accounts_activations_codes = ?"))
{
mysqli_stmt_bind_param($stmt_one, 'si', $email,  $account_activation_code);
mysqli_stmt_execute($stmt_one);
mysqli_stmt_bind_result($stmt_one, $username, $account_activation_state);
mysqli_stmt_fetch($stmt_one);
 
mysqli_stmt_close($stmt_one);

And, if I remember correctly, this was failing too:

$stmt_two = mysqli_prepare($conn, "UPDATE users SET accounts_activations = ? WHERE usernames = ?");
mysqli_stmt_bind_param($stmt_two, 'is', $userActivationState, $username); 

But this fix working:

$stmt_two = mysqli_stmt_init($conn);
if(mysqli_stmt_prepare($stmt_two, "UPDATE users SET accounts_activations = ? WHERE usernames = ?"))
{
mysqli_stmt_bind_param($stmt_two, 'is', $account_activation_state, $username);
mysqli_stmt_execute($stmt_two); 
mysqli_stmt_fetch($stmt_two);
 
mysqli_stmt_close($stmt_two);
$stmt_one = mysqli_stmt_init($conn); mysqli_stmt_close($stmt_one); $stmt_two = mysqli_stmt_init($conn); mysqli_stmt_close($stmt_two);

The above "inits" and "closes" were missing from my original version. But they exist in the fixed version. I guess, they were the cause of my malfunctions. What is your opinion ?

Link to comment
Share on other sites

Archived

This topic is now archived and is closed to further replies.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.