-1
public static function getNewsList()
{

    $db = DB::getConnection();

    $newList = array();

    $sql = $db->query('SELECT id, title, date, short_content '
        . 'FROM news '
        . 'ORDER BY date DESC '
        . 'LIMIT 10 ');
    if (!$sql) {
        echo "\nPDO::errorInfo():\n";
        print_r($db->errorInfo());
    }
    $result = $db->prepare($sql);
    $result->setFetchMode(PDO::FETCH_ASSOC);
    $result->execute();

    var_dump($result);
    $i = 0;
    while ($row = $result->fetch()) {
        $newList[$i]['id'] = $row['id'];
        $newList[$i]['title'] = $row['title'];
        $newList[$i]['data'] = $row['data'];
        $newList[$i]['short_content'] = $row['short_content'];
        $i++;
    }

    return $newList;

}

var_dump($result); возвращает object(PDOStatement)#4 (1) { ["queryString"]=> string(0) "" }

А PDO::errorInfo() - PDO::errorInfo(): Array ( [0] => 3D000 [1] => 1046 [2] => No database selected )

Привет, первым делом воспользовался поиском, но ответа не нашел. Выдает ошибку:

Fatal error: Call to a member function fetch() on a non-object in E:\OSPanel\domains\mysite.local\models\News.php on line 38

Я так понимаю это связано с тем, что var_dump($result) выводит bool(false). Я не пойму как найти ошибку. Помогите пожалуйста.

Код БД class Db

{

    public static function getConnection()
    {
        $paramsPath = ROOT .'../config/db_params.php';
        $params = include($paramsPath);
        $dsn = "mysql: host = {$params['host']}; dbname = {$params['dbname']}";
        $db = new PDO($dsn, $params['user'], $params['password']);
        $db->exec("set names utf8");

        return $db;
    }
}

и db_params

<?php

return [
    'host' => 'localhost',
    'dbname' => 'mvc_site',
    'user' => 'root',
    'password' => ''
];
  • http://php.net/manual/ru/pdo.errorinfo.php – Mike Nov 22 '17 at 17:15
  • @Mike Вопрос задается миллион раз, а ни одного ответа с указанием посмотреть код ошибки, что-то не могу найти – Anton Shchyrov Nov 22 '17 at 17:22
  • @AntonShchyrov что подталкивает на идею создать нормальный вопрос-ответ каноничный по данной проблематике ;-) – Алексей Шиманский Nov 22 '17 at 17:29
  • @AndriiShchur - выведи описание ошибки, чтоб посмотреть чем окончился запрос – Алексей Шиманский Nov 22 '17 at 17:30
  • No database selected - ну собссн надо смотре connect почему база не выбрана – Алексей Шиманский Nov 22 '17 at 17:44
  • 1
    @AntonShchyrov Ну ответ есть https://ru.stackoverflow.com/questions/423439/mysql-fetch-array-expects-parameter-1-to-be-resource-or-mysqli-result-boole только он для другого расширения работы с БД, смысл тот же, только сообщение об ошибке по другому звучит – Mike Nov 22 '17 at 17:46
  • Если использовать mysqli, то все работает. Но мне нужно решить данную проблему с PDO. – Andrii Shchur Nov 22 '17 at 17:49
  • @AndriiShchur пробелы не нужны вот тут : mysql: host = {$params['host']}; dbname = {$params['dbname']} - всё надо без пробелов – Алексей Шиманский Nov 22 '17 at 17:52
  • Убрал пробелы, теперь выдает

    Warning: PDO::prepare() expects parameter 1 to be string, object given in E:\OSPanel\domains\mysite.local\models\News.php on line 40

    Fatal error: Call to a member function setFetchMode() on a non-object in E:\OSPanel\domains\mysite.local\models\News.php on line 41

    – Andrii Shchur Nov 22 '17 at 17:55
  • Я убрал пробелы в класе БД и убрал вот эту часть $result = $db->prepare($sql); $result->setFetchMode(PDO::FETCH_ASSOC);

    Ошибок больше нет, и var_dump($result) выводит object(PDOStatement)#4 (1) { ["queryString"]=> string(76) "SELECT id, title, date, short_content FROM news ORDER BY date DESC LIMIT 10 " }.

    Теперь осталось разобраться с выводом на экран моих данных.

    – Andrii Shchur Nov 22 '17 at 18:06

3 Answers3

1

При создании объекта PDO необходимо задать режим выброса исключений при ошибках, чтобы БД сама сообщала, что именно в твоем коде не так. Самый простой вариант, дописать после коннекта строчку

$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

После этого надо прочесть сообщение об ошибке. Обычно этого достаточно, чтобы понять, в чем проблема. В данном случае проблема была в украшениях, добавленных в DSN в виде ненужных пробелов.

Остальной код также требует переделки.

Класс Database берем отсюда. Это важно, поскольку в момент, когда приложение перерастет из домашней странички про котиков во что-то полезное, оно начнет убивать сервер БД одновременными коннектами.

Дальше учим ПДО и пишем свой код в две строчки.

$sql = 'SELECT id, title, date, short_content FROM news ORDER BY date DESC LIMIT 10';
$newList = MyPDO::instance()->query($sql)->fetchAll();

Дальше надо будет учить ООП и не писать ужас типа "public static function getNewsList()" но это уже совсем другая история.

  • Спасибо, за совет. Буду разбираться! А что ни так с "public static function getNewsList()" ? Я думал, что как раз ООП здесь и использую. – Andrii Shchur Nov 28 '17 at 12:11
-1

Всем большое спасибо! 1. в соединении с БД нужно было убрать пробелы в строке с $dsn

 public static function getConnection()
    {
        $paramsPath = ROOT .'../config/db_params.php';
        $params = include($paramsPath);
        $dsn = "mysql:host={$params['host']};dbname={$params['dbname']}";
        $db = new PDO($dsn, $params['user'], $params['password']);
        $db->exec("set names utf8");

        return $db;
    }

2. В изначальном коде нужно было добавить $result->execute(); после выборки из БД

public static function getNewsList()
    {

        $db = DB::getConnection();

        $newList = array();

        $result = $db->query('SELECT id, title, date, short_content '
            . 'FROM news '
            . 'ORDER BY date DESC '
            . 'LIMIT 10 ');

        $result->execute();

        $i = 0;
        while ($row = $result->fetch()) {
            $newList[$i]['id'] = $row['id'];
            $newList[$i]['title'] = $row['title'];
            $newList[$i]['date'] = $row['date'];
            $newList[$i]['short_content'] = $row['short_content'];
            $i++;
        }
        return $newList;
    }
-2

Причина:

$result->execute();

Попробуйте так:

public static function getNewsList() {

$db = DB::getConnection();


$sql = ('SELECT id, title, date, short_content '
    . 'FROM news '
    . 'ORDER BY date DESC '
    . 'LIMIT 10 ');

$result = $db->prepare($sql);
$result->setFetchMode(PDO::FETCH_ASSOC);
$result->execute();

$i = 0;
$newList= array();
while ($row = $result->fetch()) {
    $newList[$i]['id'] = $row['id'];
    $newList[$i]['title'] = $row['title'];
    $newList[$i]['data'] = $row['data'];
    $newList[$i]['short_content'] = $row['short_content'];
    $i++;
}

return $newList;
}
artem55555p
  • 1,204
  • почему -1?, объясните пожалуйста – artem55555p Nov 22 '17 at 17:21
  • предположу, что не написано, что именно не так было и что изменилось...... ну и execute нет - что соответственно неверно – Алексей Шиманский Nov 22 '17 at 17:22
  • @Алексей Шиманский ну я ответ еще правил, не успел дописать, а уже минусуют.. я добавил execute – artem55555p Nov 22 '17 at 17:23
  • тем не менее, что именно было добавлено и что не так - не описано. что поменялось?....ну и зачем писать полусырой ответ? вот и карма) А теперь поди сыщи кто поставил минус) – Алексей Шиманский Nov 22 '17 at 17:24
  • @Алексей Шиманский ну я сейчас вот написал полный ответ.... – artem55555p Nov 22 '17 at 17:25
  • хотел быть первым, а получил минус, ну вот где справедливость... – artem55555p Nov 22 '17 at 17:25
  • Ну тот кто поставил минус очевидно увидел неправильный ответ, поставил и пошел дальше. – Алексей Шиманский Nov 22 '17 at 17:28
  • Выдало новые, ошибки, это уже интереснее, буду разбираться пока. спасибо – Andrii Shchur Nov 22 '17 at 17:30
  • @Andrii Shchur какие? – artem55555p Nov 22 '17 at 17:30
  • Ошибка невнимательности, исправил. После добавления $result = $db->prepare($sql); $result->setFetchMode(PDO::FETCH_ASSOC); $result->execute(); делаю вывод var_dump($result); object(PDOStatement)#4 (1) { ["queryString"]=> string(0) "" } – Andrii Shchur Nov 22 '17 at 17:37
  • А в чем смысл пробовать именно так, а не как у автора? – Ипатьев Nov 24 '17 at 11:36