切换到mysqli

时间:2019-01-22 18:55:50

标签: php mysql mysqli

我正在尝试将一些使用mysql的php代码转换为mysqli代码。我不确定为什么它不起作用-我没有编写原始代码,并且对它的哈希部分不太满意,这似乎是问题所在。正如我在下面的代码中所示,“错误”部分得到了回显,因此与哈希字符串有关,但是我真的不明白为什么更改为mysqli会破坏代码。下面是两个版本的代码,并且原始代码有效。我删除了变量(主机名等),但否则这就是我正在使用的代码。

Mysql代码:

// Send variables for the MySQL database class.
function db_connect($db_name)
{
    $host_name = "";
    $user_name = "";
    $password = "";
    $db_link = mysql_connect($host_name, $user_name, $password) //attempt to connect to the database
        or die("Could not connect to $host_name" . mysql_connect_error());
    mysql_select_db($db_name) //attempt to select the database
        or die("Could not select database $db_name");
    return $db_link;
}

$db_link = db_connect(""); //connect to the database using db_connect function

// Strings must be escaped to prevent SQL injection attack. 
$name = mysql_real_escape_string($_GET['name'], $db_link); 
$score = mysql_real_escape_string($_GET['score'], $db_link); 
$hash = $_GET['hash']; 

$secretKey=""; # Change this value to match the value stored in the client javascript below 

$real_hash = md5($name . $score . $secretKey); 
if($real_hash == $hash) { 
    // Send variables for the MySQL database class. 
    $query = "insert into scores values (NULL, '$name', '$score');"; 
    $result = mysql_query($query) or die('Query failed: ' . mysql_error()); 
} 

Mysqli代码(无效):

// Send variables for the MySQL database class.
function db_connect($db_name)
{
    $host_name = "";
    $user_name = "";
    $password = "";
    $db_link = mysqli_connect($host_name, $user_name, $password) //attempt to connect to the database
        or die("Could not connect to $host_name" . mysqli_connect_error());
    mysqli_select_db($db_link, $db_name) //attempt to select the database
        or die("Could not select database $db_name");
    return $db_link;
}

$db_link = db_connect(""); //connect to the database using db_connect function

// Strings must be escaped to prevent SQL injection attack. 
$name = mysqli_real_escape_string($_GET['name'], $db_link); 
$score = mysqli_real_escape_string($_GET['score'], $db_link); 
$hash = $_GET['hash']; 

$secretKey=""; # Change this value to match the value stored in the client javascript below 

$real_hash = md5($name . $score . $secretKey); 
if($real_hash == $hash) { 
    // Send variables for the MySQL database class. 
    $query = "INSERT INTO `scores` VALUES (NULL, '$name', '$score');"; 
    $result = mysqli_query($db_link, $query) or die('Query failed: ' . mysqli_error($db_link)); 
    echo $result;
}
else {
    echo "error"; //added for testing. This part gets echoed. 
}


mysqli_close($db_link); //close the database connection

3 个答案:

答案 0 :(得分:1)

一个值得注意的“陷阱”是,mysql_real_escape_stringmysqli_real_escape_string之间的参数顺序是不同的,因此您需要在转换中交换这些参数。

$name = mysqli_real_escape_string($db_link, $_GET['name']); 
$score = mysqli_real_escape_string($db_link, $_GET['score']); 

答案 1 :(得分:0)

最后一个if语句控制着mysql查询是否运行。由于您说此脚本在该语句的else部分中回显“错误”,因此看起来哈希值不匹配。

$hash变量正在$_GET['hash']中的URL字符串上传递。我建议回显$_GET['hash']$real_hash(在通过调用MD5计算出来之后),并确认它们不是相同的字符串。

我的直觉是$secretKey的值与用于生成在$_GET['hash']中传递的哈希值的键不匹配。正如评论所暗示的那样,$secretKey值必须与Javascript中使用的值匹配,否则哈希值将不匹配。

此外,您可能会发现Javascript的md5实现与PHP有所不同。它们可能会编码相同的输入,但返回的哈希值略有不同。

编辑:这也可能是Java脚本和PHP之间的字符编码差异,因此输入字符串被视为不同(从而生成不同的哈希值)。参见:identical md5 for JS and PHPGenerate the same MD5 using javascript and PHP

您还使用了$name之后的$scoremysqli_real_string_escape 的值,通过msqli被转义了,所以我建议确保使用Javascript部分也在处理转义(因此输入字符串匹配),并且$name转义功能的行为仍与先前版本相同。我建议回显$score// Set caret Position tooltipEl.classList.remove('above', 'below', 'no-transform'); if (tooltipModel.yAlign) { tooltipEl.classList.add(tooltipModel.yAlign); } else { tooltipEl.classList.add('no-transform'); } 的值,并确保它们也与Javascript端使用的值匹配。如果要在其他服务器上运行较新的代码,则可能需要设置字符集以匹配旧服务器。请参见http://php.net/manual/en/mysqli.real-escape-string.php上的“默认字符集”警告。

答案 2 :(得分:0)

花些时间进行转换是一件好事,尽管如果要使用mysqli,请完全将 转换为面向对象的接口:

// Send variables for the MySQL database class.
function db_connect($db_name)
{
    $host_name = "";
    $user_name = "";
    $password = "";

    // Enable exceptions
    mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);

    $db = new mysqli($host_name, $user_name, $password);
    $db->select_db($db_name);

    return $db;
}

$db = db_connect(""); //connect to the database using db_connect function

$secretKey=""; # Change this value to match the value stored in the client javascript below 

$real_hash = md5($name . $score . $secretKey); 

if($real_hash == $_GET['hash']) { 
    // Don't include ; inside queries run through PHP, that's only
    // necessary when using interactive MySQL shells.

    // Specify the columns you're inserting into, don't leave them ambiguous
    // ALWAYS use prepared statements with placeholder values
    $stmt = $db->prepare("INSERT INTO `scores` (name, score) VALUES (?, ?)"); 
    $stmt->bind_param("ss", $_GET['name'], $_GET['score']);

    $result = $stmt->execute();

    echo $result;
}
else {
    echo "error"; //added for testing. This part gets echoed. 
}

// Should use a connection pool here
$db->close();

此处的关键是使用带占位符值的准备好的语句,并始终指定要实际插入的列。您不希望对架构进行小的更改即可完全破坏您的代码。

解决复杂问题的第一步是消除解决方案中的所有混乱,使错误变得更加明显。