©
This document uses PHP Chinese website manual Release
(PHP 4 >= 4.1.0, PHP 5)
vsprintf — 返回格式化字符串
$format
, array $args
)作用与 sprintf() 函数类似,但是接收一个数组参数,而不是一系列可变数量的参数。
format
关于 format
的描述,参见 sprintf() 。
args
根据 format
( sprintf() 函数文档中有相关描述)参数指定的格式,在一个字符串中返回一系列值。
Example #1 vsprintf() : 前导 0 的整数
<?php
print vsprintf ( "%04d-%02d-%02d" , explode ( '-' , '1988-8-1' )); // 1988-08-01
?>
[#1] dee jay simple zero07 at geemail dawt co [2013-01-17 17:03:19]
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;
?>
[#2] Josef Kufner [2012-11-20 23:51:39]
<?php
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);
}
?>
[#3] thomas att familie dash flori dot de [2012-10-30 23:46:59]
Here is my example for named placeholders. It uses python like named placeholders except that it only allows /[a-z][a-zA-Z0-9_]/ for names.
<?php
function vsprintfn($format, $args) {
// search format patterns
preg_match_all('/((?:^|[^%])(?:%%)*)%(\([a-z][a-zA-Z0-9_]*\))?((\+|-)?(0| |\'.)?-?[0-9\.]*[bcdeEufFgGosxX])/', $format, $matches);
// determine the order of the arguments
$j = 0;
$order = array();
foreach ($matches[0] as $i => $match) {
if ($matches[2][$i] == '') {
$key = $j++;
} else {
$key = substr($matches[2][$i],1,-1);
}
$order[] = $key;
}
// prepare the data array for vsprintf in the given order
$data = array();
foreach ($order as $key) {
if (isset($args[$key])) {
$data[] = $args[$key];
}
}
// replace named format patterns with default format patterns
$format = preg_replace('/((?:^|[^%])(?:%%)*)%(\([a-z][a-zA-Z0-9_]*\))((\+|-)?(0| |\'.)?-?[0-9\.]*[bcdeEufFgGosxX])/', '$1%$3', $format);
// return formatted string
return vsprintf($format, $data);
}
$exampleData = array(0=>2.2314123123,'test'=>2.1234883);
echo vsprintfn('%%2.5f = %2.5f', $exampleData) . "\n";
echo vsprintfn('%%(test)09.5f = %(test)\'%9.5f', $exampleData) . "\n";
?>
[#4] strata_ranger at hotmail dot com [2010-06-29 11:15:16]
Here's a simple variation on vsprintf() suitable for use with database queries where the results were retrieved as an associative array keyed by column names.
<?php
function dbsprintf($format, $fields, $row)
// $format - sprintf() compatible format string
// $row - Array containing key/value pairs of data
// $fields - Array containing key names (from $row) that are to be used as arguments
{
// Loop through $fields and insert the corresponding values from $row
foreach($fields as &$value)
{
$value = $row[$value];
} unset($value);
// Format the string and return
return vsprintf($format, $fields);
}
// Some data
$row = Array('id' => '12', 'name' => 'World');
// Outputs "Hello World!"
echo dbsprintf('Hello, %s!', Array('name'), $row);
// Outputs "Hello 12!"
echo dbsprintf('Hello, %s!', Array('id'), $row);
?>
[#5] jeppe dot dyrby at gmail dot com [2009-03-04 04:52:45]
Heres a new version of the vnsprintf function, i call it dsprintf, but that should matter.
<?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 = "Hello, %(place)s, how is it hanning at %(place)s? %s works just as well";
$find = array(
'place' => 'world',
'sprintf',
'not used'
);
echo dsprintf($str, $find);
// 'Hello, world, how is it hanning at world? sprintf works just as well'
?>
[#6] www dot wesley at gmail dot com [2008-06-16 13:56:17]
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"
?>
[#7] Roadster [2006-09-30 19:44:52]
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.
[#8] jon at ardentcreative dot co dot uk [2006-02-17 03:56:15]
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>';
}
}
?>
[#9] toneee at g mail dot com [2005-12-19 09:27:45]
I found this function to be useful for formatting sql queries.
I do something like this:
function sql_build($template, $params = array()) {
global $sql_templates;
if (isset($sql_templates[$template])) {
$sql = vsprintf($sql_templates[$template], $params);
return $sql;
}
return false;
}
// Fetch list of contacts, for a given section id
$sql_templates['contacts_by_section'] = <<<ENDSQL
select
id,
name,
email,
address,
photo_id
from
contacts
where
section_id = %d
ENDSQL;
You also give yourself an added layer of security on the sql due to the sprintf formatting. For example, using %d will not allow any sql injection for that parameter.
[#10] tbS dot P dot A dot M at S dot U dot K dot Staylorbarstow dot com [2005-03-01 11:49:32]
Simple but useful routine:
<?php
function vsprintf_iter($fmt,$data) {
if (!is_array($data)) return false;
$ret = '';
foreach ($data as $d) {
$ret .= vsprintf($fmt,$d);
}
return $ret;
}
?>
[#11] jed at NOSPAM dot jed dot bz [2004-05-22 18:48:36]
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]);
return vsprintf($format, $args);
}
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 '));
}
?>
array_shift() and other costly array operations aren't required, as far as I know. I could be wrong.
[#12] samviseNOSPAM at hobbitonNOSPAM dot it [2002-07-02 06:55:01]
i wrote a short function that make use of vsprintf. It is useful in first coding/debugging of php scripts, because it is called like a simple printf and it display in italic (you can change it of course ;-) ) every debug messages, making it easy to remove them when your code is ready.
here goes :
<?php
function printd() {
$debug_array=func_get_args();
$debug_numargs=func_num_args();
$debug_fmt=$debug_array[0];
for ( $i = 0 ; $i < $debug_numargs ; $i++ )
$debug_array[$i] = $debug_array[$i+1];
$debug_text=vsprintf($debug_fmt, $debug_array);
printf("--> debug <i>%s</i>\n",
$debug_text);
}
?>