PDO – Неустранимая ошибка: вызов функции-члена функции fetch () для объекта, не являющегося объектом

если я попытаюсь запустить следующий код PHP, я получаю

Вызовите функцию-член функции fetch () для не-объекта.

Ты знаешь почему? Я использую тот же код на другом сайте, где он работает отлично.

<?php $username = ($_GET ['user']); try { $dbh = new PDO("mysql:host=localhost;dbname=***", '***', '***'); } catch (PDOException $e) { echo $e->getMessage(); } $sth = $dbh->query( "SELECT user, captcha FROM xf_captcha WHERE user='$username'" ); print_r($sth->fetch()); ?> 

Редактировать:

 $sth = $dbh->query( "SELECT username, user_state, last_activity, alerts_unread, conversations_unread, message_count FROM xf_user WHERE username='$user'" ); $row = $sth->fetch(); 

Edit2:

Означает ли это, что я должен делать больше?

 <?php $username = ($_GET ['user']); try { $dbh = new PDO("mysql:host=localhost;dbname=***", '***', '***'); } catch (PDOException $e) { echo $e->getMessage(); } $sth = $dbh->prepare("SELECT username, captcha, timestamp FROM xf_captcha WHERE username = :username", array(PDO::ATTR_CURSOR => PDO::CURSOR_FWDONLY)); $sth->execute(array(':username' => $username)); print_r($sth->fetch()); ?> 

У вашего кода есть переменная $username в верхней части вашего вопроса, но тогда у вас есть $user в нижней части.

Возможно, вы имеете в виду использовать одну и ту же переменную?

 $username = ($_GET ['user']); $sth = $dbh->query( "SELECT username, user_state, last_activity, alerts_unread, conversations_unread, message_count FROM xf_user WHERE username='$user'" ); // ^^ Should this ALSO be $username ? $row = $sth->fetch(); 

Изменить: Хорошо, теперь вы просто PDO::ATTR_EMULATE_PREPARES с PDO::ATTR_EMULATE_PREPARES . Обратите внимание:

Структура базы данных и таблицы:

 Database changed mysql> show tables -> ; +----------------+ | Tables_in_prep | +----------------+ | users | +----------------+ 1 row in set (0.00 sec) mysql> select * from users; +----+---------+--------+ | id | userid | pass | +----+---------+--------+ | 1 | Fluffeh | mypass | +----+---------+--------+ 1 row in set (0.00 sec) 

И некоторый код PHP, который скопирован с вашего, с добавленным атрибутом PDO:

 <?php //$username = ($_GET ['user']); $username="Fluffeh"; $dbh = new PDO('mysql:host=localhost;dbname=prep', 'prepared', 'example'); $dbh->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_OBJ); $sth = $dbh->query( "SELECT userid, pass FROM users WHERE userid='$username'" ); echo "Trying to use $username.\n"; print_r($sth->fetch()); echo "----------------------------------------\n\n"; ?> <?php //$username = ($_GET ['user']); $username="user2693017"; $dbh = new PDO('mysql:host=localhost;dbname=prep', 'prepared', 'example'); $dbh->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_OBJ); $sth = $dbh->query( "SELECT userid, pass FROM users WHERE userid='$username'" ); echo "Trying to use $username.\n"; print_r($sth->fetch()); echo "----------------------------------------\n\n"; ?> <?php //$username = ($_GET ['user']); $username="Oh my' or 1=1 or 'm=m"; $dbh = new PDO('mysql:host=localhost;dbname=prep', 'prepared', 'example'); $dbh->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_OBJ); $sth = $dbh->query( "SELECT userid, pass FROM users WHERE userid='$username'" ); echo "Trying to use $username.\n"; print_r($sth->fetch()); echo "----------------------------------------\n\n"; ?> <?php //$username = ($_GET ['user']); $username="(select id from users limit 1)"; $dbh = new PDO('mysql:host=localhost;dbname=prep', 'prepared', 'example'); $dbh->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_OBJ); $sth = $dbh->query( "SELECT userid, pass FROM users WHERE id='$username'" ); echo "Trying to use $username.\n"; print_r($sth->fetch()); echo "----------------------------------------\n\n"; ?> <?php //$username = ($_GET ['user']); // Changed this one to be a non-string, you might be checking an ID instead. $username="(select id from users limit 1)"; $dbh = new PDO('mysql:host=localhost;dbname=prep', 'prepared', 'example'); $dbh->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_OBJ); $sth = $dbh->query( "SELECT userid, pass FROM users WHERE id=$username" ); echo "Trying to use $username.\n"; print_r($sth->fetch()); echo "----------------------------------------\n\n"; ?> <?php //$username = ($_GET ['user']); $username="bob'; drop table users; \ "; // This one is tricker to do in PHP code. I could easily enter this into a text field however. $dbh = new PDO('mysql:host=localhost;dbname=prep', 'prepared', 'example'); $dbh->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_OBJ); //$sth = $dbh->query( "SELECT userid, pass FROM users WHERE id='$username'" ); echo "Trying to use $username.\n"; print_r($sth->fetch()); echo "----------------------------------------\n\n"; ?> 

И выход:

  Trying to use Fluffeh. stdClass Object ( [userid] => Fluffeh [pass] => mypass ) ---------------------------------------- Trying to use user2693017. ---------------------------------------- Trying to use Oh my' or 1=1 or 'm=m. stdClass Object ( [userid] => Fluffeh [pass] => mypass ) ---------------------------------------- Trying to use (select id from users limit 1). ---------------------------------------- Trying to use (select id from users limit 1). stdClass Object ( [userid] => Fluffeh [pass] => mypass ) ---------------------------------------- Trying to use bob'; drop table users; \ . ---------------------------------------- 

О, причина, по которой я оставил последний, до тех пор, пока LAST не появится в моей базе данных:

 mysql> show tables; Empty set (0.00 sec) 

Да, правильно, я просто уронил стол. Позвольте мне сказать, что снова, у меня было отборное заявление, и с небольшим обманом я ввел значение, которое ЛЮБОЙ с половиной мозга и некоторые злонамеренные намерения могли бы сделать в текстовое поле, и УДАЛИТЬ ВАШУ ТАБЛИЦУ.

Теперь, если вы правильно настроите настройки, вы можете настроить другого пользователя для операторов select и предоставить им только права select из своей базы данных, чтобы остановить подобное, но давайте будем честными … вы не так ли?

Очевидно, что настройка эмуляции недостаточна. Серьезно, теперь ПОЖАЛУЙСТА, прочитайте этот ответ , используйте подготовленные инструкции и используйте параметры, если вы хотите быть в безопасности в своем коде.

Где вызывается оператор Execute? Это также внутри вашего ->query ? Если вы не думаете об использовании следующего для лучшего построения запроса:

 <?php $username = ($_GET['user']); try { $dbh = new PDO("mysql:host=localhost;dbname=***", '***', '***'); } catch (PDOException $e) { echo $e->getMessage(); } $statement = "SELECT user, captcha FROM xf_captcha WHERE user=:username"; //If you have query as a method(Which I don't think so but if you can change "prepare" to your "query" $sth = $dbh->prepare($statement); $sth->execute(array(":username" => $username)); $row = $sth->fetch(PDO::FETCH_ASSOC); ?> 

В круглых скобках вы можете использовать массив для заполнения параметра :username для переменной $username

Я думаю, что изучение примеров PDO Class также может быть полезно для лучшего понимания PDO и методов (вы также можете обратиться к руководству PHP PDO)

Это происходит, когда таблица также не существует. убедитесь, что он на самом деле существует, и не только является держателем в базе данных из-за ошибок жесткого диска.

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