赏金更新:已经从 Mark 那里得到了非常好的答案。将 := 改编成 :,如下所示。但是,除了 DBIx 之外,我仍在寻找类似的方案。我只是想与任何东西兼容。
我需要关于我为参数化 SQL 语句中的“扩展”占位符选择的语法的建议。因为构建一些构造(IN 子句)困扰着我,所以我决定使用一些语法快捷方式,这些快捷方式可以自动扩展为普通的 ?占位符。
我喜欢他们。但我想打包分发,并问自己它们是否易于理解。
基本上我的新占位符是 ??
和 :?
(枚举参数)和 :&
和 :,
和 :|
和 ::
(用于命名占位符)具有以下用例:
-> db(" SELECT * FROM all WHERE id IN (??) ", [$a, $b, $c, $d, $e])
??
扩展为 ?,?,?,?,?,...
取决于我的 db() 函数的 $args 的数量。这个很清楚,它的语法已经标准化了。 Perls DBIx::Simple 也使用它。所以我很确定这是一个可以接受的想法。
-> db(" SELECT :? FROM any WHERE id>0 ", ["title", "frog", "id"]);
// Note: not actually parameterized attr, needs cleanup regex
承认吧。我只是喜欢笑脸。基本上这个 :?
占位符将关联的 $args 扩展为普通列名。事实上,它会丢弃任何 $args 值。它实际上对与 ?? 结合使用的 INSERT 很有用,有时对 IN 子句也很有用。但是在这里我已经在想这个新语法是否合理,或者不仅仅是用词不当,因为它混合了 : 和 ?人物。但不知何故,它似乎与语法方案很匹配。
-> db(" UPDATE some SET :, WHERE :& AND (:|) ", $row, $keys, $or);
此处助记符 :,
扩展为 name=:name
对列表,由 ,
逗号分隔。而 :&
是由 AND
连接的 column=:column 列表。对于奇偶校验,我添加了 :|
。不过,:& 在 UPDATE 命令之外还有其他用例。
但我的问题不是关于有用性,而是如果 :, 和 :& 看起来好记?
-> db(" SELECT * FROM all WHERE name IN (::) ", $assoc);
虽然我也添加了一些 ::
来插入一个 :named,:value,:list
非常像 ??
扩展到?,?,?
。相似的用例,并且为了统一起见是明智的。
不管怎样,有没有其他人实现过这样的计划?不同的占位符?或者为了简单起见,您会推荐哪个? 更新: 我知道 PHP Oracle OCI 接口(interface)也可以绑定(bind)数组参数,但不使用特定的占位符。我正在寻找可比较的占位符语法。
最佳答案
我喜欢您提案背后的基本思想,但不喜欢占位符的“命名”。我基本上有两个反对意见:
- 您的占位符以
:
开头或?
.您应该选择一种形式,以便可以立即识别占位符。我会选择?
因为它与 SQL 的冲突可能性较小,并且更常用于表示占位符。 - 占位符很难理解也很难记住。
:&
和:|
对我来说似乎是合理的,但要区分??
,:?
和:
很难。
我改变了我的 DB class支持更多占位符并更加智能:DB_intelligent.php (README中关于占位符的部分不适用于此类,仅适用于普通类。)
DB类有两种占位符:多功能?
占位符和关联数组占位符 ?x
( x
可能是 ,
、 &
或 |
)。
?
占位符:此占位符根据参数的类型确定插入的类型:
null => 'NULL'
'string' => 'string'
array('foo', 'bar') => ('foo','bar')
?x
占位符:数组中的每个元素都转换为 `field`='value'
结构并用定界符内爆。分隔符由 x
指定组件:,
用逗号分隔,&
通过 AND
和 |
通过 OR
.
示例代码:
DB::x(
'UPDATE table SET ?, WHERE value IN ? AND ?&',
array('foo' => 'bar'),
array('foo', 'bar'),
array('hallo' => 'world', 'hi' => 'back')
);
// Results in this query:
// UPDATE table SET `foo`='bar' WHERE value IN ('foo','bar') AND `hallo`='world' AND `hi`='back'
我在设计这个版本的 DB 类时的一些想法:
可能会出现一个明显的想法:为什么不使用 ?
对于所有 类型的数据,甚至是关联数组。仅添加 ?&
和 ?|
此外。使用 ?
在关联数组上与使用 ?,
相同在目前的设计中。我没有这样做的原因是安全。您经常希望从 <select multiple>
中插入数据进入查询(IN ?
)。但是由于 HTML 允许排列 (form[array]
) 表单控件,因此也可以提交具有相同名称的关联数组。因此,我的查询合成器会将其识别为字段 => 值列表。尽管这可能不会损害安全性,但它会导致严重的 SQL 错误。
关于php - SQL 的扩展占位符,例如ID 在哪里(??),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3696327/