1

我有一个命令类,它抽象了几乎所有特定的数据库函数(我们在 Mssql 2005(使用 ODBC 和本机 mssql 库)、MySQL 和 Oracle 上运行完全相同的应用程序。但有时我们的 prepare 方法会出现一些问题,当执行,用它们各自的值替换所有占位符.但问题是我正在使用以下内容:

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 Magalhaes

4

1 回答 1

2

您应该使用\b 元字符来匹配单词边界,这样您就不会意外地在较长的参数名称中匹配较短的参数名称。

此外,如果将标量值强制为一个条目的数组,则不需要特殊情况数组:

preg_replace("/:$Name\b/", 
    implode(",", $this->Adapter->QuoteValue( (array) $Parameter['Value'] )), 
    $Statement);

但是请注意,当标识符或字符串文字包含看起来像参数占位符的模式时,这可能会导致误报匹配:

SELECT * FROM ":Name";

SELECT * FROM Table WHERE column = ':Name';

当带引号的标识符和字符串文字可以包含转义引号时,这会变得更加复杂。

SELECT * FROM Table WHERE column = 'word\':Name';

您可能希望在准备期间重新考虑将变量插入 SQL 字符串,因为您正在破坏准备好的语句在安全性或性能方面的任何好处。

我理解您为什么要这样做,因为并非所有 RDBMS 后端都支持命名参数,而且 SQL 参数也不能用于IN()谓词中的值列表。但是您正在创建一个漏洞百出的抽象。

于 2009-09-10T23:33:29.440 回答