如果你传递一个对象而不是一个数组,PHP 会自动将对象转换为数组,以便你可以在 vprintf 中直接使用它。
<?php
$object = new stdClass();
$object->Property1 = 'Value 1';
$object->Property2 = 'Value 2';
vprintf('%-20s %-20s', $object);
/* 输出结果:
Value 1 Value 2
*/
?>
(PHP 4 >= 4.1.0, PHP 5, PHP 7, PHP 8)
vprintf — 输出格式化的字符串
format
格式字符串由零个或多个指令组成:直接复制到结果的普通字符(不包括 %
)和转换说明符,每个转换说明符都会获取自己的参数。
转换说明符遵循以下原型:%[argnum$][flags][width][.precision]specifier
。
一个整数,后面跟着一个美元符号 $
,用于指定在转换中要处理的第几个参数。
Flag | 描述 |
---|---|
- |
在给定的字段宽度内左对齐;右对齐是默认设置 |
+ |
在正数前面加上加号 + ;默认情况下,只有负数前面加上负号。 |
(空格) |
用空格填充结果。这是默认设置。 |
0 |
仅用零填充数字左侧。对于 s 说明符,这也可以用零填充右侧。 |
' (字符) |
用字符 (char) 填充结果。 |
一个整数,表示此转换应产生的最小字符数,或者 *
。如果使用 *
,则宽度作为在格式化程序之前的一个额外的整数值提供。
一个句点 .
,后面可以选择一个整数或 *
,其含义取决于说明符
e
、E
、f
和 F
说明符:这是小数点后要打印的位数(默认情况下,为 6 位)。
g
、G
、h
和 H
说明符:这是要打印的有效位数的最大值。
s
说明符:它充当截止点,为字符串设置最大字符限制。
注意: 如果指定了句点,但没有明确指定精度值,则假设为 0。如果使用
*
,则精度作为在格式化程序之前的一个额外的整数值提供。
Specifier | 描述 |
---|---|
% |
一个文字百分号字符。不需要参数。 |
b |
参数被视为整数,并作为二进制数呈现。 |
c |
参数被视为整数,并作为具有该 ASCII 的字符呈现。 |
d |
参数被视为整数,并作为(带符号)十进制数呈现。 |
e |
参数被视为科学记数法(例如 1.2e+2)。 |
E |
与 e 说明符类似,但使用大写字母(例如 1.2E+2)。 |
f |
参数被视为浮点数,并作为浮点数呈现(区域感知)。 |
F |
参数被视为浮点数,并作为浮点数呈现(非区域感知)。 |
g |
通用格式。 令 P 等于精度(如果非零),6(如果省略精度),或 1(如果精度为零)。然后,如果带有 E 样式的转换的指数为 X 如果 P > X ≥ −4,则转换采用 f 样式,精度为 P − (X + 1)。否则,转换采用 e 样式,精度为 P − 1。 |
G |
与 g 说明符类似,但使用 E 和 f 。 |
h |
与 g 说明符类似,但使用 F 。从 PHP 8.0.0 开始提供。 |
H |
与 g 说明符类似,但使用 E 和 F 。从 PHP 8.0.0 开始提供。 |
o |
参数被视为整数,并作为八进制数呈现。 |
s |
参数被视为字符串,并作为字符串呈现。 |
u |
参数被视为整数,并作为无符号十进制数呈现。 |
x |
参数被视为整数,并作为十六进制数呈现(使用小写字母)。 |
X |
参数被视为整数,并作为十六进制数呈现(使用大写字母)。 |
c
类型说明符忽略填充和宽度。
尝试将字符串和宽度说明符组合使用,但字符集需要每个字符超过一个字节,可能会导致意外结果。
变量将被强制转换为适合说明符的类型
Type | Specifiers |
---|---|
string | s |
int |
d 、u 、c 、o 、x 、X 、b |
float |
e 、E 、f 、F 、g 、G 、h 、H |
values
返回输出字符串的长度。
从 PHP 8.0.0 开始,如果参数数量为零,则会抛出 ValueError。在 PHP 8.0.0 之前,会发出 E_WARNING
代替。
从 PHP 8.0.0 开始,如果 [width]
小于零或大于 PHP_INT_MAX
,则会抛出 ValueError。在 PHP 8.0.0 之前,会发出 E_WARNING
代替。
从 PHP 8.0.0 开始,如果 [precision]
小于零或大于 PHP_INT_MAX
,则会抛出 ValueError。在 PHP 8.0.0 之前,会发出 E_WARNING
代替。
从 PHP 8.0.0 开始,当提供的参数少于所需参数时,会抛出 ValueError。在 PHP 8.0.0 之前,会返回 false
并发出 E_WARNING
代替。
版本 | 描述 |
---|---|
8.0.0 | 此函数不再在失败时返回 false 。 |
8.0.0 | 如果参数数量为零,则抛出 ValueError;之前此函数会发出 E_WARNING 代替。 |
8.0.0 | 如果 [width] 小于零或大于 PHP_INT_MAX ,则抛出 ValueError;之前此函数会发出 E_WARNING 代替。 |
8.0.0 | 如果 [precision] 小于零或大于 PHP_INT_MAX ,则抛出 ValueError;之前此函数会发出 E_WARNING 代替。 |
8.0.0 | 当提供的参数少于所需参数时,抛出 ValueError;之前此函数会发出 E_WARNING 代替。 |
示例 #1 vprintf(): 零填充整数
<?php
vprintf("%04d-%02d-%02d", explode('-', '1988-8-1'));
?>
上面的示例将输出
1988-08-01
如果你传递一个对象而不是一个数组,PHP 会自动将对象转换为数组,以便你可以在 vprintf 中直接使用它。
<?php
$object = new stdClass();
$object->Property1 = 'Value 1';
$object->Property2 = 'Value 2';
vprintf('%-20s %-20s', $object);
/* 输出结果:
Value 1 Value 2
*/
?>
使用 ... 操作符,vprintf($format, $array) 就相当于 printf($format, ...$array)。
<?php
$string = 'The site runs on PHP '.phpversion();
preg_match('/php ((\d)\.\d\.\d+)/i',$string,$matches);
print_r($matches);
vprintf('Match: %s<br /> Version %s; Major:%d.',$matches);
?>
输出
Array ( [0] => PHP 5.2.5 [1] => 5.2.5 [2] => 5 )
Match: PHP 5.2.5 Version 5.2.5; Major:5.
对于 preg_match
如果提供了 matches,则用搜索结果填充它。$matches[0] 将包含与完整模式匹配的文本,$matches[1] 将包含与第一个捕获的圆括号内的子模式匹配的文本,依此类推。
对于 toolofthesystem at gmail dot com
你不需要在 vprintf() 中使用输出缓冲区,因为你可以使用 vsprintf(),它具有与 vprintf() 相同的功能,只是它返回结果字符串而不是输出它。
我知道你可以使用 %1$s 或 %3$s 来选择第一个或第三个字符串,但你是否可以使用数组名称来选择它们呢?
例如 %'user'$s $'email'$s
我倾向于随着时间的推移向我的数据库添加内容,这可以节省大量重新编码的工作。
另一种显示数组的方式是使用 array_walk()。这在内联 echo/print 中很有用,在这些情况下 foreach 不起作用,例如:
<?php
echo "These errors: ", (unset)array_walk($msgs, function($a) { echo "<p>$a</p>"; } ), "must be corrected.";
?>
根据我的测试,对于文本块,sprintf() 速度很慢。
此外,占位符和实际变量或数据结构列表之间的映射通常会使代码难以阅读。但 printf() 家族得到了广泛的支持,并且具有大量很棒的功能。但是性能是一个冷酷的 mistress!
从易读性、维护性和调试的角度来看,我更喜欢 HEREDOC 和 "...{$variable}..." 方法。
对于包含占位符的 HTML 标记块,速度最快的方法是:
?>
<div> markup etc<?= $variable ?>more markup
<?
我的测试包含了 20 次循环,每次循环迭代 100 万次,使用输出缓冲区,在每次循环中丢弃缓冲区。
计时结果从 <?= $var ?> 方法的平均 2.1 毫秒/百万次迭代到使用 printf() 的 7.6 毫秒/百万次迭代不等。
我也会尝试一些基准测试工具,因为我刚刚自己编写了这些代码,可能会引入偏差,但它们是在负载较低的开发服务器上运行的。
希望这些结果很有趣。
当尝试列出从 MySQL 返回的信息时,这个函数有时会派上用场
function print_sql($query,$printf){
$sql_sql = mysql_query($query);
while($sql = mysql_fetch_row($sql_sql)){
vprintf($printf,$sql);
}
}
不幸的是,当我尝试创建一个参数以将其包含在返回的字符串中时,它似乎绕过了输出缓冲区……要么就是我操作不当。