note 94608 added to function.sprintf
| From: | nate at frickenate dot com | Date: | Sat, 14 Nov 2009 07:45:40 +0000 |
| Subject: | note 94608 added to function.sprintf | ||
| Groups: | php.notes | ||
| Request: | Send a blank email to php-notes+get-162899@lists.php.net to get a copy of this message | ||
Here's a clean, working version of functions to allow using named arguments instead of numeric
ones. ex: instead of sprintf('%1$s', 'Joe');, we can use
sprintf('%name$s', array('name' => 'Joe'));. I've provided 2
different versions: the first uses the php-like syntax (ex: %name$s), while the second uses the
python syntax (ex: %(name)s).
<?php
/**
* version of sprintf for cases where named arguments are desired (php syntax)
*
* with sprintf: sprintf('second: %2$s ; first: %1$s', '1st', '2nd');
*
* with sprintfn: sprintfn('second: %second$s ; first: %first$s', array(
* 'first' => '1st',
* 'second'=> '2nd'
* ));
*
* @param string $format sprintf format string, with any number of named arguments
* @param array $args array of [ 'arg_name' => 'arg value', ... ]
replacements to be made
* @return string|false result of sprintf call, or bool false on error
*/
function sprintfn ($format, array $args = array()) {
// map of argument names to their corresponding sprintf numeric argument value
$arg_nums = array_slice(array_flip(array_keys(array(0 => 0) + $args)), 1);
// find the next named argument. each search starts at the end of the previous replacement.
for ($pos = 0; preg_match('/(?<=%)([a-zA-Z_]\w*)(?=\$)/', $format, $match,
PREG_OFFSET_CAPTURE, $pos);) {
$arg_pos = $match[0][1];
$arg_len = strlen($match[0][0]);
$arg_key = $match[1][0];
// programmer did not supply a value for the named argument found in the format string
if (! array_key_exists($arg_key, $arg_nums)) {
user_error("sprintfn(): Missing argument '${arg_key}'",
E_USER_WARNING);
return false;
}
// replace the named argument with the corresponding numeric one
$format = substr_replace($format, $replace = $arg_nums[$arg_key], $arg_pos, $arg_len);
$pos = $arg_pos + strlen($replace); // skip to end of replacement for next iteration
}
return vsprintf($format, array_values($args));
}
/**
* version of sprintf for cases where named arguments are desired (python syntax)
*
* with sprintf: sprintf('second: %2$s ; first: %1$s', '1st', '2nd');
*
* with sprintfn: sprintfn('second: %(second)s ; first: %(first)s', array(
* 'first' => '1st',
* 'second'=> '2nd'
* ));
*
* @param string $format sprintf format string, with any number of named arguments
* @param array $args array of [ 'arg_name' => 'arg value', ... ]
replacements to be made
* @return string|false result of sprintf call, or bool false on error
*/
function sprintfn ($format, array $args = array()) {
// map of argument names to their corresponding sprintf numeric argument value
$arg_nums = array_slice(array_flip(array_keys(array(0 => 0) + $args)), 1);
// find the next named argument. each search starts at the end of the previous replacement.
for ($pos = 0; preg_match('/(?<=%)\(([a-zA-Z_]\w*)\)/', $format, $match,
PREG_OFFSET_CAPTURE, $pos);) {
$arg_pos = $match[0][1];
$arg_len = strlen($match[0][0]);
$arg_key = $match[1][0];
// programmer did not supply a value for the named argument found in the format string
if (! array_key_exists($arg_key, $arg_nums)) {
user_error("sprintfn(): Missing argument '${arg_key}'",
E_USER_WARNING);
return false;
}
// replace the named argument with the corresponding numeric one
$format = substr_replace($format, $replace = $arg_nums[$arg_key] . '$', $arg_pos,
$arg_len);
$pos = $arg_pos + strlen($replace); // skip to end of replacement for next iteration
}
return vsprintf($format, array_values($args));
}
?>
----
Server IP: 66.207.199.35
Probable Submitter: 66.131.25.74
----
Manual Page -- http://www.php.net/manual/en/function.sprintf.php
Edit -- https://master.php.net/note/edit/94608
Del: integrated -- https://master.php.net/note/delete/94608/integrated
Del: useless -- https://master.php.net/note/delete/94608/useless
Del: bad code -- https://master.php.net/note/delete/94608/bad+code
Del: spam -- https://master.php.net/note/delete/94608/spam
Del: non-english -- https://master.php.net/note/delete/94608/non-english
Del: in docs -- https://master.php.net/note/delete/94608/in+docs
Del: other reasons-- https://master.php.net/note/delete/94608
Reject -- https://master.php.net/note/reject/94608
Search -- https://master.php.net/manage/user-notes.php