3 回答

TA貢獻1852條經(jīng)驗 獲得超1個贊
我已經(jīng)遇到過相同的問題好幾次了,我想我已經(jīng)找到了一個非常簡單和好的解決方案。萬一我想多次使用參數(shù),我只是將它們存儲到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
}
唯一的缺點可能是您需要執(zhí)行其他MySQL查詢-但恕我直言,這是完全值得的。
由于User-Defined Variables在MySQL中是會話綁定的,因此也不必擔心變量會@term在多用戶環(huán)境中產(chǎn)生副作用。

TA貢獻1831條經(jīng)驗 獲得超4個贊
我創(chuàng)建了兩個函數(shù)來通過重命名重復使用的術語來解決該問題。一種用于重命名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:參數(shù),l:函數(shù)
str:字符串中的局部,n:數(shù)字,a:數(shù)組,m:混合
添加回答
舉報