2012-01-19 3 views
4

Кто-нибудь знает лучшую реализацию sprintf в PHP? Я искал что-то вроде строки форматирования, мы имеем в Python:улучшенный sprintf для PHP

print "Hello %(name)s. Your %(name)s has just been created!" % { 'name' : 'world' } 
# prints::: Hello world. Your world has just been created! 

Это очень удобно, чтобы избежать повторения тех же самых переменных без необходимости, такие как:

sprintf("Hello %s. Your %s has just been created!", 'world', 'world'); 
# prints::: Hello world. Your world has just been created! 

Я думаю, довольно легко создайте это самостоятельно, но не пытайтесь изобретать колесо, если знаете, что я имею в виду ... но я не мог найти (может быть, неправильные ключевые слова поиска) любые следы этого в любом месте.

Если кто-нибудь может помочь, я ценю.

Приветствия,

+1

Это особенно интересное использование, если вы хотите построить обширные запросы с помощью _INSERT MySQL ... ON DUPLICATE KEY UPDATE Синтаксис ..._ [http://dev.mysql.com/doc/refman/5.0/ru /insert-on-duplicate.html](http://dev.mysql.com/doc/refman/5.0/en/insert-on-duplicate.html) –

+0

См. http://stackoverflow.com/questions/ 5701985/vsprintf-or-sprintf-with-named-arguments-or-simple-tempalte-parsing-in-php и http://stackoverflow.com/questions/7435233/name-php-specifiers-in-printf-strings – lqez

ответ

8

Вы можете использовать позиционные (но не названные) аргументы, чтобы сделать это, например

printf('Hello %1$s. Your %1$s has just been created!', 'world'); 

слово предостережения здесь: вы должны использовать одиночные кавычки, иначе знаки доллара заставит PHP попробовать для замены $s со значением этой переменной (которая не существует).

Если вам нужны именованные аргументы, вам придется делать это с помощью регулярного выражения; например, см. How to replace placeholders with actual values?.

+0

аккуратный! Благодарю. Это сделает трюк! –

5

Вы можете повторить тот же заполнитель с РНР sprintf (хотя это может выглядеть не так хорошо):

$str = sprintf('%1$s %1$s', 'yay'); 
// str: 'yay yay' 

Вы можете использовать n$ сразу после % в заполнителе, где n - позиция аргумента (так %1$s относится к первому аргументу (как строка), %2$s относится ко второму и т. д.). Как вы можете видеть выше, когда вы используете помещики, которые позиционно привязаны, вы можете повторять их в строке без дублирования аргументов, когда вы вызываете sprintf.

+0

Вы правы ... не так хорошо, но, по крайней мере, трюк. Благодаря! –

3

Следующий код был украден от a post by Salathe on TalkPHP.

$szAdjective = 'fluffy'; 
$szNoun = 'cat'; 

printf('Yesterday, I saw a %s. '. 
     'It was a %s %s! I have '. 
     'never seen a %s quite so %s.', 
     $szNoun, 
     $szAdjective, 
     $szNoun, 
     $szNoun, 
     $szAdjective); 

printf('Yesterday, I saw a %1$s. '. 
     'It was a %2$s %1$s! I have '. 
     'never seen a %1$s quite so %2$s.', 
     $szNoun, 
     $szAdjective); 

Эти два выражения эквивалентны и оба будут выход

«Вчера я видел кошку. Это был пушистый кот! Я никогда не видел кошку совсем так пушистый.»

+0

Спасибо за помощь! –

2

Я ответил на этот самый вопрос в другом посте: vsprintf or sprintf with named arguments, or simple template parsing in PHP

Но это имеет тот же формат Youre ищет!

Это действительно лучший способ пойти имхо. Никаких загадочных символов, просто используйте имена ключей!

Как взята с сайта PHP: http://www.php.net/manual/en/function.vsprintf.php

function dsprintf() { 
    $data = func_get_args(); // get all the arguments 
    $string = array_shift($data); // the string is the first one 
    if (is_array(func_get_arg(1))) { // if the second one is an array, use that 
    $data = func_get_arg(1); 
    } 
    $used_keys = array(); 
    // get the matches, and feed them to our function 
    $string = preg_replace('/\%\((.*?)\)(.)/e', 
    'dsprintfMatch(\'$1\',\'$2\',\$data,$used_keys)',$string); 
    $data = array_diff_key($data,$used_keys); // diff the data with the used_keys 
    return vsprintf($string,$data); // yeah! 
} 

function dsprintfMatch($m1,$m2,&$data,&$used_keys) { 
    if (isset($data[$m1])) { // if the key is there 
    $str = $data[$m1]; 
    $used_keys[$m1] = $m1; // dont unset it, it can be used multiple times 
    return sprintf("%".$m2,$str); // sprintf the string, so %s, or %d works like it should 
    } else { 
    return "%".$m2; // else, return a regular %s, or %d or whatever is used 
    } 
} 

$str = <<<HITHERE 
Hello, %(firstName)s, I know your favorite PDA is the %(pda)s. You must have bought %(amount)s 
HITHERE; 

$dataArray = array(
    'pda'   => 'Newton 2100', 
    'firstName' => 'Steve', 
    'amount'  => '200' 
); 
echo dsprintf($str, $dataArray); 
// Hello, Steve, I know your favorite PDA is the Newton 2100. You must have bought 200 
+0

Неплохо. Спасибо, что поделился! Я предпочел бы использовать это, чем «загадочный», как вы упомянули. –

0

Я написал небольшой компонент, который позволит вам сделать имя замены в PHP строк. Это называется . С его помощью вы можете получить то, что вы хотите с помощью следующего кода:

$engine = new StringTemplate\Engine; 

$engine->render(
    '"Hello {name}. Your {name} has just been created!"', 
    [ 
     'name' => 'world', 
    ] 
); 
//Prints "Hello world. Your world has just been created!" 

многомерного значение массива допускается слишком. Надеюсь, что это поможет.

Смежные вопросы