PDO - Fatal error: Call to a member function fetch() on a non-object(PDO - 致命错误:在非对象上调用成员函数 fetch())
问题描述
如果我尝试运行以下 PHP 代码,我会得到一个
if I try to run the following PHP code, I get a
在非对象上调用成员函数 fetch().
Call to a member function fetch() on a non-object.
你知道为什么吗?我在另一个网站上使用相同的代码,它工作得很好.
Do you know why? I use the same code on another site, where it works just fine.
<?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();
<小时>
这看起来安全吗,我应该做更多吗?
Does this look safe, should I do more ?
<?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代码>在底部.
Your code has the variable $username
in the top part of your question, but you then have $user
in the bottom section.
您是否打算使用相同的变量?
Are you perhaps meaning to use the same variable?
$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
很可爱.观察这一点:
Okay, now you are just being cute with your PDO::ATTR_EMULATE_PREPARES
. Observe this:
数据库和表结构:
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 属性:
And some PHP code that is copied from yours, with the added PDO attribute:
<?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.
";
print_r($sth->fetch());
echo "----------------------------------------
";
?>
<?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.
";
print_r($sth->fetch());
echo "----------------------------------------
";
?>
<?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.
";
print_r($sth->fetch());
echo "----------------------------------------
";
?>
<?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.
";
print_r($sth->fetch());
echo "----------------------------------------
";
?>
<?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.
";
print_r($sth->fetch());
echo "----------------------------------------
";
?>
<?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.
";
print_r($sth->fetch());
echo "----------------------------------------
";
?>
还有输出:
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;
.
----------------------------------------
哦,我把最后一个留到最后一个的原因是这个输出现在在我的数据库中:
Oh, the reason I left the last one till LAST is this output now in my database:
mysql> show tables;
Empty set (0.00 sec)
是的,没错,我刚刚丢了一张桌子.让我再说一遍,我有一个 select 语句,我用一个小技巧输入了一个值,任何有半脑和一些恶意意图的人都可以在文本字段中执行,然后删除你的表.
Yes, that's right, I just dropped a table. Let me say that again, I had a select statement, and with a little trickery I entered in a value that ANYONE with half a brain and some malicious intent could do into a text field, and DROPPED YOUR TABLE.
现在,当然,如果您设置正确,您可能会为 select 语句设置一个不同的用户,并且只授予他们数据库中的 select
权限,以停止这种事情正在发生 - 但老实说......你不是吗?
Now, granted, if you are setting things up properly, you might well set up a different user for the select statements, and only grant them select
rights from your database, to stop this sort of thing happening - but lets be honest... you aren't are you?
显然设置模拟是不够的.说真的,现在请务必阅读该答案,如果您想在代码中保持安全,请使用准备好的语句并使用参数.
Clearly setting that emulation is not enough. Seriously, now PLEASE do go read that answer, use prepared statements and use params if you want to be secure in your code.
这篇关于PDO - 致命错误:在非对象上调用成员函数 fetch()的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:PDO - 致命错误:在非对象上调用成员函数 fetch()
基础教程推荐
- Libpuzzle 索引数百万张图片? 2022-01-01
- 在多维数组中查找最大值 2021-01-01
- 如何在 PHP 中的请求之间持久化对象 2022-01-01
- 通过 PHP SoapClient 请求发送原始 XML 2021-01-01
- WooCommerce 中选定产品类别的自定义产品价格后缀 2021-01-01
- mysqli_insert_id 是否有可能在高流量应用程序中返回 2021-01-01
- 超薄框架REST服务两次获得输出 2022-01-01
- 在 PHP 中强制下载文件 - 在 Joomla 框架内 2022-01-01
- 在 Woocommerce 中根据运输方式和付款方式添加费用 2021-01-01
- XAMPP 服务器不加载 CSS 文件 2022-01-01