Php 带命名参数与问号参数的PDO语句

Php 带命名参数与问号参数的PDO语句,php,pdo,Php,Pdo,我有一个用于数据库管理的类,我的一个子类定义了一个查询,如下所示只是一个示例,许多其他函数实际上是为了测试目的而剥离的: namespace Tests\SQL\Arguments { // SQL query class Query { public $attributes; // constructor for this object public function __construct() { if

我有一个用于数据库管理的类,我的一个子类定义了一个查询,如下所示只是一个示例,许多其他函数实际上是为了测试目的而剥离的:

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);
}
如您所见,我自动选择函数参数,因此我可以在构建时轻松地将查询与其参数分离。除了批量插入/更新/删除操作之外,我还想提供一些安全性,比如防止SQL注入和其他事情

我的问题是。。。鉴于此结构,当我像一个简单的示例一样传递此结构时,它将以不同的方式运行,但此结构暂时有效:

使用命名参数如:date、:client、:amount、:status或使用问号参数如?、?、?、?,会有什么不同吗

编辑-更好的解释

很抱歉,我的问题显然很模糊。我的意图是使用一种类似于sprintf的机制,但是,我没有存储包含所有参数的字符串,而是以单独的方式存储查询和参数

这只是查询类。还有用于在组中存储查询的QueryGroup类、用于存储和管理所有数据库连接的Manager类和负责为给定数据库连接保存所有查询和查询组的Connection类

关于命名参数,我认为我正在使用的方法没有问题,因为它可以工作,就像我说的,就像sprintf函数一样。我将在查询字符串中提供问号或参数名称

我想做一个分离,以提供额外的过滤功能,如转义或引用参数,以防止针对给定数据库的某种形式的注入或破坏

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


任何提示都将不胜感激:

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

特别是在您的示例中,未命名参数将非常适合,因为它简化了函数调用


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

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

特别是在您的示例中,未命名参数将非常适合,因为它简化了函数调用


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

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

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

虽然在技术上没有区别,因为PDO只是在内部将命名的占位符替换为问号,但存在可用性问题

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

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

虽然使用命名将更加详细

虽然没有技术上的区别,因为PDO只是在内部将命名占位符替换为问号,但存在可用性问题

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

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

如果使用named,当您从func_get_args(如上所述)中提取值时,它将更加详细,这不是您的execute方法,那么它们将被枚举,因此不会命名。只是好奇而已。对于像SELECT*FROM t WHERE id IN这样的查询,您有解决方案吗?我还没有实现一个合适的解决方案,但是我可以使用类似数组映射函数$input{if is_数组$input{return explode,$input},$arguments或类似的过程来执行一个传统的传递。必须测试它,很难。我明白了,一个魔术。好吧,没有更多的反对意见,我只是喜欢更稳健的方式。然而,这次返航爆炸看起来相当危险。这只是我脑海中浮现的一个简单的例子。正确的方法是分析每个数组/参数成员,将其从任何危险组件中剥离出来,例如,不需要的标记或故意引用来破坏SQL语句。现在,我只是在SQL类的不同部分上进行简单的测试。但感谢您的提示:当您从func_get_args(如上所述)获取值时,这不是您的execute方法,那么它们将被枚举,因此不会命名。只是好奇而已。对于像SELECT*FROM t WHERE id IN这样的查询,您有解决方案吗?我还没有实现一个合适的解决方案,但是我可以用一些东西执行一个传统的pass

类似ng的数组映射函数$input{if is_数组$input{return explode,$input}},$arguments或类似的过程。必须测试它,很难。我明白了,一个魔术。好吧,没有更多的反对意见,我只是喜欢更稳健的方式。然而,这次返航爆炸看起来相当危险。这只是我脑海中浮现的一个简单的例子。正确的方法是分析每个数组/参数成员,将其从任何危险组件中剥离出来,例如,不需要的标记或故意引用来破坏SQL语句。现在,我只是在SQL类的不同部分上进行简单的测试。但谢谢你的暗示:这正是我想要的答案。非常感谢你的解释:不客气。同时检查我关于return$this的更新;在构造函数中。关于“无需执行返回$this”短语。。。对拥有它很有用,因为它允许我进行方法链接。这样,您可以执行类似$query=newquery…->output的操作;或者,在QueryGroup类中,执行类似$group1->addQuery…->addQuery…->addQuery…->addQuery…->addQuery…;:这对我来说是新鲜事。使用PHP5.3.10,您使用的是哪个版本的php?PHP5.4.13,始终保持最新版本正是我想要的答案。非常感谢你的解释:不客气。同时检查我关于return$this的更新;在构造函数中。关于“无需执行返回$this”短语。。。对拥有它很有用,因为它允许我进行方法链接。这样,您可以执行类似$query=newquery…->output的操作;或者,在QueryGroup类中,执行类似$group1->addQuery…->addQuery…->addQuery…->addQuery…->addQuery…;:这对我来说是新鲜事。使用PHP5.3.10,您使用的是哪个版本的php?PHP5.4.13,始终保持最新版本专用查询类对我很有用,原因如下:1它允许我以逻辑方式分离所有查询组件;2它允许我使用正则表达式、定义函数、lambda或任何方法对查询或参数执行额外的过滤/转换,3它允许我在批量操作中动态计算它的字符串长度,这样无论我使用的是什么数据库驱动程序,我都可以调整它以获得最大的性能:像查询生成器一样的PLooks。我希望看到它付诸实施。对我来说,它要解决的大多数问题都是非常罕见的,而且是偶然的。它是我正在构建的框架的一部分。你说得对。。。大多数问题可能是偶然出现的,尽管我在设计SQL类时是基于我在不同领域(如电子商务)与客户一起工作时发现的真实场景,CRM和计费管理,其中已知的解决方案不能/不会解决这些问题,而且他们会从中获益匪浅。专用查询类对我很有用,原因如下:1它允许我以逻辑方式分离所有查询组件;2它允许我使用正则表达式、定义函数、lambda或任何方法对查询或参数执行额外的过滤/转换,3它允许我在批量操作中动态计算它的字符串长度,这样无论我使用的是什么数据库驱动程序,我都可以调整它以获得最大的性能:像查询生成器一样的PLooks。我希望看到它付诸实施。对我来说,它要解决的大多数问题都是非常罕见的,而且是偶然的。它是我正在构建的框架的一部分。你说得对。。。大多数问题可能是偶然出现的,尽管我正在根据我在不同领域(如电子商务、CRM和计费管理)与客户合作时发现的真实场景设计SQL类,而已知的解决方案不能/不会解决这些问题,而且他们会从中获益匪浅。