严格的标准:只有变量应该通过引用传递 - 为什么这仍然有用,我该如何纠正呢?

I am trying to query a database to check if an email is already registered, following submission of user details.

However, I get a "Strict standards: Only variables should be passed by reference" error with the following code (excerpt):

} else  if (isset($_POST['srSubmit']) && $_POST['srEmail']) {

    //check if email already taken
    if ($stmtreg = $mysqli->prepare("SELECT user_email FROM users WHERE user_email = ?")) {
        $stmtreg->bind_param("s", strtolower($_POST['srEmail']));
        $stmtreg->execute();
        $stmtreg->store_result();
        $num_rows = $stmtreg->num_rows();
        $stmtreg->bind_result($email);
        $stmtreg->fetch();
        $stmtreg->close();
    }

I have two questions: i) why does the script still work, even with this error? an ii) what is causing it and how do I fix it?

Thanks

Set a temporary variable for strtolower($_POST['srEmail']), something like:

$email = strtolower($_POST['srEmail']);

and then pass in $email to your bind_param. Even though strtolower() returns a string, PDO cant reference it because it's not a variable.

Can't answer your first question, but here is how you pass by reference:

//check if email already taken
if ($stmtreg = $mysqli->prepare("SELECT user_email FROM users WHERE user_email = ?")) {
    $email = strtolower($_POST['srEmail']);
    $stmtreg->bind_param("s", &$email);
    $stmtreg->execute();
    $stmtreg->store_result();
    $num_rows = $stmtreg->num_rows();
    $stmtreg->bind_result($email);
    $stmtreg->fetch();
    $stmtreg->close();
}

In order to pass a variable by reference, you need to put an & before the variable name (eg &$email)

Look at this line:

$stmtreg->bind_param("s", strtolower($_POST['srEmail']));

As php manual for bind_param says:

bool mysqli_stmt::bind_param ( string $types , mixed &$var1 [, mixed &$... ] )

This function requires a variable to be passed by reference. While you are not passing a value to it: the result of strtolower function.

To see the difference look at this code:

<?php
function foo(&$var)
{
    $var .= "!";
}

$a = "1";
foo($a);
print $a;
print "
";

$b = "1";
foo(strtolower($b));
print $b;
?>

It will print:

1!
1

$b wasn't modified, because php doesn't have a variable to modify. http://www.php.net/manual/en/language.references.pass.php

So, save your result to a variable and pass it instead:

$email = strtolower($_POST['srEmail']);
$stmtreg->bind_param("s", $email);

"why does the script still work, even with this error?"

Because you just need to substitute the parameter with the value and is not modifying the input variable in bind_param function.

Q: Why does this script still work?

Because it's a warning, not really an error.

Q: What's causing it?

It's this line causing the error.

$stmtreg->bind_param("s", strtolower($_POST['srEmail']));

bind_param is expecting a VARIABLE as the second parameter. The strtolower function returns a string, not a variable.

Q: How do I fix this?

One way to fix this is to assign the return from strtolower to a variable, and then reference the variable in bind_param:

$lower_email = strtolower($_POST['srEmail']);
$stmtreg->bind_param("s", $lower_email);