если я попытаюсь запустить следующий код 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 получает ошибку при попытке прочитать ее «вручную».