Instead of inventing own functions in case you'd like to use array keys as placeholder names and replace corresponding array values in a string, just use the str_replace:
$string = 'Hello %name!';
$data = array(
'%name' => 'John'
);
$greeting = str_replace(array_keys($data), array_values($data), $string);vsprintf
Почист и полокален преглед на PHP референцата, со задржана структура од PHP.net и подобра читливост за примери, секции и белешки.
vsprintf
Референца за `function.vsprintf.php` со подобрена типографија и навигација.
vsprintf
(PHP 4 >= 4.1.0, PHP 5, PHP 7, PHP 8)
vsprintf — (PHP 4 >= 4.1.0, PHP 5, PHP 7, PHP 8)
= NULL
Врати форматиран стринг sprintf() Работи како
Параметри
format-
Низата за форматирање се состои од нула или повеќе директиви: обични знаци (со исклучок на
%) што се копираат директно во резултатот и спецификации за конверзија, секоја од кои резултира со добивање на сопствен параметар.Спецификацијата за конверзија следи овој прототип:
%[argnum$][flags][width][.precision]specifier.но прифаќа низа од аргументи, наместо променлив број на аргументи.
Цел број проследен со знак долар
$, за да се специфицира кој број аргумент да се третира во конверзијата.Argnum
Знаменце = NULL -Порамни лево во дадената ширина на полето; Десното порамнување е стандардно +Префикс позитивни броеви со знак плус +; Стандардно само негативните се префиксирани со негативен знак.FlagsЈа пополнува низата со празни места. Ова е стандардно. 0Само лево ги пополнува броевите со нули. Со sспецификатори ова може да ги пополни и десно со нули.'(простор)Го полни резултатот со карактерот (char). Ширина
Или цел број што кажува колку знаци (минимум) треба да резултира оваа конверзија, или
*. Ако*се користи, тогаш ширината се дава како дополнителна цел вредност што му претходи на онаа форматирана од спецификаторот.Прецизност
Период
.опционално проследено со цел број или*, чие значење зависи од спецификаторот:-
За
e,E,fandFспецификатори: ова е бројот на цифри што треба да се испечатат по децималната точка (по дифолт, ова е 6). -
За
g,G,handHспецификатори: ова е максималниот број на значајни цифри што треба да се испечатат. -
За
sспецификатор: делува како точка на прекин, поставувајќи максимално ограничување на карактерите на низата.
Забелешка:
Ако е специфициран периодот без експлицитна вредност за прецизност, се претпоставува 0. Ако
*се користи, прецизноста се дава како дополнителна цел вредност што му претходи на онаа форматирана од спецификаторот.Спецификатори Спецификатор = NULL %Буквален процентен знак. Не е потребен аргумент. bАргументот се третира како цел број и се претставува како бинарен број. cАргументот се третира како цел број и се претставува како карактер со таа ASCII. dАргументот се третира како цел број и се претставува како (потпишан) децимален број. eАргументот се третира како научна нотација (на пр. 1.2e+2). EКако eспецификатор, но користи големи букви (на пр. 1.2E+2).fАргументот се третира како пловечки број и се прикажува како пловечки број (свесен за локалот). FАргументот се третира како пловечки број и се прикажува како пловечки број (не свесен за локалот). gОпшт формат. Нека P е еднакво на прецизноста ако е различно од нула, 6 ако прецизноста е изоставена или 1 ако прецизноста е нула. Потоа, ако конверзијата со стил E би имала експонент X: Ако P > X ≥ −4, конверзијата е со стил f и прецизност P − (X + 1). Во спротивно, конверзијата е со стил e и прецизност P − 1. GКако gспецификатор, но користиEandf.hКако gспецификатор, но користиF. Достапно од PHP 8.0.0.HКако gспецификатор, но користиEandF. Достапно од PHP 8.0.0.oАргументот се третира како цел број и се прикажува како октален број. sАргументот се третира и прикажува како стринг. uАргументот се третира како цел број и се прикажува како непотпишан децимален број. xАргументот се третира како цел број и се прикажува како хексадецимален број (со мали букви). XАргументот се третира како цел број и се прикажува како хексадецимален број (со големи букви). Ги ескејпува специјалните знаци во стринг за употреба во SQL изјаваНа
cспецификаторот за тип ги игнорира подлогата и ширината.Ги ескејпува специјалните знаци во стринг за употреба во SQL изјаваОбидот за користење комбинација од спецификаторите за стринг и ширина со множества знаци што бараат повеќе од еден бајт по знак може да резултира со неочекувани резултати.
Променливите ќе бидат претворени во соодветен тип за спецификаторот:
Ракување со типови Тип Спецификатори string sint d,u,c,o,x,X,bfloat e,E,f,F,g,G,h,H -
values-
Вратени вредности
(знак)
format.
Errors/Exceptions
Од PHP 8.0.0, а ValueError се фрла ако бројот на аргументи е нула. Пред PHP 8.0.0, а E_WARNING беше емитирано наместо тоа.
Од PHP 8.0.0, а ValueError се фрла ако [width] е помало од нула или поголемо од PHP_INT_MAX. Пред PHP 8.0.0, а E_WARNING беше емитирано наместо тоа.
Од PHP 8.0.0, а ValueError се фрла ако [precision] е помало од нула или поголемо од PHP_INT_MAX. Пред PHP 8.0.0, а E_WARNING беше емитирано наместо тоа.
Од PHP 8.0.0, а ValueError се фрла кога се даваат помалку аргументи отколку што е потребно. Пред PHP 8.0.0, false беше вратено и а E_WARNING емитирано наместо тоа.
Дневник на промени
| Верзија | = NULL |
|---|---|
| 8.0.0 |
Оваа функција повеќе не враќа false при неуспех.
|
| 8.0.0 |
Фрли а ValueError ако бројот на аргументи е нула; претходно оваа функција емитираше а E_WARNING instead.
|
| 8.0.0 |
Фрли а ValueError if [width] е помало од нула или поголемо од PHP_INT_MAX; претходно оваа функција емитираше а E_WARNING instead.
|
| 8.0.0 |
Фрли а ValueError if [precision] е помало од нула или поголемо од PHP_INT_MAX; претходно оваа функција емитираше а E_WARNING instead.
|
| 8.0.0 |
Фрли а ValueError кога се даваат помалку аргументи отколку што е потребно; претходно оваа функција емитираше а E_WARNING instead.
|
Примери
Пример #1 vsprintf()Врати вредности од низата како форматиран стринг според
<?php
print vsprintf("%04d-%02d-%02d", explode('-', '1988-8-1'));
?>Пример #1 Пример што покажува затворачка ознака што го опфаќа последниот нов ред
1988-08-01
Види Исто така
- printf() Излез на стринг
- sprintf() - Врати форматирана низа
- fprintf() - Запиши форматирана низа во поток
- vprintf() Излез на стринг
- vfprintf() - Запиши форматирана низа во поток
- sscanf() - Парсирај влез од низа според формат
- fscanf() - Парсира влез од датотека според формат
- number_format() - Заокружи дропки надолу
- date() - Форматирај Unix временски печат
Белешки од корисници 11 белешки
<?php
/**
* Like vsprintf, but accepts $args keys instead of order index.
* Both numeric and strings matching /[a-zA-Z0-9_-]+/ are allowed.
*
* Example: vskprintf('y = %y$d, x = %x$1.1f', array('x' => 1, 'y' => 2))
* Result: 'y = 2, x = 1.0'
*
* $args also can be object, then it's properties are retrieved
* using get_object_vars().
*
* '%s' without argument name works fine too. Everything vsprintf() can do
* is supported.
*
* @author Josef Kufner <jkufner(at)gmail.com>
*/
function vksprintf($str, $args)
{
if (is_object($args)) {
$args = get_object_vars($args);
}
$map = array_flip(array_keys($args));
$new_str = preg_replace_callback('/(^|[^%])%([a-zA-Z0-9_-]+)\$/',
function($m) use ($map) { return $m[1].'%'.($map[$m[2]] + 1).'$'; },
$str);
return vsprintf($new_str, $args);
}
?><?php
/**
* Return a formatted string like vsprintf() with named placeholders.
*
* When a placeholder doesn't have a matching key in `$args`,
* the placeholder is returned as is to see missing args.
* @param string $format
* @param array $args
* @param string $pattern
* @return string
*/
function p($format, array $args, $pattern="/\{(\w+)\}/") {
return preg_replace_callback($pattern, function ($matches) use ($args) {
return @$args[$matches[1]] ?: $matches[0];
}, $format);
}
$args = ["database"=>"people", "user"=>"staff", "pass"=>"pass123", "host"=>"localhost"];
// With PHP-like placeholders: the variable is embedded in a string "{$database}" but without the dollar sign
$format = <<<SQL
CREATE DATABASE IF NOT EXISTS {database};
GRANT ALL PRIVILEGES ON {database_name}.* TO '{user}'@'{host}';
SET PASSWORD = PASSWORD('{pass}');
SQL;
echo p($format, $args);
/*
Result:
CREATE DATABASE IF NOT EXISTS people;
GRANT ALL PRIVILEGES ON {database_name}.* TO 'staff'@'localhost';
SET PASSWORD = PASSWORD('pass123');
The `{database_name}` placeholder doesn't exist as a matching key in `$args` so it's returned as is.
*/
// With Ruby-like placeholders
$format = <<<SQL
CREATE DATABASE IF NOT EXISTS :database;
GRANT ALL PRIVILEGES ON :database_name.* TO ':user'@':host';
SET PASSWORD = PASSWORD(':pass');
SQL;
echo p($format, $args, "/:(\w+)/");
/*
Result:
CREATE DATABASE IF NOT EXISTS people;
GRANT ALL PRIVILEGES ON :database_name.* TO 'staff'@'localhost';
SET PASSWORD = PASSWORD('pass123');
The `:database_name` placeholder doesn't exist as a matching key in `$args` so it's returned as is.
*/Note that this function now throws an ValueError* as of PHP 8.0 if there is an error:
$ php -r 'var_dump(vsprintf("%d", []));'
> Fatal error: Uncaught ValueError: The arguments array must contain 1 items, 0 given in Command line code:1
*ValueError is new in PHP 8.0, so if you want to make your code compatible to PHP 7.x you should test that the arguments array has the correct length.This can be used for quick and dirty internationalization:
<?php
$GLOBALS['strings']['example'] = "There are %d people.";
// Loads a phrase from the translations list in lang/$lang/phrases.php
function t() {
$args = func_get_args();
$nArgs = func_num_args();
$phrase = array_shift($args);
$nArgs--;
include_once("../lang/" . lang() . "/phrases.php");
if (isset($GLOBALS['strings'][$phrase])) {
return vsprintf($GLOBALS['strings'][$phrase], $args);
} else {
return '<span style="color: #ff0000">Untranslated string: ' . $phrase . '</span>';
}
}
?>vnsprintf is equal to vsprintf except for associative, signed or floating keys.
vnsprintf supports for example "%assocKey$05d", "%-2$'+10s" and "%3.2$05u", vsprintf doesn't
vnsprintf( '%2$d', $array) [2nd value] is equal to vsprintf( '%2$d', $array) [2nd value]
vnsprintf( '%+2$d', $array) [key = 2] is equal to vnsprintf( '%2.0$d', $array) [key = 2]
vnsprintf( '%+2$d', $array) [key = 2] is different of vsprintf( '%+2$d', $array) [unsupported]
When you use signed or floating keys, vnsprintf searchs for the signed truncated key of the original array
Note¹: vnsprintf does not support for example "%someKeyf" (floating number, key = someKey) or "%+03d" (signed decimal number, key = 3), you should use "%someKey$f" or "%+03$d" respectively.
Note²: "%+03d" (or "%1$+03d") will be interpreted as signed zero-padded decimal number
<?php
function vnsprintf( $format, array $data)
{
preg_match_all( '/ (?<!%) % ( (?: [[:alpha:]_-][[:alnum:]_-]* | ([-+])? [0-9]+ (?(2) (?:\.[0-9]+)? | \.[0-9]+ ) ) ) \$ [-+]? \'? .? -? [0-9]* (\.[0-9]+)? \w/x', $format, $match, PREG_SET_ORDER | PREG_OFFSET_CAPTURE);
$offset = 0;
$keys = array_keys($data);
foreach ( $match as &$value )
{
if ( ( $key = array_search( $value[1][0], $keys) ) !== FALSE || ( is_numeric( $value[1][0]) && ( $key = array_search( (int)$value[1][0], $keys) ) !== FALSE ) ) {
$len = strlen( $value[1][0]);
$format = substr_replace( $format, 1 + $key, $offset + $value[1][1], $len);
$offset -= $len - strlen( $key);
}
}
return vsprintf( $format, $data);
}
$examples = array(
2.8=>'positiveFloat', // key = 2 , 1st value
-3=>'negativeInteger', // key = -3 , 2nd value
'my_name'=>'someString' // key = my_name , 3rd value
);
echo vsprintf( "%%my_name\$s = '%my_name\$s'\n", $examples); // [unsupported]
echo vnsprintf( "%%my_name\$s = '%my_name\$s'\n", $examples); // output : "someString"
echo vsprintf( "%%2.5\$s = '%2.5\$s'\n", $examples); // [unsupported]
echo vnsprintf( "%%2.5\$s = '%2.5\$s'\n", $examples); // output : "positiveFloat"
echo vsprintf( "%%+2.5\$s = '%+2.5\$s'\n", $examples); // [unsupported]
echo vnsprintf( "%%+2.5\$s = '%+2.5\$s'\n", $examples); // output : "positiveFloat"
echo vsprintf( "%%-3.2\$s = '%-3.2\$s'\n", $examples); // [unsupported]
echo vnsprintf( "%%-3.2\$s = '%-3.2\$s'\n", $examples); // output : "negativeInteger"
echo vsprintf( "%%2\$s = '%2\$s'\n", $examples); // output : "negativeInteger"
echo vnsprintf( "%%2\$s = '%2\$s'\n", $examples); // output : [= vsprintf]
echo vsprintf( "%%+2\$s = '%+2\$s'\n", $examples); // [unsupported]
echo vnsprintf( "%%+2\$s = '%+2\$s'\n", $examples); // output : "positiveFloat"
echo vsprintf( "%%-3\$s = '%-3\$s'\n", $examples); // [unsupported]
echo vnsprintf( "%%-3\$s = '%-3\$s'\n", $examples); // output : "negativeInteger"
?>Please note: The same functionality (sortof) can be attained between version 4.0.4 and 4.1.0 using call_user_func_array.
Example:
call_user_func_array("sprintf", $arg)
First element of $arg is the format. This rescued me in a situation where version 4.1.0 wasn't available.Using a heredoc with vprintf:
<?php
$string = <<<THESTRING
I like the state of %1\$s <br />
I picked: %2\$d as a number, <br />
I also picked %2\$d as a number again <br />
%3\$s<br />
THESTRING;
$returnText = vprintf( $string, array('Oregon','7','I Love Oregon') );
echo $returnText;
?>MessageFormatter::formatMessage(string $locale, string $pattern, array $values)
or
msgfmt_format_message(string $locale, string $pattern, array $values)
can be an alternativ option:
$values = ['rank'=>10, 'name'=>'Frank']
MessageFormatter::formatMessage('en', 'Hello {name}, your rank is {rank}', $values);
Also access by index is possible "{1}", formating and a lot more.
https://unicode-org.github.io/icu/userguide/format_parse/numbers/vsprintf() accepts arrays with any keys, so the array_shift() technique is unnecessary when writing a printf-type function. Any parameters you require are easily unset from the array you retrieve with func_get_args():
<?php
function mysprintf($format) {
$args = func_get_args();
unset($args[0]); /* get rid of "$format" */
return vsprintf($format, $args);
}
/* I use this technique in production code as follows: */
function logf($target, $string) {
$args = func_get_args();
unset($args[0], $args[1]);
fprintf($GLOBALS['config']['logtargets'][$target],
"[%s] %s\n", date('H:i'), wordwrap(vsprintf($string, $args), 75, '\n\r '));
}
/* e.g.:
logf(DEBUG, "Oops! %s", mysql_error());
*/
?>
array_shift() and other costly array operations aren't required, as far as I know. I could be wrong.It's necessary to clearly how to apply argument swapping when using an array of arguments. One might be tempted to use %0$ to reference $args[0].
In reality, the position specifier is always the array index+1:
$args[0] is referenced by %1$...
$args[1] is referenced by %2$...
etc.
Similarly, the first subpattern of a RegEx match would be found in $matches[1], the second in $match[2], etc. However if the $matches array is used as arguments to vsprint(), then the position specifier is subpattern+1:
preg_match( $pattern, $subject, $matches );
vsprintf( 'Full Match = %1$s, first Subpattern = %2$s, second Subpattern = %3$s', $matches );