Где мы должны использовать метод fetch_assoc?

Я начал этот небольшой блог-проект и думаю, что только что совершил ошибку, не включив метод fetch_assoc. Это код:

$data = new database();
$sql = "SELECT * FROM post ";
 $article = $data->select($sql);
 foreach ($article as  $value) : ?>
 <div class="blog-post">
<h2 class="blog-post-title"><?= $value["blog_title"]; ?></h2>

и вот как выглядит метод выбора:

public function select($sql){
     $result = $this->con->query($sql) or die($this->con->error.__LINE__);
     if ($result->num_rows > 0) {
        return $result;
     }else {
       return false;
     }
}

Я хочу знать, почему это сработало для меня (название блога отображается правильно), хотя я забыл поставить метод fetch_assoc?


person Fares Ars    schedule 04.07.2020    source источник


Ответы (1)


Вам не нужно использовать fetch_assoc() большую часть времени. Если вы пишете какой-то класс абстракции вокруг mysqli, вам никогда не придется напрямую использовать какие-либо функции mysqli.

mysqli:query() возвращает объект типа mysqli_result, который является итерируемым. Это означает, что вы можете использовать цикл foreach для его повторения.

Я должен указать, что вы все еще следуете некоторым плохим методам программирования. Вы никогда не должны использовать or die($this->con->error.__LINE__). Это ужасная практика кодирования и совершенно не нужная. Вместо этого вы должны включить правильную отчетность об ошибках. См. Как получить сообщение об ошибке в MySQLi?

Ваш метод select() должен возвращать только массив. Это сделало бы ваш код намного проще и менее подверженным ошибкам. Итак, перепишите свою функцию select() следующим образом:

public function select($sql){
    return $this->con->query($sql)->fetch_all(MYSQLI_ASSOC);
}

Как видите, вся функциональность представляет собой одну строку кода, а это означает, что ваш метод select() не очень полезен. Вместо этого вы можете заменить его чем-то более общим. Таким образом, вы избегаете большого количества повторений кода.

public function executeQuery(string $sql, array $params = []): ?array {
    // Prepare/bind/execute
    $stmt = $this->con->prepare($sql);
    if ($params) {
        $stmt->bind_param(str_repeat("s", count($params)), ...$params);
    }
    $stmt->execute();
    // If it was a select query which gives result then return results in an array
    if ($result = $stmt->get_result()) {
        return $result->fetch_all(MYSQLI_BOTH);
    }
    // If it is INSERT/UPDATE then return null instead of array
    return null;
}

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

person Dharman    schedule 04.07.2020
comment
спасибо @Dharman за ваш ответ, но bind_param(str_repeat("s",count($params)), ...$params) у нас могут быть другие вещи, такие как целое число, поэтому нам нужно d вместо s и для $params я думаю, нам нужен цикл для всех параметры помещаются в виде массива в executeQuery methode - person Fares Ars; 05.07.2020
comment
@FaresArs В 99,99% случаев вам не нужно ничего, кроме строки. Но если вам нужно указать тип вручную, я рекомендую прочитать эту короткую статью: phpdelusions.net/mysqli/simple< /а> - person Dharman; 05.07.2020