支付宝扫一扫付款
微信扫一扫付款
(微信为保护隐私,不显示你的昵称)
dump()
函数只是一个轻量化的打包儿器,以及一个调用VarDumper::dump()
的更方便的方式。你可以通过VarDumper::setHandler($callable)
来改变此函数的行为。调用dump()
之后就会被转发给callable
。
通过添加一个handler,你可以自定义Cloners、Dumpers以及Casters,就像下面解释的那样。一个handler函数的简单实现,可能看起来像下面这样:
1 2 3 4 5 6 7 8 9 10 11 | use Symfony\Component\VarDumper\VarDumper;
use Symfony\Component\VarDumper\Cloner\VarCloner;
use Symfony\Component\VarDumper\Dumper\CliDumper;
use Symfony\Component\VarDumper\Dumper\HtmlDumper;
VarDumper::setHandler(function ($var) {
$cloner = new VarCloner();
$dumper = 'cli' === PHP_SAPI ? new CliDumper() : new HtmlDumper();
$dumper->dump($cloner->cloneVar($var));
}); |
Cloner用于创建任意PHP变量的中间层(intermediate representation)。它输出一个Data
对象,以便打包这个层。
你可以按下述方式创建Data
对象:
1 2 3 4 5 6 7 8 | use Symfony\Component\VarDumper\Cloner\VarCloner;
$cloner = new VarCloner();
$data = $cloner->cloneVar($myVar);
// this is commonly then passed to the dumper
// see the example at the top of this page
// 这(数据)通常要传到dumper中,参考前例
// $dumper->dump($data); |
cloner还能在创建表现层时施加限制,以便相应的数据对象能够仅以被克隆变量的子集来呈现。在调用clonerVar()
之前,你应该配置这些限制:
配置即将经过第一个嵌套级别(past the first nesting level)被克隆的元素的最大值。元素被统计时使用的是宽度优先(breadth-first)的算法,以便低级别的元素相对于深层嵌套的元素有更高的优先级(priority)。
在裁切超长字符串之前,配置将被克隆的字符最大值。
两种情况下,指定-1
即代表去除任何限制。
在剥离变量之前,通过下列方法,你可以进一步限制即将成为结果的Data
对象:
在深度上的剥离限制。
在每一层深度上所允许的最大元素数量。
允许移除内部对象对零星输出的处理(对测试有用)。
不像cloner在之前的“以移除数据为目的”的限制,这几个方法可以在剥离之前修改来修改去,因为它们并不对内部的中间层有所影响。
dumper负责生成PHP变量的字符串表现层,使用一个Data
对象作为输入。输出的目标和格式则因dumpers而异。
组件内置了一个用于HTML输出的HtmlDumper
,以及一个用于“可选加亮”的命令行输出的CliDumper
。
例如,若你要剥离一些$variable
变量,只需:
1 2 3 4 5 6 7 | use Symfony\Component\VarDumper\Cloner\VarCloner;
use Symfony\Component\VarDumper\Dumper\CliDumper;
$cloner = new VarCloner();
$dumper = new CliDumper();
$dumper->dump($cloner->cloneVar($variable)); |
使用构造构造器的第一个参数,,你可以选择dump将被写入的输出流(output stream)。默认时,CliDumper
写入php://stdout
,而HtmlDumper
写入php://output
。然而任意PHP stream(resource或URL)都是可接受的。
若不使用流目标(stram desination),你也可传入一个callable
,它将被一个dumper所生成的每一行所重复调用。这个callable(回调)可以通过dumper的构造器的第一个参数来配置,但也可以使用setOutput()
方法,或者是dump()
方法的第二个参数(来配置)。
例如,为了把一个变量剥离成一个字符串,你可以:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | use Symfony\Component\VarDumper\Cloner\VarCloner;
use Symfony\Component\VarDumper\Dumper\CliDumper;
$cloner = new VarCloner();
$dumper = new CliDumper();
$output = '';
$dumper->dump(
$cloner->cloneVar($variable),
function ($line, $depth) use (&$output) {
// A negative depth means "end of dump"
if ($depth >= 0) {
// Adds a two spaces indentation to the line
$output .= str_repeat(' ', $depth).$line."\n";
}
}
);
// $output is now populated with the dump representation of $variable
// $output现在被装入变量$variable的剥离内容 |
做同样事的另一个选择:
1 2 3 4 5 6 7 8 9 10 11 12 | use Symfony\Component\VarDumper\Cloner\VarCloner;
use Symfony\Component\VarDumper\Dumper\CliDumper;
$cloner = new VarCloner();
$dumper = new CliDumper();
$output = fopen('php://memory', 'r+b');
$dumper->dump($cloner->cloneVar($variable), $output);
$output = stream_get_contents($output, -1, 0);
// $output is now populated with the dump representation of $variable
// $output现在被装入变量$variable的剥离内容 |
Dumpers实现的是DataDumperInterface
接口,具体化了dump(Data $data)
方法。它们也可以去实现DumperInterface
接口,该接口把它们(dumpers)从遍历一个Data
对象内部结构所需的逻辑中释放出来。
嵌套在PHP变量中的对象和资源(objects and resources)是被“cast(投掷)”到Data
中间层的数组中。通过把“投掷器(caster)”打到进程中,你可以对每一个对象/资源来修改这个数组呈现。本组件内置了很多casters,用于基础PHP类和其他常规类。
如果你需要构建自己的Caster,你要在克隆PHP变量之前注册它。Casters可以使用Cloner的构造器,或是其addCasters()
方法:
1 2 3 4 5 6 7 8 | use Symfony\Component\VarDumper\Cloner\VarCloner;
$myCasters = array(...);
$cloner = new VarCloner($myCasters);
// or 或
$cloner->addCasters($myCasters); |
提供的$myCasters
参数是一个数组,映射的是一个类、一个接口或一个资源类型(resource type)的回调(callable):
1 2 3 4 | $myCasters = array(
'FooClass' => $myFooClassCallableCaster,
':bar resource' => $myBarResourceCallableCaster,
); |
如你所见,资源类型使用了一个:
前缀,为的是防止类名冲突。
因为一个对象有一个主class,和潜在的许多父类或接口,很多casters可以被应用到一个对象。这时,casters被一个接一个地调用,从绑定了接口、父类然后是主类(main class)的casters开始。几个casters可以被注册到同一资源/类/接口。它们按照注册顺序来调用。
casters负责返回数组方式的被克隆的对象属性或资源。它们是接收四个参数的回调(callables):
被投掷的对象或资源;
跟在PHP原生cast操作符(array)
后面的一个基于对象建模的数组;
一个用于呈现对象(类、types等)的主属性(main properties)Stub
对象;
true/false。caster被调用时是否是嵌套结构?
这里有个简单的caster,它没有做任何事:
1 2 3 4 5 6 | function myCaster($object, $array, $stub, $isNested)
{
// ... populate/alter $array to your needs
// ... 根据你的需求来载入/改变 $array
return $array;
} |
对于对象来说,$array
参数自带了:预加载(pre-populated)时使用的PHP原生(array)
casting操作符,或是当魔术方法存在时$object->__debugInfo()
的返回值。然后,一个Caster的返回值被当做数组参数,给到链路(chain)中的另一个Caster。
当使用(array)
操作符进行casting时,PHP对受保护属性添加了前缀\0*\0
,对private属性则是类所拥有的属性。例如,\0Foobar\0
前缀将添加到type Foobar这个对象的所有私有属性。Casters遵循这个约定,并添加了两个前缀:\0~\0
用于虚拟属性(virtual properties),而\0+\0
用于动态属性(runtime运行时添加的属性,而非类声明里的)
虽然可以,但还是建议你不要在将对象投掷到Caster时,改变该对象的状态。
自己写casters之前,应当参考现有的caster程序。
本文,包括例程代码在内,采用的是 Creative Commons BY-SA 3.0 创作共用授权。