Reputation: 2443
I need a simple and fast solution to replace nth occurrence (placeholder) in a string.
For example, nth question mark in sql query should be replaced with a provided value.
$subject = "SELECT uid FROM users WHERE uid = ? or username = ?";
So, i need function like str_replace_nth($seach, $replace, $subject, $nth)
and for second question mark it should be called as str_replace_nth("?", $username, $subject, 2);
Any ideas?
P.S. Please, don't suggest me to use PDO, because I'm working on FDO (Facebook Data Object) a library with an interface similar to PDO, but for FQL.
Important notice! I've figured out that this approach is bad because after first replacement the query is modified and indexes are lost. (Bad approaches come when you're programming late at night :() So, as @GolezTrol mention in comment, it's better to replace all at once.
Upvotes: 9
Views: 10392
Reputation: 492
None of your solutions worked for me, so I made this:
$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() is just a function I use for printing :
echo '<pre>';
print_r($tab);
echo '</pre>';
Upvotes: 0
Reputation: 158
Validation on input parameter not done
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);
}
Upvotes: 0
Reputation: 12665
Here is the function you asked for:
$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);
Note: $nth
is a zero based index!
But I'll recommend to use something like the following to replace the placeholders:
$subject = "SELECT uid FROM users WHERE uid = ? or username = ?";
$args = array('1', 'steve');
echo vsprintf(str_replace('?', '%s', $subject), $args);
Upvotes: 15
Reputation: 4012
Instead of using question marks, why don't use markers like that :
$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);
Upvotes: 6