note 94608 added to function.sprintf

From: 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

« previous php.notes (#162899) next »