PHP-код больше не работает при переходе на mysqli - PullRequest
0 голосов
/ 22 января 2019

Я пытаюсь преобразовать некоторый php-код, который использует mysql, в код mysqli.Я не уверен, почему это не работает - я не писал оригинальный код и не очень доволен его хэш-частью, и, похоже, проблема в этом.Как показано в приведенном ниже коде, часть «error» выводится эхом, поэтому это связано с хеш-строками, но я не совсем понимаю, почему переход на 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 голосов
/ 22 января 2019

Последний оператор if определяет, будет ли выполняться запрос MySQL или нет.Поскольку вы говорите, что этот скрипт отображает "ошибку" из части else этого оператора, похоже, что хэши не совпадают.

Переменная $hash передается в строке URL в$_GET['hash'].Я предлагаю повторить $_GET['hash'] и $real_hash (после их вычисления при вызове MD5) и проверить, что они не являются идентичными строками.

Я догадываюсь, что значение $secretKey несоответствует ключу, который используется для генерации хэша, переданного в $_GET['hash'].Как намекает на комментарий, значение $secretKey должно соответствовать значению, используемому в Javascript, иначе хэши не будут совпадать.

Кроме того, вы можете обнаружить, что в реализации md5 Javascript есть разницапо сравнению с PHP.Они могут кодировать один и тот же вход, но возвращают немного разные хэши.

Редактировать: Это также может быть разница в кодировке символов между Javascript и PHP, поэтому строки ввода выглядят как разные (таким образом генерируя разные хэши).См .: идентичный md5 для JS и PHP и Создание одного и того же MD5 с использованием javascript и PHP .

Вы также используете значения $name и $score после они были экранированы, хотя mysqli_real_string_escape, поэтому я бы посоветовал убедиться, что часть Javascript также обрабатывает этот экранирование (чтобы входные строки совпадали) и чтобы функция экранирования msqli все еще работалаведет себя идентично предыдущей версии.Я бы посоветовал повторить значения $name и $score и убедиться, что они совпадают с тем, что использует сторона Javascript.Если вы используете более новый код на другом сервере, вам может потребоваться установить набор символов, соответствующий старому серверу.См. Предупреждение «Набор символов по умолчанию» в http://php.net/manual/en/mysqli.real-escape-string.php.

0 голосов
/ 22 января 2019

Хорошо, что вы тратите время на конвертацию, хотя конвертируйте полностью в объектно-ориентированный интерфейс, если вы хотите использовать 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();

Ключевым моментом здесь является использование подготовленных операторов со значениями заполнителей и всегда указание, в какие столбцы вы фактически вставляете.Вы не хотите, чтобы незначительное изменение схемы полностью сломало ваш код.

Первый шаг к решению сложной проблемы - устранить весь беспорядок в решении, чтобы ошибки стали более очевидными.

0 голосов
/ 22 января 2019

Одним из примечательных "уловок" является то, что порядок аргументов не совпадает между 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']); 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...