sprintf() 根据一个格式和一组值拼出一个字符串并返回:格式里的每个 % 占位符依次被下一个值替换。sprintf('%s is %d years old', 'Ada', 36) 返回 "Ada is 36 years old"。printf() 接收同样的参数,但它直接打印结果,而不是返回结果。
占位符按从左到右的顺序依次填入。%.2f 总是显示两位小数(4.50,而不是 4.5),%05d 用零把数字补足到五位。
格式说明符
一个占位符由 %、可选的修饰符和一个表示类型的字母组成:
| 说明符 | 含义 | sprintf(...) | 结果 |
|---|---|---|---|
%s | 字符串 | sprintf('%s', 'PHP') | PHP |
%d | 整数(有符号) | sprintf('%d', 42.9) | 42 |
%f | 浮点数,默认 6 位小数 | sprintf('%f', 1.5) | 1.500000 |
%.2f | 浮点数,2 位小数 | sprintf('%.2f', 1.5) | 1.50 |
%e | 科学计数法 | sprintf('%e', 1234.5678) | 1.234568e+3 |
%x / %X | 十六进制 | sprintf('%x', 255) | ff |
%o | 八进制 | sprintf('%o', 8) | 10 |
%b | 二进制 | sprintf('%b', 5) | 101 |
%c | 由编码得到的字符 | sprintf('%c', 65) | A |
%u | 无符号整数 | sprintf('%u', 3) | 3 |
%% | 百分号本身 | sprintf('%d%%', 50) | 50% |
改一下下面的值,再运行一次:
%d 会把浮点数向零截断,所以 42.9 变成 42。如果想得到 43,先四舍五入:sprintf('%d', round(42.9))。不是数字的字符串(比如 'abc')在 %d 下会变成 0。
用前导零补位
在 % 和字母之间可以放一个填充字符和一个宽度。%05d 的意思是“用 0 补足到 5 位宽”。格式化订单号、发票编号、时间和日期通常就这么写。
宽度是最小值。比宽度更长的数字会完整打印出来。
%05.2f:宽度和小数位一起用
对浮点数来说,宽度计算的是结果的所有字符,包括小数点和负号。所以 %05.2f 作用于 3.14159 得到 03.14:一共五个字符,其中两个在小数点后面。
%f 使用当前区域设置(用 setlocale() 设置)的小数点,而 %F 始终使用点号。如果你的代码设置了区域,而 JSON、CSV 或 API 又需要点号,就用 %F。
按列对齐文本
正数宽度表示右对齐,宽度前加 - 表示左对齐,' 后面跟一个字符可以指定自定义填充字符。把它们组合起来,就能排出整齐的纯文本报表和小票。
%-14s 在商品名右侧补空格到 14 个字符,%8.2f 把价格在 8 个字符内右对齐,%'-27s 配合空字符串打印出一行 27 个短横线。%'*10s 用 * 代替空格填充。
给参数编号,重复使用或调换顺序
%1$s 表示“第一个参数,作为字符串”,%2$d 表示“第二个参数,作为整数”。有了编号占位符,你可以重复使用一个值,或者在不改参数列表的情况下调换顺序。当不同语言的语序不一样时,翻译人员正需要这一点。
vsprintf、printf 和返回值
vsprintf() 以一个数组的形式接收所有值,值本来就放在数组里时很方便。printf() 返回它打印的字节数,vprintf() 是 printf() 的数组版本。
printf() 返回的计数包含换行符,所以 "Hello\n" 是 6 个字节。对于多字节文本,它数的是字节,而不是字符。
参数太少会抛出错误
从 PHP 8 开始,如果格式里的占位符比值多,会抛出 ArgumentCountError,而不是返回 false。遇到这个错误时,数一数 % 占位符的个数(%% 不算)。
错误信息把格式字符串也算作一个参数:ArgumentCountError: 4 arguments are required, 3 given。多余的参数会被悄悄忽略,所以反过来的错误不会报错。如果 sprintf 的结果看起来不对,把格式和值并排打印出来对照。如果你只需要千位分隔符,用 number_format() 比用 sprintf 自己拼要简单。完整的修饰符列表见 php.net。
常见问题
PHP 中怎么给数字加前导零?
用 sprintf('%05d', 42),它返回 "00042"。0 是填充字符,5 是总宽度。对字符串来说,str_pad('42', 5, '0', STR_PAD_LEFT) 得到同样的结果。
怎么用 sprintf 把数字保留 2 位小数?
用 %.2f:sprintf('%.2f', 3.14159) 返回 "3.14",sprintf('%.2f', 5) 返回 "5.00"。再加上宽度还能同时补零:%08.2f 得到 "00003.14"。
PHP 中 printf 和 sprintf 有什么区别?
sprintf() 返回格式化后的字符串,方便你保存起来。printf() 直接把它打印出来,并返回打印的字节数。echo sprintf(...) 和 printf(...) 的输出完全相同。
PHP 中 %s 是什么意思?
%s 是 sprintf() 和 printf() 里字符串的占位符:sprintf('Hello, %s', 'Ada') 返回 "Hello, Ada"。传给 %s 的数字会被转换成字符串。%d 用于整数,%f 用于浮点数。
sprintf 中怎么重复使用同一个参数?
给占位符编号:sprintf('%1$s loves %2$s, and %2$s loves %1$s', 'Ada', 'PHP')。格式字符串要用单引号:在双引号里,PHP 会把 $s 当成变量,于是 "%1$s" 变成 %1 后面跟着 $s 的值。