具有命名参数的VSO语句VS问号参数

时间:2013-04-06 18:56:00

标签: php pdo

我有一个用于数据库管理的类,我的一个子类(定义查询的子类)是这样定义的(只是一个示例,许多其他函数实际上被剥离用于测试目的):

namespace Tests\SQL\Arguments {
    // SQL query
    class Query {
        public $attributes;

        // constructor for this object
        public function __construct() {
            if ($arguments = func_get_args()) {
                $this->attributes["query"] = current($arguments);

                if (sizeof($arguments) > 1) {
                    $this->attributes["parameters"] = array_slice($arguments, 1, sizeof($arguments));
                }

                return $this;
            }
        }
    }

    $query = new Query("INSERT INTO `clients/history` (`date`,`client`,`ammount`,`status`) VALUES (?,?,?,?);", date("Y-m-d H:i:s"), 57, 17852.25, "A");
    print_r($query);
}

正如您所看到的,我会自动获取函数参数,因此我可以在构造时轻松地将查询与其参数分开。除了批量INSERT/UPDATE/DELETE操作之外,我还想提供一些安全性,例如防止SQL注入和其他事情。

我的问题是......鉴于这种结构,当我传递这样的结构时(只是一个简单的例子,它将以不同的方式运行,但这一个暂时有效 ):

$this->queries["clients/history"]->execute($this->attributes["query"], $this->attributes["parameters"]);

使用(:date,:client,:ammount,:status)等命名参数或使用(?,?,?,?)等问号参数会有什么不同吗?

编辑 - 更好的解释

很抱歉我的问题带来的(明显的)模糊不清。我的意图是有一个类似于sprintf的机制,但是,我只是以一种单独的方式存储查询和参数,而不是存储一个包含所有参数的字符串。

这只是Query类。还有QueryGroup类(用于存储组中的查询),Manager类(存储和管理所有数据库连接)和Connection类(它负责将给定数据库连接的所有查询和查询组保存在一起。

关于命名参数,我发现我正在使用的方法没有问题,因为这像我说的那样有效,就像sprintf函数一样。我将在查询字符串中提供问号或参数名称。

我想进行分离以提供额外的过滤功能,例如转义或引用参数,以防止某些形式的注入或破坏给定数据库。

我公开的execute()方法只是PDO的execute()方法的纸质副本。我试图确定的是,使用命名参数或问号参数是否同样“安全”(或者可能存在一些差异,我没有看到)。

任何提示都将不胜感激:)

3 个答案:

答案 0 :(得分:5)

命名的未命名参数之间的区别在于,对于未命名的参数,您必须注意它们将与查询绑定的顺序。

特别是在你的例子中,未命名的params非常适合,因为它可以简化函数调用。


进一步请注意,您无需在构造函数方法中调用return $this;

答案 1 :(得分:1)

在你的情况下它应该没有区别。

答案 2 :(得分:1)

虽然没有技术差异(因为PDO会在内部将命名占位符替换为问号),但是存在可用性问题

对于类似sprintf的函数问号似乎是一个更好的解决方案。因为他们会让你使用sprintf风格(不知道你为什么要为查询创建一个完整的类):

$query = new Query("SELECT * FROM t WHERE a=? AND b=?", $ida, $idb);

虽然命名它会更加冗长

相关问题