我正在处理一个旧的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语句的问号参数。
我的问题的答案可能是否定的,但我想解决这个问题,而不必仅使用问号参数,这些参数要求我在构建数组时跟踪我为所有参数保留的顺序。
有没有什么好的方法可以将参数绑定到部分语句,或者解决使用我上面描述的大量问号参数的问题?
答案 0 :(得分:0)
这是工程错误。
我的推荐;包含与参数相对应的变量的数组。 例如
让$sql1 = "select * from Apples where a=? and b=?"
$sql2 = " or c=?;"
两者均来自函数gen_sql1()
和gen_sql2()
。
只需让gen_sql1
返回数组的前半部分:1, 2
。让gen_sql2
返回下半场:3
。
最后,组合数组,你有一个数组并将它们插入"?"各个顺序的参数:
$fullsql = "select * from Apples where a=1 and b=2 or c=3"
答案 1 :(得分:0)
我通过构建两个变量来解决这个问题:一个是查询字符串,另一个是查询参数的哈希数组。
if (is_string($search) && !empty($search)) {
$search = 'AND (voucher.code LIKE :code OR user.email LIKE :email OR user.salutation LIKE :salutation)';
$params['code'] = "%%$search%%";
$params['email'] = "%%$search%%";
$params['salutation'] = "%%$search%%";
} else {
$search = '';
}
当您完成所有条件代码时,您有一个查询参数的哈希数组,您可以将其传递给PDO execute()
。
但您必须确保所有命名参数都是唯一的。如果在不同的条件搜索术语中使用相同的名称,则会出现混乱。在这种情况下,位置参数具有优势。