3 回答
![?](http://img1.sycdn.imooc.com/545847d40001cbef02200220-100-100.jpg)
TA贡献1852条经验 获得超1个赞
我已经遇到过相同的问题好几次了,我想我已经找到了一个非常简单和好的解决方案。万一我想多次使用参数,我只是将它们存储到MySQL中User-Defined Variable。
这使代码更具可读性,并且您在PHP中不需要任何其他功能:
$sql = "SET @term = :term";
try
{
$stmt = $dbh->prepare($sql);
$stmt->bindValue(":term", "%$term%", PDO::PARAM_STR);
$stmt->execute();
}
catch(PDOException $e)
{
// error handling
}
$sql = "SELECT ... FROM table WHERE name LIKE @term OR number LIKE @term";
try
{
$stmt = $dbh->prepare($sql);
$stmt->execute();
$stmt->fetchAll();
}
catch(PDOException $e)
{
//error handling
}
唯一的缺点可能是您需要执行其他MySQL查询-但恕我直言,这是完全值得的。
由于User-Defined Variables在MySQL中是会话绑定的,因此也不必担心变量会@term在多用户环境中产生副作用。
![?](http://img1.sycdn.imooc.com/545864000001644402200220-100-100.jpg)
TA贡献1831条经验 获得超4个赞
我创建了两个函数来通过重命名重复使用的术语来解决该问题。一种用于重命名SQL,另一种用于重命名绑定。
/**
* Changes double bindings to seperate ones appended with numbers in bindings array
* example: :term will become :term_1, :term_2, .. when used multiple times.
*
* @param string $pstrSql
* @param array $paBindings
* @return array
*/
private function prepareParamtersForMultipleBindings($pstrSql, array $paBindings = array())
{
foreach($paBindings as $lstrBinding => $lmValue)
{
// $lnTermCount= substr_count($pstrSql, ':'.$lstrBinding);
preg_match_all("/:".$lstrBinding."\b/", $pstrSql, $laMatches);
$lnTermCount= (isset($laMatches[0])) ? count($laMatches[0]) : 0;
if($lnTermCount > 1)
{
for($lnIndex = 1; $lnIndex <= $lnTermCount; $lnIndex++)
{
$paBindings[$lstrBinding.'_'.$lnIndex] = $lmValue;
}
unset($paBindings[$lstrBinding]);
}
}
return $paBindings;
}
/**
* Changes double bindings to seperate ones appended with numbers in SQL string
* example: :term will become :term_1, :term_2, .. when used multiple times.
*
* @param string $pstrSql
* @param array $paBindings
* @return string
*/
private function prepareSqlForMultipleBindings($pstrSql, array $paBindings = array())
{
foreach($paBindings as $lstrBinding => $lmValue)
{
// $lnTermCount= substr_count($pstrSql, ':'.$lstrBinding);
preg_match_all("/:".$lstrBinding."\b/", $pstrSql, $laMatches);
$lnTermCount= (isset($laMatches[0])) ? count($laMatches[0]) : 0;
if($lnTermCount > 1)
{
$lnCount= 0;
$pstrSql= preg_replace_callback('(:'.$lstrBinding.'\b)', function($paMatches) use (&$lnCount) {
$lnCount++;
return sprintf("%s_%d", $paMatches[0], $lnCount);
} , $pstrSql, $lnLimit = -1, $lnCount);
}
}
return $pstrSql;
}
用法示例:
$lstrSqlQuery= $this->prepareSqlForMultipleBindings($pstrSqlQuery, $paParameters);
$laParameters= $this->prepareParamtersForMultipleBindings($pstrSqlQuery, $paParameters);
$this->prepare($lstrSqlQuery)->execute($laParameters);
有关变量命名的说明:
p:参数,l:函数
str:字符串中的局部,n:数字,a:数组,m:混合
添加回答
举报