【问题标题】:How to use prepared statements with Postgres如何在 Postgres 中使用准备好的语句
【发布时间】:2009-08-07 22:58:43
【问题描述】:

我知道我需要准备好的语句,因为我在一个脚本中多次调用我的数据库。

我想获得有关 following sentence 的具体示例

查看类型转换、验证和清理变量以及将 PDO 与准备好的语句一起使用。

我知道他所说的验证和清理变量是什么意思。但是,我不完全确定准备好的陈述。我们如何准备陈述?通过过滤器,即通过消毒?还是通过一些 PDO 层?层的定义是什么?

准备好的语句在语句中是什么意思?请使用具体的例子。

【问题讨论】:

    标签: php postgresql pdo


    【解决方案1】:

    准备好的语句是什么意思 声明?

    来自documentation

    此功能允许将重复使用的命令只解析和计划一次,而不是每次执行。

    pg_prepare

    来自上面链接页面的示例:

    <?php
    // Connect to a database named "mary"
    $dbconn = pg_connect("dbname=mary");
    
    // Prepare a query for execution
    $result = pg_prepare($dbconn, "my_query", 'SELECT * FROM shops WHERE name = $1');
    
    // Execute the prepared query.  Note that it is not necessary to escape
    // the string "Joe's Widgets" in any way
    $result = pg_execute($dbconn, "my_query", array("Joe's Widgets"));
    
    // Execute the same prepared query, this time with a different parameter
    $result = pg_execute($dbconn, "my_query", array("Clothes Clothes Clothes"));
    ?>
    

    MySQL documentation for Prepared Statements 很好地回答了以下问题:

    • 为什么要使用准备好的语句?
    • 什么时候应该使用准备好的 声明?

    【讨论】:

    • 您的示例是否具有与 Robot 相同的功能?对我来说,它们比机器人的要清晰得多。他似乎使用了很多数组,这让我难以阅读。
    • @Masi - 我提供的示例来自 pg_prepare 文档页面。它们更容易理解,但我想说@Glass Robot 的示例更真实(例如,命名标记)。我建议你尽快弄脏你的手。没有“一个例子可以统治所有这些”。
    • 您的答案不使用 PDO。这表明我可以在没有 PDO 的情况下使用准备好的语句。 PDO 似乎只提供数据库独立性。
    • 好像pg_query = pg_prepare + pg_pg_execution - ability_to_run_a_list_vars_to_a_statement.
    • 请在上面或stackoverflow.com/questions/1247373/…查看我对您的回答的回复
    【解决方案2】:

    这意味着它将通过消除手动引用参数的需要来帮助您防止 SQL 注入攻击。

    您使用命名或问号标记代替将变量放入 sql 中,在执行语句时将替换实际值。

    PHP 手册中PDO 的定义:
    'PHP 数据对象 (PDO) 扩展定义了一个轻量级、一致的接口,用于在 PHP 中访问数据库。'

    参见PDOPDO::prepare 的php 手册。

    带有命名标记的预准备语句示例:

    <?php
    $pdo = new PDO('pgsql:dbname=example;user=me;password=pass;host=localhost;port=5432');
    
    $sql = "SELECT username, password
    FROM users
    WHERE username = :username
    AND password = :pass";
    
    $sth = $pdo->prepare($sql);
    $sth->execute(array(':username' => $_POST['username'], ':pass' => $_POST['password']));
    $result = $sth->fetchAll();
    

    带有问号标记的预处理语句示例:

    <?php
    $pdo = new PDO('pgsql:dbname=example;user=me;password=pass;host=localhost;port=5432');
    
    $sql = "SELECT username, password
    FROM users
    WHERE username = ?
    AND password = ?";
    
    $sth = $pdo->prepare($sql);
    $sth->execute(array($_POST['username'], $_POST['password']));
    $result = $sth->fetchAll();
    

    【讨论】:

    • 当用户名=a 和密码=a 时,您的命令似乎从表用户中选择用户名和密码列。这表明该代码在现实生活中不实用,因为当您已经知道它们时选择两个列名是没有意义的。但是,如果您根据两者选择第三列,那么您的方式似乎可行。似乎对用户的输入进行了处理,因此使用用户输入执行查询时的失败/意外不会改变原始数据,因此没有 SQL 注入:例如,如果准备失败则停止...
    【解决方案3】:

    我们如何准备报表:

    您可以一次性定义一个查询,并且可以使用不同的值随时调用它。 (例如,在一个循环中)

    $result = pg_prepare($dbconn, "my_query", 'SELECT * FROM shops WHERE name = $1');
    $result = pg_execute($dbconn, "my_query", array("Joe's Widgets"));
    $result = pg_execute($dbconn, "my_query", array("row two"));
    $result = pg_execute($dbconn, "my_query", array("row three"));
    

    见:http://us2.php.net/manual/en/function.pg-execute.php

    【讨论】:

      【解决方案4】:

      回复 Karim79 的回答

      这个

      $result = pg_prepare($dbconn, "query1", 'SELECT passhash_md5 FROM users WHERE email = $1');
      

      好像和这个一样

      $result = pg_prepare($dbconn, "query1", 'SELECT passhash_md5 FROM users WHERE email = ?');
      

      结论:使用pg_preparepg_execute 使PHP 更加高效,因为您不需要考虑清理。它还可以帮助您使用 PDO。

      【讨论】:

        猜你喜欢
        • 2020-08-20
        • 1970-01-01
        • 2014-12-16
        • 2021-02-04
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-12-18
        • 1970-01-01
        相关资源
        最近更新 更多