字符串函数
在线手册:中文  英文

vsprintf

(PHP 4 >= 4.1.0, PHP 5)

vsprintf返回格式化字符串

说明

string vsprintf ( string $format , array $args )

作用与 sprintf() 函数类似,但是接收一个数组参数,而不是一系列可变数量的参数。

参数

format

关于 format 的描述,参见 sprintf()

args

返回值

根据 formatsprintf() 函数文档中有相关描述)参数指定的格式,在一个字符串中返回一系列值。

范例

Example #1 vsprintf(): 前导 0 的整数

<?php
print vsprintf("%04d-%02d-%02d"explode('-''1988-8-1')); // 1988-08-01
?>

参见


字符串函数
在线手册:中文  英文

用户评论:

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;
?>

Josef Kufner (2012-11-20 23:51:39)

<?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);
}
?>

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

/**
 * Returns a formatted string. Accepts named arguments.
 * @param string $format
 * @param array $args
 * @return string
 **/
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";

?>

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);

?>

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'
?>

www dot wesley at gmail dot com (2008-11-15 12:02:02)

Here's the new version of vnsprintf()

Thanks to "César K?stli" and "Jan Ulrych"

<?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$matchPREG_SET_ORDER PREG_OFFSET_CAPTURE);
    
$offset 0;
    
$keys array_keys($data);
    foreach( 
$match as &$value )
    {
        if ( ( 
$key array_search$value[1][0], $keysTRUE) ) !== FALSE || ( is_numeric$value[1][0] ) && ( $key array_search( (int)$value[1][0], $keysTRUE) ) !== FALSE) )
        {
            
$len strlen$value[1][0]);
            
$format substr_replace$format$key$offset $value[1][1], $len);
            
$offset -= $len strlen$key);
        }
    }
    return 
vsprintf$format$data);
}

$example = array(
    
=> 'first',
    
'second' => 'second',
    
'third',
    
4.2 => 'fourth',
    
'fifth',
    -
6.7 => 'sixth',
    
'seventh',
    
'eighth',
    
'9' => 'ninth',
    
'tenth' => 'tenth',
    
'-11.3' => 'eleventh',
    
'twelfth'
);

echo 
vnsprintf'%1$s %2$s %3$s %4$s %5$s %6$s %7$s %8$s %9$s %10$s %11$s %12$s<br />'$example); // acts like vsprintf
echo vnsprintf'%+0$s %second$s %+1$s %+4$s %+5$s %-6.5$s %+6$s %+7$s %+9$s %tenth$s %-11.3$s %+10$s<br />'$example);
?>

jan dot ulrych at gmail dot com (2008-07-14 01:45:20)

Thanks a lot for vnsprintf function.
However, there is a little bug which occurs only when the number of parameters in the $data is greater than 10.
The replacement is not performed correctly when two or more replacements should be performed. When the referenced parameter is at position greater or equal to 10 in $data array and it precedes any other referenced parameter in $format string then the subsequent replacement(s) are not performed correctly.
The $offset value should be calculated as
$offset -= $len - strlen( 1 + $key);
as we substitute string (or float) identifier in the original $format string by value 1 + $key, not $key.

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$matchPREG_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$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"
?>

iisys_ at hotmail dot com (2006-11-19 10:29:15)

I've made this simple function for more compatibility with different applications.
As arguments, it can accept an array or single arguments.

<?php
function asprintf() {
    
$a func_get_args();
    
$format array_shift($a);
    if (
is_array($a[0])) {
        
$a $a[0];
    }
    return 
vsprintf($format$a);
}

# Examples.

$sql_arguments = array('fields' => '*''table' => 'users''field' => 'user''value' => 'exploited');

echo 
asprintf("SELECT %s FROM %s WHERE %s = '%s'"$sql_arguments);
# Would output: SELECT * FROM users WHERE user = 'exploited'

echo asprintf("SELECT %s FROM %s WHERE %s = '%s'"'*''users''user''exploited');
# Would output the same.
?>

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.

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>';
    }
}
?>

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.

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;
}
?>

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]); /* 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.

drm at melp dot nl (2004-01-29 21:02:51)

When combining with func_get_args as above, you might want to consider using array_shift:

<?
function someFunc () {
   $args = func_get_args ();
   $format = array_shift ( $args );
   // do something
   return vsprintf ( $format, $args );
}
?>

keeps it clean ;)

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 $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);
}
?>

易百教程