mysqli_fetch_asso c () ожидает, что параметр 1 будет mysqli_result, строка задана в цикле while - PullRequest
0 голосов
/ 04 февраля 2020

У меня сейчас есть этот код, но он выдает мне ошибку mysqli_fetch_assoc() expects parameter 1 to be mysqli_result, string given on line 22

Код такой:

1   $servername = "localhost";
2   $user = "root";
3   $pass = "";
4   $db = "mafioso";
5
6   $con = mysqli_connect($servername, $user, $pass, $db);
7
8   $cash_utbetaling[0] = 50000000;
9   $cash_utbetaling[1] = 40000000;
10  $cash_utbetaling[2] = 30000000;
11  $cash_utbetaling[3] = 20000000;
12  $cash_utbetaling[4] = 10000000;
13
14  $kuler_utbetaling[0] = 25;
15  $kuler_utbetaling[1] = 20;
16  $kuler_utbetaling[2] = 15;
17  $kuler_utbetaling[3] = 10;
18  $kuler_utbetaling[4] = 5;
19
20  $i = 0;
21  $result = mysqli_query($con, "SELECT * FROM daily_exp ORDER BY exp DESC LIMIT 5");
22  while($row_best = mysqli_fetch_assoc($result)) {
23    
24    $acc_id = $row_best['acc_id'];
25
26    $sql = "SELECT * FROM accounts WHERE ID='".$acc_id."'";
27    $query = mysqli_query($con, $sql) or die (mysqli_error());
28    $row_top5 = mysqli_fetch_assoc($query);
29    
30    $result = "UPDATE accounts SET money = (money + ".$cash_utbetaling[$i]."), 
      bullets = (bullets + ".$kuler_utbetaling[$i].")  WHERE ID = ".$acc_id."";
31    mysqli_query($con, $result) or die("Bad query: $result");
32
33    $i++;
34  }

Кажется, я не могу найти ошибку, я работаю тот же код в другом файле и нет проблем.

Ответы [ 2 ]

2 голосов
/ 04 февраля 2020

Вы перезаписываете $result

// This is supposed to be
//  a mysqli_result object ----------v-----v
while($row_best = mysqli_fetch_assoc($result)) 
{
    // some code
    // $result is now a string. Next iteration will raises the warning
    $result = "UPDATE accounts SET ...";
}

Так что вам нужно дать своим переменным разные имена. Называть запрос $result не лучшим выбором.


Примечание:

Ваши внутренние запросы уязвимы для SQL инъекций. Один должен использовать подготовленные операторы вместо конкатенирующих строк.

Например:

// prepare the query
$query = "SELECT * FROM accounts WHERE ID=?";
if ($stmt = mysqli_prepare($con, $query)) {

    // bind the param
    mysqli_stmt_bind_param($stmt, "s", $acc_id);

    // execute the query
    mysqli_stmt_execute($stmt);

    // get the result. Of course, avoir using the same variable name, again :)
    $result = mysqli_stmt_get_result($stmt);
}

Для получения дополнительной информации о подготовленных операторах с помощью mysqli читайте официальную документацию или учебные пособия , написанные @ YourCommonSense

1 голос
/ 04 февраля 2020

Ваша главная проблема здесь в том, что вы назвали переменную запроса SQL тем же именем, что и результат, который вы использовали в то время как l oop. Вы перезаписываете его строкой в ​​строке 30:

30    $result = "UPDATE accounts SET money = (money + ".$cash_utbetaling[$i]."), 
      bullets = (bullets + ".$kuler_utbetaling[$i].")  WHERE ID = ".$acc_id."";

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

mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
$con = mysqli_connect("localhost", "root", "", "mafioso");
$con->set_charset('utf8mb4');


$cash_utbetaling[0] = 50000000;
$cash_utbetaling[1] = 40000000;
$cash_utbetaling[2] = 30000000;
$cash_utbetaling[3] = 20000000;
$cash_utbetaling[4] = 10000000;
$kuler_utbetaling[0] = 25;
$kuler_utbetaling[1] = 20;
$kuler_utbetaling[2] = 15;
$kuler_utbetaling[3] = 10;
$kuler_utbetaling[4] = 5;
$i = 0;

$result = mysqli_query($con, "SELECT * FROM daily_exp ORDER BY exp DESC LIMIT 5");
$daily_exp = $result->fetch_all(MYSQLI_ASSOC);

// prepare update
$stmt = $con->prepare('UPDATE accounts SET money = (money + ? ), bullets = (bullets + ? ) WHERE ID=?');

foreach ($daily_exp as $row_best) {
    $stmt->bind_param('sss', $cash_utbetaling[$i], $kuler_utbetaling[$i], $row_best['acc_id']);
    $stmt->execute();
    $i++;
}
  1. Вам нужно включить отчеты об ошибках вместо использования or die (mysqli_error()), которое никогда не будет работать из-за отсутствия аргумента.
  2. Не используйте пока l oop до go через результаты. Гораздо лучше получить все записи сразу или l oop в результате, используя foreach. Если бы вы воспользовались моим предложением, то, скорее всего, вы бы вообще избежали опечатки.
  3. Вы должны использовать подготовленные заявления. В вашем коде значения являются целыми числами и константами, но я предполагаю, что в какой-то момент вы будете использовать переменные, что означает, что вам нужно использовать заполнители и параметры.
  4. Запрос SELECT внутри l oop ничего не делал, поэтому я удалил его из своего ответа.
  5. Вам следует избегать проблемы N + 1 запросов. Попробуйте сделать то же самое в одном запросе, только если это возможно.
...