【发布时间】:2018-01-04 16:53:02
【问题描述】:
我正在处理一个旧的 PHP 应用程序,我的任务是确保所有区域都使用准备好的语句。目前它使用 sprintf 在执行之前构建大部分查询。
以下是当前实现的一些示例代码:
$queryString = "SELECT count(user.uid) as count
FROM user
LEFT JOIN voucher
ON user.voucher_uid = voucher.uid
LEFT JOIN affiliation
ON voucher.uid = affiliation.voucher_uid
@affiliation
LEFT JOIN account
ON affiliation.account_uid = account.uid
WHERE affiliation.account_uid IN (@accounts)
@active
@search
@template
@onlyown
AND voucher.template NOT LIKE 'api_%'
AND user.role != 'superadmin'";
$sql = replace_tokens(
$queryString,
array(
'accounts' => implode(', ', array_fill(0, count($accounts), '?')),
'template' => $template,
'search' => $search,
'onlyown' => $onlyown,
'affiliation' => $affiliation,
'active' => $active
)
);
return array_get(self::queryFetchOne($sql, $accounts), 'count', 0);
replace_tokens函数将前面用@声明的“变量”替换为sql。下面是如何构建 @search 变量的示例。
if (is_string($search) && !empty($search)) {
$search = sprintf('AND (voucher.code LIKE "%%%s%%" OR user.email LIKE "%%%s%%" OR user.salutation LIKE "%%%s%%")', $search, $search, $search);
} else {
$search = '';
}
现在,我想通过将%%%s%% 更改为:search 并简单地使用命名参数来解决搜索问题。但是,$accounts 变量是一个帐户名称数组,并在 in 语句中使用问号参数。
我的问题的答案可能是否定的,但我想解决这个问题,而不必只使用问号参数,这需要我在构建数组时跟踪我为所有参数保留的顺序。
有没有什么好的方法可以将参数绑定到部分语句或解决我上面描述的使用大量问号参数的问题?
【问题讨论】:
-
不,这是不可能的。不过,您可以继续使用当前方法,只需确保将
"%%%s%%"(包括引号)替换为$pdo->quote($variable)结果。或者您可以继续处理参数的麻烦,但在这种情况下,您必须将所有变量收集到数组中以便进一步执行
标签: php pdo dynamic-sql