将参数绑定到部分SQL语句

问题描述 投票:1回答:2

我正在处理一个旧的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语句的问号参数。

我的问题的答案可能是否定的,但我想解决这个问题,而不必仅使用问号参数,这将要求我在构建数组时跟踪我为所有参数保留的顺序。

有没有什么好方法可以将参数绑定到部分语句,或者解决使用上面描述的大量问号参数的问题?

php pdo dynamic-sql
2个回答
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()

但是您必须确保所有命名参数都是唯一的。如果在不同的条件搜索术语中使用相同的名称,则会出现混乱。在那种情况下,位置参数具有优势。


0
投票

这是一个工程错误。

我的建议;包含与参数相对应的变量的数组。例如

$sql1 = "select * from Apples where a=? and b=?"

$sql2 = " or c=?;"

两者都是从函数gen_sql1()gen_sql2()生成的。

只需让gen_sql1返回阵列的前半部分:1, 2gen_sql2回归下半场:3

最后,组合数组,你有一个数组,并将它们插入“?”各个顺序的参数:

$fullsql = "select * from Apples where a=1 and b=2 or c=3"

© www.soinside.com 2019 - 2024. All rights reserved.