Php mysqli连接无法使用mysqli\u real\u escape\u字符串

Php mysqli连接无法使用mysqli\u real\u escape\u字符串,php,sql,mysqli,Php,Sql,Mysqli,我有一个简单的演示php脚本正在尝试。我之前一直在使用不推荐使用的mysql\uu扩展,试图从该扩展迁移到mysqli\uu的过程中出现了过多的错误。当尝试使用mysqli\u real\u escape\u stringphp抛出一个未定义的变量错误似乎无法找出原因 <?php $servername = "localhost"; $username = "root"; $password = ""; $dbname = "bridgoo"; // Create connec

我有一个简单的演示php脚本正在尝试。我之前一直在使用不推荐使用的
mysql\uu
扩展,试图从该扩展迁移到mysqli\uu的过程中出现了过多的错误。当尝试使用
mysqli\u real\u escape\u string
php抛出
一个未定义的变量错误
似乎无法找出原因

    <?php

$servername = "localhost";
$username = "root";
$password = "";
$dbname = "bridgoo";

// Create connection
$conn = new mysqli($servername, $username, $password, $dbname);


// Check connection
if ($conn->connect_error) {
  //do stuff
  }
// prepare and bind
$stmt = $conn->prepare("INSERT INTO bridgoo_users (username, email, password) VALUES (?, ?, ?)");
$stmt->bind_param("sss", $username, $password, $email);


    //generate password hash using blowfish algorithm
   $password_hash =  password_hash($_POST['password'], PASSWORD_BCRYPT, ["cost" => 9]);

$username = clean_input($_POST['username']);
$password = clean_input($password_hash);
$email = clean_input($_POST['email']);


function clean_input($input){

    $input = htmlentities($input);
    $input = htmlspecialchars($input,ENT_QUOTES);
    $input = mysqli_real_escape_string($conn,$input);

    return $input;
}


$stmt->execute();
$stmt->close();
$conn->close();

?>

php错误通知:未定义变量:第24行C:\xampp\server1\htdocs\bridgoo\inc\register.php中的conn


您的
clean_input
函数没有访问
$conn
变量的权限,它位于不同的位置

简单的解决方案是将连接作为参数添加到函数中。大概是这样的:

<?php
...


$username = clean_input($_POST['username'], $conn);
$password = clean_input($password_hash, $conn);
$email = clean_input($_POST['email'], $conn);


function clean_input($input, $conn){

...

您应该将
$conn
作为参数传递给函数
clean_input

$username = clean_input($conn, $_POST['username']);
$password = clean_input($conn, $password_hash);
$email = clean_input($conn, $_POST['email']);


function clean_input($conn, $input){

    $input = htmlentities($input);
    $input = htmlspecialchars($input,ENT_QUOTES);
    $input = mysqli_real_escape_string($conn,$input);

    return $input;
}

关于
未定义变量$conn
的错误与此有关,其他人已经回答了这个问题

但您的代码也需要一些其他建议

如果使用查询参数,则根本不需要清除输入。这就是使用查询参数的要点:不需要使用
mysqli\u real\u escape\u string()
,因为参数是自动安全的

事实上,您不能使用
mysqli\u real\u escape\u string()
,因为您的数据将以
\'
转义撇号插入数据库

简单地说:SQL参数和
mysqli\u real\u escape\u string()
是互斥的。不要两者都做。

此外,使用
htmlspecialchars()
htmlspecialchars()
来清理SQL输入也毫无意义,即使您使用
mysqli\u real\u escape\u string()
而不是参数

这些与html相关的功能仅用于html输出。它们对于保护您的web应用程序免受攻击非常重要,这是您需要了解的另一个不相关的web安全风险。但对SQL输入进行清理时不需要它们

其他意见:

  • 您在mysqli连接和应用程序数据中同时使用用户名和密码变量,这令人困惑。没有理由重复使用变量,它们不会让您付出任何代价
  • 确保INSERT中参数的顺序与传递给
    bind_param()
    的绑定变量的顺序相匹配
  • 始终检查
    prepare()
    execute()
    的返回值。如果失败,则返回FALSE。如果失败,您必须记录错误并向用户报告页面无法工作

    我更喜欢将技术错误消息记录到PHP错误日志中 文件,并向用户报告更友好的内容

    养成在开发过程中打开一个窗口来查看PHP错误日志的习惯,这会对您有很大帮助

以下是我建议您如何编写代码:

<?php

$mysql_servername = "localhost";
$mysql_username = "root";
$mysql_password = "";
$mysql_dbname = "bridgoo";

$conn = new mysqli($mysql_servername, $mysql_username, $mysql_password, $mysql_dbname);

if ($conn->connect_error) {
  error_log($conn->connect_error);
  die("Sorry, a database error occurred.");
}

$stmt = $conn->prepare("
  INSERT INTO bridgoo_users (username, password, email) 
  VALUES (?, ?, ?)");
if ($stmt === false) {
  error_log($conn->error);
  die("Sorry, a database error occurred.");
}

$stmt->bind_param("sss", $username, $password_hash, $email);

//generate password hash using blowfish algorithm
$password_hash = password_hash($_POST['password'], PASSWORD_BCRYPT, ["cost" => 9]);

$username = $_POST['username'];
$email = $_POST['email'];

if ($stmt->execute() === false) {
  error_log($conn->error);
  die("Sorry, a database error occurred.");
}

if ($stmt->affected_rows == 1) {
  echo "Success!"
} else {
  echo "Sorry, an unknown problem occurred, and your record was not saved."
}

如果($conn->connect\u error){
您在错误流中?或者您在
clean\u input
函数中?最后一个-您需要将
$conn
作为参数传递到此finction中。或者您可以在函数中执行
全局$conn
。但我认为这是非常糟糕的做法。
clean\u input()
摆脱该方法;您使用的是一个准备好的语句,您不需要它。现在检查查询
mysqli\u error($conn)中的错误
然后告诉我们错误是什么,如果有的话。这是一个打字错误-复制了db.php。不在受影响的脚本中。好吧,这里还有另一个问题,除了我没有人发现,呵呵-变量和列名;它们不在序列中。很好的捕获@FunkFortyNiner。整个代码让我不寒而栗,但发现对齐问题是一个错误keen eye.passing$conn作为参数在调用它时抛出未定义的函数
致命错误:在C:\xampp\server1\htdocs\bridgoo\inc\register.php的第13行调用未定义的函数clean\u input()
我将其称为
clean\u input($conn,$\u POST['username'])
发布你的php文件。
发布的第13行
//检查连接
发布你的文件。这里没有心理主义者。重命名连接变量也是一个好主意,因为OP使用相同的变量作为密码,这实际上可能是一个问题,因为一个变量可能会覆盖另一个。这是也可能触发一个alleycat的逃逸门;-)嘿,等一下,变量和列名都出了问题。我现在才发现。在
password\u verify()上,这会失败
@FunkFortyNiner,谢谢,很好的回答,我没有注意到。我已经在我的示例代码中修复了它,并在上面的项目符号列表中添加了一个注释。不客气,比尔。当然还有其他问题,但这仍然有待于了解或说明。我们只希望他们在所有方面都遵守手册;-)有些事情确实会悄悄失败。回答得很好W