将参数绑定到部分SQL语句

时间:2018-01-04 16:53:03

标签: php pdo dynamic-sql

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

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

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

2 个答案:

答案 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()

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

相关问题