tags:

views:

410

answers:

8

Is there any function which replaces params in a string? Something like this:

Code:

$format_str = "My name is %name."; /* this was set in a 
                                      configuration file - config.php */

$str = xprintf($format_str, array('name' => 'Joe', 'age' => 150)); 
              /* above is somewhere in main code */

The expected value of $str after the operation is:

My name is Joe.

Update: I am aware of sprintf. But, it would not suffice in this case. I have modified the code to show what is the difference.

+3  A: 

you could use this:

function xprintf($str, $array, $chr = '%') {

   foreach ($array as &$key => $val) {
       $key = $chr . $key;
   }

   return strtr($str, $array);
}

$str = xprintf('My name is %name', array('name' => 'Joe'));
Ozzy
Wtf, why did i get downvoted. I would have talked about sprintf but from the way he asked the question, it seems he wants UNIQUE identifiers not just %s.I get downvoted for reading the question -_-
Ozzy
Similar to your answer, Something more like what he's after: http://au2.php.net/manual/en/function.sprintf.php#83779 see the example sprintf3
Stobor
Thx for the link. Ill update my answer with something more like what he wants
Ozzy
The problem with str_replace is that it replaces replacements. For example try this: $str = xprintf('My name is %first %last', array('first' => '%last', 'last' => 'Smith')); You should get 'My name is %last Smith' but instead you get 'My name is Smith Smith'. Using strtr avoids this problem.
rojoca
Thanks rojoca, ill update my answer to use strtr
Ozzy
+2  A: 

Do you mean sprintf()?

$str = sprintf("My name is %s.", 'Joe');

yjerem
A: 

Try giving printf() a whirl. That website has a lot of examples for using arrays with printf.

printf("My name is %s", "Joe");
rascher
A: 

You could always use eval... (gasp!)

$myStr = 'Hi my name is $name. I\'m $age years old.';
$myVars = array("name" => "Joe", "age" => 6);
$parsed = parseString($myStr, $myVars);

function parseString($str, $vars) {
    extract($vars);
    return eval('return "' . addslashes($str) . '";');
}

Before anyone gets cranky about using extract AND eval, as long as you have control over the input template string, I can't see how this could be a security problem.

nickf
+7  A: 

seems like strtr is what is a builtin function which can do the same. (got this from going thru drupal code).

>> $format_str = "My name is %name.";
My name is %name.
>> strtr($format_str, array('%name' => 'Joe', '%age' => 150))
My name is Joe.
sleepy
This looks to be exactly what is required.
Christian
strtr is perfect for this
thomasrutter
A: 

PHP can pull in values from an array without using sprintf():

$data = array('name' => 'Joe', 'age' => 150);
print "My name is $data[name], my age is $data[age].";
too much php
Doesn't help - needs to be able to deal with an actual string containing % followed by a word, where the string value is set BEFORE the replacement values are known.
thomasrutter
A: 

This function, "map" (and replace), is part of my web application system:

function replace($search, $replace, $mixed)
{
    if (is_string($mixed)) {
        return @str_replace($search, $replace, $mixed);
    } else if (is_array($mixed)) {
        foreach ($mixed as $k => $v) {
            $mixed[$k] = replace($search, $replace, $v);
        }
        return $mixed;
    } else {
        return $mixed;
    }
}


function map($a, $contents, $case_sensitive=false)
{
    if (!is_array($a)) {
        return $contents;
    }
    if (!$case_sensitive) {
        $a = array_change_key_case($a);
    }
    $s = array();
    $r = array();
    foreach ($a as $k => $v) {
        if (is_scalar($v) || empty($v)) {
            $s[] = "{".$k."}";
            $r[] = $v;
        }
    }
    if (!$case_sensitive) {
        $contents = preg_replace_mixed('/{([-_ =,.\/\'"A-Za-z0-9]+)}/ei', "'{'.strtolower('\\1').'}'", $contents);
    }
    return replace($s, $r, $contents);
}

Does a very good job. Supply any string with bracketed variables names, and it does the trick.

Syntax is different, but could be modified for your purposes:

$str = map(array('name' => 'Joe'), 'My name is {name}');

I prefer it over the % syntax.

razzed
A: 

You're looking for vsprintf. http://us2.php.net/vsprintf

It allows you to pass an array of arguments as you indicated.

dirtside