9

我需要一个简单快速的解决方案来替换字符串中的第 n 个出现(占位符)。

例如,sql 查询中的第 n 个问号应替换为提供的值。

$subject = "SELECT uid FROM users WHERE uid = ? or username = ?";

所以,我需要类似的功能str_replace_nth($seach, $replace, $subject, $nth),对于第二个问号,它应该被称为str_replace_nth("?", $username, $subject, 2);

有任何想法吗?

PS 请不要建议我使用 PDO,因为我正在研究FDO(Facebook 数据对象),这是一个具有类似于 PDO 接口的库,但用于 FQL。

重要的提醒!我发现这种方法很糟糕,因为在第一次替换后,查询被修改并且索引丢失了。(当你在深夜编程时会出现不好的方法:()所以,正如@GolezTrol 在评论中提到的那样,最好一次替换所有内容。

4

4 回答 4

15

这是您要求的功能:

$subject = "SELECT uid FROM users WHERE uid = ? or username = ?";

function str_replace_nth($search, $replace, $subject, $nth)
{
    $found = preg_match_all('/'.preg_quote($search).'/', $subject, $matches, PREG_OFFSET_CAPTURE);
    if (false !== $found && $found > $nth) {
        return substr_replace($subject, $replace, $matches[0][$nth][1], strlen($search));
    }
    return $subject;
}

echo str_replace_nth('?', 'username', $subject, 1);

注意:$nth是一个从零开始的索引!

但我会建议使用类似以下的东西来替换占位符:

$subject = "SELECT uid FROM users WHERE uid = ? or username = ?";

$args = array('1', 'steve');
echo vsprintf(str_replace('?', '%s', $subject), $args);
于 2013-11-11T13:41:52.867 回答
6

不要使用问号,为什么不使用这样的标记:

$subject = "SELECT uid FROM users WHERE uid = :uid or username = :username";
$parameters = array(
    ':uid' => 42,
    ':username' => 'John',
);
$subject = str_replace(array_keys($parameters), $parameters, $subject);
于 2013-11-11T13:09:09.277 回答
0

未完成对输入参数的验证

 function str_replace_nth($search, $replace, $subject, $nth){
  $match_arr = explode($search,$subject);
  $match_arr = array_filter($match_arr);

   foreach($match_arr as $key=>$val){

      if($key == $nth-1){ // array index start with Zero
        $match_arr[$key] .=  $replace;
      }else{
        $match_arr[$key] .=  '?';
      }

   }
   return implode('',$match_arr);
}
于 2013-11-11T13:50:06.103 回答
0

你的解决方案都不适合我,所以我做了这个:

$sql1 = "SELECT * FROM allegro_user WHERE User_Emp_Nb = ? AND User_Activ_status = ?";
$sql2 = "SELECT * FROM allegro_user WHERE User_Emp_Nb = :emp_nb AND User_Activ_status = :activ";

function prepare_query($sql, $args) {
    foreach ($args as $key => $value) {
        if (is_numeric($key)) {
            $sql = preg_replace('/\?/', "'" . $value . "'", $sql, 1);
        } else {
            $sql = str_replace($key, "'" . $value . "'", $sql);
        }
    }
    return $sql;

}

tab($sql1);
$sql = prepare_query($sql1, array('0216313', 'A'));
tab($sql1);

tab($sql2);
$sql = prepare_query($sql2, array(':emp_nb' => '0216313', ':activ' => 'A'));
tab($sql2);

tab() 只是我用于打印的一个函数:

echo '<pre>';
print_r($tab);
echo '</pre>';
于 2015-11-10T16:00:37.023 回答