sprintf

(PHP 4, PHP 5, PHP 7, PHP 8)

sprintfBiçemli bir dizge döndürür

Açıklama

function sprintf(string $biçem, mixed ...$değerler): string

biçem dizgesiyle biçemlenerek üretilmiş bir dizge döndürür.

Bağımsız Değişkenler

biçem

Biçem dizgesi sıfır veya daha fazla yönergeden oluşur: doğrudan sonuca kopyalanmış sıradan karakterler (% hariç) ve dönüşüm belirtimleri, her biri kendi bağımsız değişkeninin getirilmesiyle sonuçlanır.

Bir dönüşüm belirtiminin sözdizimi: %[degnum$][seçenekler][genişlik][.hassasiyet]belirteç.

degnum

Ardına bir dolar imi $ konmuş bir tamsayı; dönüşümde ele alınacak bağımsız değişken sayısını belirler.

seçenekler
Seçenek Açıklama
- Verilen alan genişliğinde sola dayalı; Sağa dayalılık öntanımlıdır.
+ Pozitif sayıların önüne artı imi konur; Öntanımlı olarak sadece negatif sayılara eksi imi konur.
(boşluk) Sonuca boşluklarla dolgu yapar. Bu öntanımlıdır.
0 Sayılar sadece soldan sıfırla doldurulur. s belirteçleri ile sağ taraf da sıfırla doldurulur.
'(krk) Sonuca (krk) karakteri ile dolgu yapılır.

genişlik

Bu dönüşümün kaç karakterle sonuçlanacağının belirtildiği tamsayı veya *. * kullanılmışsa, genişlik, belirtici tarafından biçimlendirilmiş değerden önce ek bir tamsayı değeri olarak sağlanır.

hassasiyet

Bir nokta . ve ardından anlamı belirtece bağlı olan seçimlik bir tamsayı veya *:

  • e, E, f ve F belirteçleri için: ondalık noktadan sonra yazdırılacak rakam sayısı (6 öntanımlıdır)

  • g ve G, h ve H belirteçleri için: yazdırılacak maksimum anlamlı basamak sayısı.

  • s belirteci için: dizeye azami karakter sınırı koyan bir kesme noktası gibi davranır.

Bilginize:

Nokta, hassasiyet için açık bir değer olmadan belirtilirse, 0 varsayılır. * kullanılmışsa, genişlik, belirtici tarafından biçimlendirilmiş değerden önce ek bir tamsayı değeri olarak sağlanır.

Belirteçler
Belirteç Açıklama
% Yüzde karakteri. Değer gerekmez.
b Değer bir tamsayı olarak ele alınır ve ikil bir sayı olarak gösterilir.
c Değer bir tamsayı olarak ele alınır ve ASCII bir karakter olarak gösterilir.
d Değer bir tamsayı olarak ele alınır ve (işaretli) bir ondalık sayı olarak gösterilir.
e Değer bilimsel bir gösterim (örn. 1.2e+2) olarak ele alınır. Hassasiyet belirteci,ondalık noktadan sonraki basamakların sayısını ifade eder.
E e belirteci gibi, farklı olarak büyük harf kullanır (örn. 1.2E+2).
f Değer kayan noktalı sayı olarak ele alınır ve kayan noktalı sayı olarak gösterilir (yerele uygun).
F Değer kayan noktalı sayı olarak ele alınır ve kayan noktalı sayı olarak gösterilir (yerele bakmaz).
g

Genel biçem.

P sıfırdan farklı hassasiyet olsun, hassasiyet verilmemişse 6, hassasiyet sıfır ise 1 olsun. E tarzındaki dönüşümün üssü X ise:

P > X ≥ −4 ise, dönüşüm f tarzı ve hassasiyet P − (X + 1) olur. Aksi takdirde, dönüşüm e tarzı ve hassasiyet P − 1 olur.

G g gibidir fakat E ve f kullanır.
h g gibidir fakat F kullanır. PHP 8.0.0 ve sonrasında kullanılabilir.
H ggibidir fakat E ve F kullanır. PHP 8.0.0 ve sonrasında kullanılabilir.
o Değer bir tamsayı olarak ele alınır ve sekizlik bir sayı olarak gösterilir.
s Değer bir dizge olarak ele alınır ve gösterilir.
u Değer bir tamsayı olarak ele alınır ve işaretsiz bir ondalık sayı olarak gösterilir.
x Değer bir tamsayı olarak ele alınır ve onaltılık bir sayı olarak gösterilir (küçük harfli).
X Değer bir tamsayı olarak ele alınır ve onaltılık bir sayı olarak gösterilir (büyük harfli).

Uyarı

c tür belirteci dolguyu ve genişliği yoksayar.

Uyarı

Karakter başına birden fazla bayt gerektiren karakter kümeleriyle dizge ve genişlik belirteçlerini bir arada kullanmaya çalışmak, beklenmeyen sonuçlar verebilir

Değişkenler, belirteç için uygun bir türe zorlanacaktır:

Tür Yönetimi
Tür Belirteçler
string s
int d, u, c, o, x, X, b
double e, E, f, F, g, G, h, H

değerler

Dönen Değerler

biçem dizgesine göre biçemlendirilerek üretilen bir dizge döner.

Hatalar/İstisnalar

PHP 8.0.0 ve sonrasında, bağımsız değişken sayısı sıfırsa ValueError oluşuyor. PHP 8.0.0 öncesinde bunun yerine bir E_WARNING uyarısı verilirdi.

PHP 8.0.0 ve sonrasında, [width] (genişlik) sıfırdan küçükse veya PHP_INT_MAX'tan büyükse bir ValueError oluşuyor. PHP 8.0.0 öncesinde, bir E_WARNING uyarısı verilirdi.

PHP 8.0.0 ve sonrasında, [precision] (hassasiyet) sıfırdan küçükse veya PHP_INT_MAX'tan büyükse bir ValueError oluşuyor. PHP 8.0.0 öncesinde, bir E_WARNING uyarısı verilirdi.

PHP 8.0.0 ve sonrasında, gereğinden daha az bağımsız değişken verildiğinde bir ArgumentCountError oluşuyor. PHP 8.0.0 öncesinde, bir E_WARNING uyarısı verilirdi.

Sürüm Bilgisi

Sürüm: Açıklama
8.0.0 Bu işlev başarısızlık durumunda artık false döndürmüyor.
8.0.0 Bağımsız değişken sayısı sıfırsa ValueError oluşuyor. Evvelce bunun yerine bir E_WARNING uyarısı verilirdi.
8.0.0 [width] (genişlik) sıfırdan küçükse veya PHP_INT_MAX'tan büyükse bir ValueError oluşuyor; evvelce bir E_WARNING uyarısı verilirdi.
8.0.0 [precision] (hassasiyet) sıfırdan küçükse veya PHP_INT_MAX'tan büyükse bir ValueError oluşuyor; evvelce bir E_WARNING uyarısı verilirdi.
8.0.0 Gereğinden daha az bağımsız değişken verildiğinde bir ArgumentCountError oluşuyor; evvelce bir E_WARNING uyarısı verilirdi.

Örnekler

Örnek 1 - Bağımsız değişken takaslama

Biçem dizgesi bağımsız değişken numaralama/takaslama destekliyor.

<?php
$num = 5;
$location = 'tree';

$format = 'There are %d monkeys in the %s';
echo sprintf($format, $num, $location);
?>

Yukarıdaki örneğin çıktısı:

There are 5 monkeys in the tree

Biçem dizgesini ayrı bir dosyada oluşturduğunuzu varsayalım. Çünkü ona u12a uygulamak ve yeniden yazmak istiyoruz:

<?php
$format = 'The %s contains %d monkeys';
echo sprintf($format, $num, $location);
?>

Artık bir sorunumuz var. Biçem dizgesindeki belirteçlerin sırası koddaki bağımsız değişken sırasına uygun değil. Koda dokunmak istemiyoruz, biçem dizgesindeki belirteçler koda uyum sağlasın istiyoruz. Bu durumda biçem dizgesini şöyle yararız:

<?php
$format = 'The %2$s contains %1$d monkeys';
echo sprintf($format, $num, $location);
?>

Belirteçlerin bir yararı da koda bağımsız değişken eklemeksizin belirteçlerin yinelenebilmesidir.

<?php
$format = 'The %2$s contains %1$d monkeys.
           That\'s a nice %2$s full of %1$d monkeys.';
echo sprintf($format, $num, $location);
?>

Bağımsız değişken takaslama yapılırken n$ konum belirteci hemen yüzde iminden (%) sonra, diğer belirteçlerden önce gelmelidir; aşağıdaki gibi:

Örnek 2 - Dolgu karakteri belirtmek

<?php
echo sprintf("%'.9d\n", 123);
echo sprintf("%'.09d\n", 123);
?>

Yukarıdaki örneğin çıktısı:

+......123
+000000123

Örnek 3 - Konum belirteçlerini diğer belirteçlerle birlikte kullanmak

<?php
+$format = 'The %2$s contains %1$04d monkeys';
+echo sprintf($format, $num, $location);
?>

Yukarıdaki örneğin çıktısı:

The tree contains 0005 monkeys

Örnek 4 - sprintf() ve sıfır dolgulu tamsayılar

<?php
$isodate = sprintf("%04d-%02d-%02d", $year, $month, $day);
?>

Örnek 5 - sprintf() ve para biçemleme

<?php
$money1 = 68.75;
$money2 = 54.35;
$money = $money1 + $money2;
echo $money;
echo "\n";
$formatted = sprintf("%01.2f", $money);
echo $formatted;
?>

Yukarıdaki örneğin çıktısı:

123.1
123.10

Örnek 6 - sprintf() ve bilimsel gösterim

<?php
$number = 362525200;

echo sprintf("%.3e", $number);
?>

Yukarıdaki örneğin çıktısı:

3.625e+8

Ayrıca Bakınız

  • printf() - Biçemli bir dizge çıktılar
  • fprintf() - Biçemli dizgeyi bir akıma yazar
  • vprintf() - Biçemli bir dizge çıktılar
  • vsprintf() - Biçemli bir dizge döndürür
  • vfprintf() - Biçemli dizgeyi bir akıma yazar
  • sscanf() - Girdi dizgesini belli bir biçeme göre yorumlar
  • fscanf() - Bir dosyadaki girdiyi belli bir biçeme göre çözümler
  • number_format() - Sayıyı binlik bölümlere ayırır
  • date() - Unix zaman damgasını biçimlendirir

add a note

User Contributed Notes 34 notes

up
109
remy dot damour at -please-no-spam-laposte dot net
17 years ago
With printf() and sprintf() functions, escape character is not backslash '\' but rather '%'.

Ie. to print '%' character you need to escape it with itself:
<?php
printf('%%%s%%', 'koko'); #output: '%koko%'
?>
up
74
Alex R. Gibbs
13 years ago
1.  A plus sign ('+') means put a '+' before positive numbers while a minus sign ('-') means left justify.  The documentation incorrectly states that they are interchangeable.  They produce unique results that can be combined:

<?php
echo sprintf ("|%+4d|%+4d|\n",   1, -1);
echo sprintf ("|%-4d|%-4d|\n",   1, -1);
echo sprintf ("|%+-4d|%+-4d|\n", 1, -1);
?>

outputs:

|  +1|  -1|
|1   |-1  |
|+1  |-1  |

2.  Padding with a '0' is different than padding with other characters.  Zeros will only be added at the front of a number, after any sign.  Other characters will be added before the sign, or after the number:

<?php
echo sprintf ("|%04d|\n",   -2);
echo sprintf ("|%':4d|\n",  -2);
echo sprintf ("|%-':4d|\n", -2);

// Specifying both "-" and "0" creates a conflict with unexpected results:
echo sprintf ("|%-04d|\n",  -2);

// Padding with other digits behaves like other non-zero characters:
echo sprintf ("|%-'14d|\n", -2);
echo sprintf ("|%-'04d|\n", -2);
?>

outputs:

|-002|
|::-2|
|-2::|
|-2  |
|-211|
|-2  |
up
7
iannacone
2 years ago
it is also worth to notice that Argnum starts from 1 and NOT 0
up
5
Anonymous
4 years ago
If the format string is enclosed in double-quotes (""), you need to escape the dollar sign after argnum with a backslash character (\), like this %1\$s, so that the PHP doesn't try to interpret them as variable. Using a backslash like this is called an escape sequence.

<?php
// Sample string
$number = 499;
$format = "The number without decimal points: %1\$d, and the number with two decimal points: %1\$.2f";

// Formatting and print the string
printf($format, $number);
?>
up
24
kontakt at myseosolution dot de
11 years ago
There are already some comments on using sprintf to force leading leading zeros but the examples only include integers. I needed leading zeros on floating point numbers and was surprised that it didn't work as expected.

Example:
<?php
sprintf('%02d', 1);
?>

This will result in 01. However, trying the same for a float with precision doesn't work:

<?php
sprintf('%02.2f', 1);
?>

Yields 1.00. 

This threw me a little off. To get the desired result, one needs to add the precision (2) and the length of the decimal seperator "." (1). So the correct pattern would be

<?php
sprintf('%05.2f', 1);
?>

Output: 01.00

Please see http://stackoverflow.com/a/28739819/413531 for a more detailed explanation.
up
17
timo dot frenay at gmail dot com
15 years ago
Here is how to print a floating point number with 16 significant digits regardless of magnitude:

<?php
    $result = sprintf(sprintf('%%.%dF', max(15 - floor(log10($value)), 0)), $value);
?>

This works more reliably than doing something like sprintf('%.15F', $value) as the latter may cut off significant digits for very small numbers, or prints bogus digits (meaning extra digits beyond what can reliably be represented in a floating point number) for very large numbers.
up
17
viktor at textalk dot com
17 years ago
A more complete and working version of mb_sprintf and mb_vsprintf. It should work with any "ASCII preserving" encoding such as UTF-8 and all the ISO-8859 charsets. It handles sign, padding, alignment, width and precision. Argument swapping is not handled.

<?php
if (!function_exists('mb_sprintf')) {
  function mb_sprintf($format) {
      $argv = func_get_args() ;
      array_shift($argv) ;
      return mb_vsprintf($format, $argv) ;
  }
}
if (!function_exists('mb_vsprintf')) {
  /**
   * Works with all encodings in format and arguments.
   * Supported: Sign, padding, alignment, width and precision.
   * Not supported: Argument swapping.
   */
  function mb_vsprintf($format, $argv, $encoding=null) {
      if (is_null($encoding))
          $encoding = mb_internal_encoding();

      // Use UTF-8 in the format so we can use the u flag in preg_split
      $format = mb_convert_encoding($format, 'UTF-8', $encoding);

      $newformat = ""; // build a new format in UTF-8
      $newargv = array(); // unhandled args in unchanged encoding

      while ($format !== "") {
      
        // Split the format in two parts: $pre and $post by the first %-directive
        // We get also the matched groups
        list ($pre, $sign, $filler, $align, $size, $precision, $type, $post) =
            preg_split("!\%(\+?)('.|[0 ]|)(-?)([1-9][0-9]*|)(\.[1-9][0-9]*|)([%a-zA-Z])!u",
                       $format, 2, PREG_SPLIT_DELIM_CAPTURE) ;

        $newformat .= mb_convert_encoding($pre, $encoding, 'UTF-8');
        
        if ($type == '') {
          // didn't match. do nothing. this is the last iteration.
        }
        elseif ($type == '%') {
          // an escaped %
          $newformat .= '%%';
        }
        elseif ($type == 's') {
          $arg = array_shift($argv);
          $arg = mb_convert_encoding($arg, 'UTF-8', $encoding);
          $padding_pre = '';
          $padding_post = '';
          
          // truncate $arg
          if ($precision !== '') {
            $precision = intval(substr($precision,1));
            if ($precision > 0 && mb_strlen($arg,$encoding) > $precision)
              $arg = mb_substr($precision,0,$precision,$encoding);
          }
          
          // define padding
          if ($size > 0) {
            $arglen = mb_strlen($arg, $encoding);
            if ($arglen < $size) {
              if($filler==='')
                  $filler = ' ';
              if ($align == '-')
                  $padding_post = str_repeat($filler, $size - $arglen);
              else
                  $padding_pre = str_repeat($filler, $size - $arglen);
            }
          }
          
          // escape % and pass it forward
          $newformat .= $padding_pre . str_replace('%', '%%', $arg) . $padding_post;
        }
        else {
          // another type, pass forward
          $newformat .= "%$sign$filler$align$size$precision$type";
          $newargv[] = array_shift($argv);
        }
        $format = strval($post);
      }
      // Convert new format back from UTF-8 to the original encoding
      $newformat = mb_convert_encoding($newformat, $encoding, 'UTF-8');
      return vsprintf($newformat, $newargv);
  }
}
?>
up
11
krzysiek dot 333 at gmail dot com - zryty dot hekko dot pl
15 years ago
Encoding and decoding IP adress to format: 1A2B3C4D (mysql column: char(8) )

<?php
function encode_ip($dotquad_ip)
{
    $ip_sep = explode('.', $dotquad_ip);
    return sprintf('%02x%02x%02x%02x', $ip_sep[0], $ip_sep[1], $ip_sep[2], $ip_sep[3]);
}

function decode_ip($int_ip)
{
    $hexipbang = explode('.', chunk_split($int_ip, 2, '.'));
    return hexdec($hexipbang[0]). '.' . hexdec($hexipbang[1]) . '.' . hexdec($hexipbang[2]) . '.' . hexdec($hexipbang[3]);
}
?>
up
12
nate at frickenate dot com
16 years ago
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));
}

?>
up
11
no dot email dot address at example dot com
24 years ago
Using argument swapping in sprintf() with gettext: Let's say you've written the following script:

<?php
$var = sprintf(gettext("The %2\$s contains %1\$d monkeys"), 2, "cage");
?>

Now you run xgettext in order to generate a .po file. The .po file will then look like this:

#: file.php:9
#, ycp-format
msgid "The %2\\$s contains %1\\$d monkeys"
msgstr ""

Notice how an extra backslash has been added by xgettext.

Once you've translated the string, you must remove all backslashes from the ID string as well as the translation, so the po file will look like this:

#: file.php:9
#, ycp-format
msgid "The %2$s contains %1$d monkeys"
msgstr "Der er %1$d aber i %2$s"

Now run msgfmt to generate the .mo file, restart Apache to remove the gettext cache if necessary, and you're off.
up
10
dwieeb at gmail dot com
16 years ago
If you use the default padding specifier (a space) and then print it to HTML, you will notice that HTML does not display the multiple spaces correctly. This is because any sequence of white-space is treated as a single space.

To overcome this, I wrote a simple function that replaces all the spaces in the string returned by sprintf() with the character entity reference "&nbsp;" to achieve non-breaking space in strings returned by sprintf()

<?php
//Here is the function:
function sprintf_nbsp() {
   $args = func_get_args();
   return str_replace(' ', '&nbsp;', vsprintf(array_shift($args), array_values($args)));
}

//Usage (exactly like sprintf):
$format = 'The %d monkeys are attacking the [%10s]!';
$str = sprintf_nbsp($format, 15, 'zoo');
echo $str;
?>

The above example will output:
The 15 monkeys are attacking the [       zoo]!

<?php
//The variation that prints the string instead of returning it:
function printf_nbsp() {
   $args = func_get_args();
   echo str_replace(' ', '&nbsp;', vsprintf(array_shift($args), array_values($args)));
}
?>
up
10
jfgrissom at gmail dot com
17 years ago
I had a nightmare trying to find the two's complement of a 32 bit number.

I got this from http://www.webmasterworld.com/forum88/13334.htm (credit where credit is due... =P  )

Quote: ...find out the 2's complement of any number, which is -(pow(2, n) - N) where n is the number of bits and N is the number for which to find out its 2's complement.

This worked magic for me... previously I was trying to use

sprintf ("%b",$32BitDecimal);
But it always returned 10000000000000000000000 when the $32BitDecimal value got above 2,000,000,000.

This -(pow(2, n) - N)
Worked remarkably well and was very accurate.

Hope this helps someone fighting with two's complement in PHP.
up
8
splogamurugan at gmail dot com
17 years ago
$format = 'There are %1$d monkeys in the %s and %s ';
printf($format, 100, 'Chennai', 'Bangalore'); 

Expecting to output
"There are 100 monkeys in the Chennai and bangalore"

But, this will output 
"There are 100 monkeys in the 100 and Chennai"

Because, the second and Third specifiers takes 1rst and 2nd arguments. Because it is not assigned with any arguments.