Preg_replace 准备语句的解决方案
我有一个命令类,它抽象了几乎所有特定的数据库功能(我们在 Mssql 2005(使用 ODBC 和本机 mssql 库)、MySQL 和 Oracle 上运行完全相同的应用程序。但有时我们的准备方法会遇到一些问题,当执行后,将所有占位符替换为各自的值。但问题是我使用以下内容:
if(is_array($Parameter['Value']))
{
$Statement = str_ireplace(':'.$Name, implode(', ', $this->Adapter->QuoteValue($Parameter['Value'])), $Statement);
}
else
{
$Statement = str_ireplace(':'.$Name, $this->Adapter->QuoteValue($Parameter['Value']), $Statement);
}
当我们有两个或多个相似的参数名称时,例如 session_browser 和 session_browse_version ...第一个将部分替换最后一个。
当然,我们学会了在特定顺序内指定参数,但现在我有一些“空闲”时间,我想做得更好,所以我正在考虑切换到 preg_replace...但我做得不好在正则表达式中,任何人都可以提供任何有关正则表达式的帮助来替换像 ':parameter_name` 这样的字符串
最好的问候, 布鲁诺·BB·马加拉斯
I have a command class that abstracts almost all specific database functions (We have the exactly same application running on Mssql 2005 (using ODBC and the native mssql library), MySQL and Oracle. But sometimes we had some problems with our prepare method that, when executed, replaces all placeholders with their respective values. But the problem is that I am using the following:
if(is_array($Parameter['Value']))
{
$Statement = str_ireplace(':'.$Name, implode(', ', $this->Adapter->QuoteValue($Parameter['Value'])), $Statement);
}
else
{
$Statement = str_ireplace(':'.$Name, $this->Adapter->QuoteValue($Parameter['Value']), $Statement);
}
The problem arises when we have two or mer similar parameters names, for example, session_browser and session_browse_version... The first one will partially replace the last one.
Course we learned to go around specifying the parameters within a specific order, but now that I have some "free" time I want to make it better, so I am thinking on switching to preg_replace... and I am not good in regular expression, can anyone give any help with a regex to replace a string like ':parameter_name`?
Best Regards,
Bruno B B Magalhaes
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
您应该使用
\b
元字符 来匹配单词边界,这样您就不会意外地在较长的参数名称中匹配较短的参数名称。另外,如果将标量值强制转换为一个条目的数组,则不需要特殊情况的数组:
但是请注意,当标识符或字符串文字包含看起来像参数占位符:
当带引号的标识符和字符串文字可以包含转义引号时,这会变得更加复杂。
您可能需要重新考虑在准备期间将变量插入 SQL 字符串,因为您正在破坏准备好的语句在安全性或性能方面的任何优势。
我明白你为什么要做你正在做的事情,因为并非所有 RDBMS 后端都支持命名参数,而且 SQL 参数也不能用于
IN()
谓词中的值列表。但你正在创建一个非常漏洞百出的抽象。You should use the
\b
metacharacter to match the word boundary, so you don't accidentally match a short parameter name within a longer parameter name.Also, you don't need to special-case arrays if you coerce a scalar Value to an array of one entry:
Note, however, that this can make false positive matches when an identifier or a string literal contains a pattern that looks like a parameter placeholder:
This gets even more complicated when quoted identifiers and string literals can contain escaped quotes.
You might want to reconsider interpolating variables into SQL strings during prepare, because you're defeating any benefits of prepared statements with respect to security or performance.
I understand why you're doing what you're doing, because not all RDBMS back-end supports named parameters, and also SQL parameters can't be used for lists of values in an
IN()
predicate. But you're creating an awfully leaky abstraction.