'C# String.Format() Equivalent in PHP?

I'm building a rather large Lucene.NET search expression. Is there a best practices way to do the string replacement in PHP? It doesn't have to be this way, but I'm hoping for something similar to the C# String.Format method.

Here's what the logic would look like in C#.

var filter = "content:{0} title:{0}^4.0 path.title:{0}^4.0 description:{0} ...";

filter = String.Format(filter, "Cheese");

Is there a PHP5 equivalent?



Solution 1:[1]

Try sprintf http://php.net/sprintf

Solution 2:[2]

try this one if there is an error or 'create_function'

public static function format()
{
    $args = func_get_args();
    $format = array_shift($args);

    preg_match_all('/(?=\{)\{(\d+)\}(?!\})/', $format, $matches, PREG_OFFSET_CAPTURE);
    $offset = 0;
    foreach ($matches[1] as $data) {
        $i = $data[0];
        $format = substr_replace($format, @$args[$i], $offset + $data[1] - 1, 2 + strlen($i));
        $offset += strlen(@$args[$i]) - 2 - strlen($i);
    }

    return $format;
}

I found it from here

Solution 3:[3]

Using preg_replace_callback with a modern approach, we can even use a helper class library to support dot notation (adbario/php-dot-notation) inside out format along with array keys:

use \Adbar\Dot;

function format($text, ...$args)
{
    $params = new Dot([]);

    if (count($args) === 1 && is_array($args[0])) {
        $params->setArray($args[0]);
    } else {
        $params->setArray($args);
    }

    return preg_replace_callback(
        '/\{(.*?)\}/',
        function ($matches) use ($params) {
            return $params->get($matches[1], $matches[0]);
        },
        $text
    );
}

And we can use it like this:

> format("content:{0} title:{0}^4.0 path.title:{0}^4.0 description:{0} ...", "Cheese");
"content:Cheese title:Cheese^4.0 path.title:Cheese^4.0 description:Cheese ..."

> format(
    'My name is {name} and my age is {age} ({name}/{age})',
    ['name' => 'Christos', 'age' => 101]
);
"My name is Christos and my age is 101 (Christos/101)"

> format(
    'My name is {name}, my age is {info.age} and my ID is {personal.data.id} ({name}/{info.age}/{personal.data.id})',
    [
        'name' => 'Chris',
        'info' => [
            'age' => 40
        ],
        'personal' => [
            'data' => [
                'id' => '#id-1234'
            ]
        ]
    ]
);
"My name is Christos, my age is 101 and my ID is #id-1234 (Christos/101/#id-1234)"

Of course we can have a simple version without any extra libraries if we don't want multilevel array support using dot notation:

function format($text, ...$args)
{
    $params = [];

    if (count($args) === 1 && is_array($args[0])) {
        $params = $args[0];
    } else {
        $params = $args;
    }

    return preg_replace_callback(
        '/\{(.*?)\}/',
        function ($matches) use ($params) {
            if (isset($params[$matches[1]])) {
                return $params[$matches[1]];
            }
            return $matches[0];
        },
        $text
    );
}

Solution 4:[4]

I came up with this solution: https://github.com/andreasahlen/StringNetFormat

Very simple, because at first stage... feel free to use it.

print StringNetFormat("Hallo {0}, {1}, and {2}, ({0}, {1}, {2})", array ("Harry", "Doreen", "Wakka")); 

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Mateusz Kubiczek
Solution 2 Irfan Soetedja
Solution 3 Christos Lytras
Solution 4 Andreas Ahlen