我正在尝试将一些使用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
答案 0 :(得分:1)
一个值得注意的“陷阱”是,mysql_real_escape_string
和mysqli_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 PHP和Generate the same MD5 using javascript and PHP。
您还使用了$name
之后的$score
和mysqli_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();
此处的关键是使用带占位符值的准备好的语句,并始终指定要实际插入的列。您不希望对架构进行小的更改即可完全破坏您的代码。
解决复杂问题的第一步是消除解决方案中的所有混乱,使错误变得更加明显。