php SQL PDO-> Fetch()问题

时间:2011-08-31 10:36:16

标签: php mysql pdo

<?php
$g_id=$_GET['gid'];

// $one = $pdo->query("SELECT * FROM contactgroups WHERE id=".$g_id);
// $result = $one->fetch();
?>

Rename groupname: <input type="text" placeholder="<?php // $one['gr_name']; ?>">

这是我的小代码,它根本不起作用,我找不到我做错了什么。任何帮助将不胜感激。

2 个答案:

答案 0 :(得分:4)

  • 您的PHP代码已注释
  • 您没有致电echo
  • 您正在使用$one而不是$result
  • 您没有对输入进行消毒,这不会导致此问题,但应该修复它。消毒就像$g_id = intval( $_GET['gid'] );一样简单,但我建议调查prepared statements

话虽如此,这应该有效:

<?php
$g_id=$_GET['gid']; 

$one = $pdo->query("SELECT * FROM contactgroups WHERE id=".$g_id);
$result = $one->fetch();
?>

Rename groupname: <input type="text" placeholder="<?php echo $result['gr_name']; ?>">

答案 1 :(得分:2)

结果存储在$result数组中,而不是PDO对象$one中。如果你不打算使用短标签,这也需要回声。

<input type="text" placeholder="<?php echo $result['gr_name']; ?>">

我使用的是shorttags,所以如果PHP安装程序已启用它们,但它们在PHP 5.6中已被弃用:

<input type="text" placeholder="<?= $result['gr_name']; ?>">

您现在可以使用短标签,我将继续使用它们来抗议删除这个非常有用的功能。弃用短标签会破坏很多WP主题和简单的模板引擎!

您还应该考虑使用prepared statements。没有它们,这个脚本很容易受到SQL注入。

<?php
$query = $pdo->prepare("SELECT * FROM contactgroups WHERE id=:id");
if( $query->execute(array(':id' => $_GET['id'])) ) {
    $result = $query->fetch();
?>
<input type="text" placeholder="<?php echo $result['gr_name']; ?>" />
<?php } ?>

PDO如何阻止SQL注入(太长时间无法发表评论 - 向下滚动以查看更好的解释)
让我们从查询开始:

mysql_query("DELETE FROM users WHERE id='".$id."'");

如果$id = "' OR 1=1 --";,那么当发送给MySQL时,查询看起来像这样( - 表示评论的开始):

DELETE FROM users WHERE id='' OR 1=1 --'

显然,随之而来的破坏可能是灾难性的,也可能是不可逆转的(除非你有一些聪明的数据库管理员)。这里的修复而不是使用冗长的mysql_real_escape_string()(我真的从来没有理解为什么函数名称首先如此冗长),我们现在可以使用PDO预处理语句。

通过PDO::preparing()声明您正在向您的数据库发送一条消息,告诉它存储并优化此查询,因为它将在以后使用。您的数据库存储优化查询,请仔细记录数据所在的位置。

$statement = $pdo->prepare('DELETE FROM users WHERE id=:id');

PDO将为您提供PDOStatement的实例,您可以PDO::bindParam()对其进行值和执行。所以,让我们这样做并执行。

$statement->bindParam(':id', $id);
$statement->execute();

现在一些幕后魔术发生在这里。 PDO将数据发送到MySQL。 MySQL检查数据并插入准备好的语句中。通过了解数据的放置位置和插入数据的长度,MySQL可以确定查询中不需要执行的字符范围(读取:数据)。 因此,当黑客尝试SQL注入时,MySQL甚至不会担心评估绑定到预准备语句的任何内容。

  1. PDO对MySQL说"The data for :id is ' OR 1=1 --"
  2. MySQL找到以下位置:id在预准备语句中。 (在本例中,字符28)
  3. MySQL计算数据的长度(在本例中为11个字符)
  4. MySQL完成一年级数学,并记得它应该将字符28到39之间的所有内容视为字符。
  5. MySQL插入数据,现在查询如下:

    DELETE FROM users WHERE id=' OR 1=1 --

  6. 但是,因为它知道数据的位置,所以MySQL只分析管道(|)之外的所有命令和关键字。

    DELETE FROM users WHERE id=|' OR 1=1 --|

  7. 因此管道之间的文本实际上从未被分析过。当MySQL需要比较id时,它仍然将表中的id与数据进行比较,但由于数据从未执行过,因此SQL注入失败。

    更好地解释PDO如何阻止SQL注入

    当我们使用PDO准备语句时,它会通知数据库即将出现的查询以及数据在查询中的位置。当我们将数据绑定到该查询并执行它时,数据库会在幕后工作,以确保阻止SQL注入。
    让我们将幕后工作带到另一个背景下。您管理一个PHP博客,您的引擎完全由您自己编写。你为自己写的一个聪明的评论系统感到自豪,直到一些混蛋决定发表这个评论:

    <script type="text/javascript">
    alert('You just been H4X0RED!!!!1 LOLS');
    </script>
    

    在计算机屏幕上大喊四个字母后,确保脚本小子的父母再也没有让他上网,你用htmlspecialchars()解决了代码中的XSS漏洞。

    $comment_text = htmlspecialchars($_POST['comment_text']);
    

    现在你在这做了什么?当脚本小子在凌晨3点醒来并偷偷溜到他的电脑再次尝试代码时,htmlspecialchars()将他蹩脚的幽默尝试变成了乱七八糟的混乱。该函数接受HTML中重要的任何字符(即<>),并将它们转换为字面值(&lt;&gt;)。

    &lt;script type=&quot;text/javascript&quot;&gt;
    alert('You just been H4X0RED!!!!1 LOLS');
    &lt;/script&gt;
    

    每个人的浏览器中的HTML解析器都将&lt解释为不是HTML标记的开头,而是作为实际输出字符<的标志。这基本上是数据库引擎对输入到预准备语句中的所有数据所做的事情。除了在SQL字母组成有效命令(以及有效数据)之外,引擎会将数据中的所有字符解释为其文字值。所以而不是:

    DELETE FROM users WHERE id = 0 OR 1=1 --'
    

    它评估数据中的每个字符,因为它是字面值。在HTML中将是:

    DELETE FROM users WHERE id = &#48;&#32;&#79;&#82;&#32;&#49;&#61;&#49;&#32;&#45;&#45;&#39;
    

    如果你看both here,他们都输出相同的东西,除了第二个,'数据'被解析器解释为它的文字值而不是它的功能值。 SQL做同样的事情。通过使用数据的文字值,任何实际数据都不能被解释为命令或一部分。