跳到内容

VarDumper 组件

编辑此页

VarDumper 组件提供了从任何 PHP 变量中提取状态的机制。在此基础上,它提供了一个更好的 dump() 函数,您可以用来代替 var_dump

安装

1
$ composer require --dev symfony/var-dumper

注意

如果您在 Symfony 应用程序之外安装此组件,您必须在代码中 require vendor/autoload.php 文件,以启用 Composer 提供的类自动加载机制。阅读本文了解更多详情。

注意

如果在 Symfony 应用程序内部使用,请确保已安装 DebugBundle(或运行 composer require --dev symfony/debug-bundle 安装它)。

dump() 函数

VarDumper 组件创建了一个全局 dump() 函数,您可以用来代替例如 var_dump。通过使用它,您将获得

  • 每个对象和资源类型的专用视图,例如,在 dump 单个代理实体时过滤掉 Doctrine 内部结构,或使用 stream_get_meta_data 获取有关已打开文件的更多信息;
  • 可配置的输出格式:HTML 或彩色命令行输出;
  • 能够 dump 内部引用,无论是软引用(对象或资源)还是硬引用(数组或对象属性上的 =&)。同一对象/数组/资源的重复出现将不再一次又一次地出现。此外,您将能够检查数据的引用结构;
  • 能够在输出缓冲处理程序的上下文中操作。

例如

1
2
3
4
5
6
7
8
9
require __DIR__.'/vendor/autoload.php';

// create a variable, which could be anything!
$someVar = ...;

dump($someVar);

// dump() returns the passed value, so you can dump an object and keep using it
dump($someObject)->someMethod();

默认情况下,输出格式和目标根据您当前的 PHP SAPI 选择

  • 在命令行 (CLI SAPI) 上,输出写入 STDOUT。这对某些人来说可能很令人惊讶,因为这绕过了 PHP 的输出缓冲机制;
  • 在其他 SAPI 上,dumps 以 HTML 格式写入常规输出中。

提示

您还可以通过显式定义 VAR_DUMPER_FORMAT 环境变量并将其值设置为 htmlcliserver 来显式选择输出格式。

注意

如果您想将 dump 输出捕获为字符串,请阅读高级部分,其中包含示例。您还将学习如何更改格式或将输出重定向到您想要的任何位置。

提示

为了使 dump() 函数在运行任何 PHP 代码时始终可用,您可以在您的计算机上全局安装它

  1. 运行 composer global require symfony/var-dumper
  2. auto_prepend_file = ${HOME}/.composer/vendor/autoload.php 添加到您的 php.ini 文件中;
  3. 不时运行 composer global update symfony/var-dumper 以获得最新的错误修复。

提示

VarDumper 组件还提供了一个 dd() (“dump and die”) 辅助函数。此函数使用 dump() dump 变量,并立即结束脚本的执行(使用 exit)。

Dump Server

dump() 函数将其内容输出到与您的应用程序相同的浏览器窗口或控制台终端中。有时将真实输出与调试输出混合可能会令人困惑。这就是为什么此组件提供了一个服务器来收集所有 dump 的数据。

使用 server:dump 命令启动服务器,无论何时您调用 dump(),dump 的数据都不会显示在输出中,而是发送到该服务器,服务器将其输出到自己的控制台或 HTML 文件

1
2
3
4
5
6
# displays the dumped data in the console:
$ php bin/console server:dump
  [OK] Server listening on tcp://0.0.0.0:9912

# stores the dumped data in a file using the HTML format:
$ php bin/console server:dump --format=html > dump.html

在 Symfony 应用程序内部,dump server 的输出使用 debug 包的 dump_destination 选项配置

1
2
3
# config/packages/debug.yaml
debug:
   dump_destination: "tcp://%env(VAR_DUMPER_SERVER)%"

在 Symfony 应用程序之外,使用 ServerDumper

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
require __DIR__.'/vendor/autoload.php';

use Symfony\Component\VarDumper\Cloner\VarCloner;
use Symfony\Component\VarDumper\Dumper\CliDumper;
use Symfony\Component\VarDumper\Dumper\ContextProvider\CliContextProvider;
use Symfony\Component\VarDumper\Dumper\ContextProvider\SourceContextProvider;
use Symfony\Component\VarDumper\Dumper\HtmlDumper;
use Symfony\Component\VarDumper\Dumper\ServerDumper;
use Symfony\Component\VarDumper\VarDumper;

$cloner = new VarCloner();
$fallbackDumper = \in_array(\PHP_SAPI, ['cli', 'phpdbg']) ? new CliDumper() : new HtmlDumper();
$dumper = new ServerDumper('tcp://127.0.0.1:9912', $fallbackDumper, [
    'cli' => new CliContextProvider(),
    'source' => new SourceContextProvider(),
]);

VarDumper::setHandler(function (mixed $var) use ($cloner, $dumper): ?string {
    return $dumper->dump($cloner->cloneVar($var));
});

注意

ServerDumper 的第二个参数是 DataDumperInterface 实例,当服务器不可达时用作回退。第三个参数是上下文提供程序,它允许收集有关数据被 dump 的上下文的一些信息。内置的上下文提供程序有:clirequestsource

然后您可以使用以下命令启动开箱即用的服务器

1
2
$ ./vendor/bin/var-dump-server
  [OK] Server listening on tcp://127.0.0.1:9912

使用环境变量配置 Dump Server

如果您不想修改应用程序配置(例如,快速调试给您的项目),请使用 VAR_DUMPER_FORMAT 环境变量。

首先,像往常一样启动服务器

1
$ ./vendor/bin/var-dump-server

然后,通过在应用程序的 .env 文件中配置此值,使用 VAR_DUMPER_FORMAT=server 环境变量运行您的代码。对于控制台命令,您也可以如下定义此环境变量

1
$ VAR_DUMPER_FORMAT=server [your-cli-command]

注意

server 格式使用的主机是在 VAR_DUMPER_SERVER 环境变量中配置的主机,如果没有定义,则使用 127.0.0.1:9912。如果您愿意,您也可以在 VAR_DUMPER_FORMAT 环境变量中配置主机,如下所示:VAR_DUMPER_FORMAT=tcp://127.0.0.1:1234

DebugBundle 和 Twig 集成

DebugBundle 允许将此组件更好地集成到 Symfony 应用程序中。

由于在应用程序的控制器或模型中生成(即使是调试)输出可能会破坏它,例如,发送 HTTP 标头或损坏您的视图,因此 bundle 配置了 dump() 函数,以便变量 dump 在 Web 调试工具栏中。

但是,如果工具栏无法显示,因为例如您调用了 die()/exit()/dd() 或发生致命错误,则 dumps 将写入常规输出中。

在 Twig 模板中,有两个构造可用于 dump 变量。两者之间的选择主要是个人品味问题,仍然

  • {% dump foo.bar %} 是在不应修改原始模板输出时使用的方式:变量不会内联 dump,而是在 Web 调试工具栏中;
  • 相反,{{ dump(foo.bar) }} 会内联 dump,因此可能适合或不适合您的用例(例如,您不应在 HTML 属性或 <script> 标签中使用它)。

可以通过配置 debug.dump_destination 选项来更改此行为。在 DebugBundle 配置参考中阅读有关此选项和其他选项的更多信息。

提示

如果 dump 的内容很复杂,请考虑使用本地搜索框来查找特定的变量或值。首先,单击 dump 内容的任意位置,然后按 Ctrl + FCmd + F 以使本地搜索框出现。支持所有用于导航搜索结果的常用快捷键(Ctrl + GCmd + GF3 等)。完成后,按 Esc 再次隐藏该框。

如果您想使用浏览器搜索输入,请在关注 VarDumper 的搜索输入时再次按 Ctrl + FCmd + F

在 PHPUnit 测试套件中使用 VarDumper 组件

VarDumper 组件提供了一个 trait,可以帮助为 PHPUnit 编写一些测试。

这将为您提供两个新的断言

assertDumpEquals()
验证作为第二个参数给出的变量的 dump 是否与作为第一个参数提供的预期 dump 匹配。
assertDumpMatchesFormat()
类似于上一个方法,但接受预期 dump 中的占位符,基于 PHPUnit 提供的 assertStringMatchesFormat() 方法。

VarDumperTestTrait 还包括以下其他方法

setUpVarDumper()
用于配置可用的 caster 及其选项,这是一种仅控制您期望的字段并允许编写简洁测试的方法。
tearDownVarDumper()
在每种情况下自动调用,以重置在 setUpVarDumper() 中进行的自定义配置。

示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
use PHPUnit\Framework\TestCase;
use Symfony\Component\VarDumper\Test\VarDumperTestTrait;

class ExampleTest extends TestCase
{
    use VarDumperTestTrait;

    protected function setUp(): void
    {
        $casters = [
            \DateTimeInterface::class => static function (\DateTimeInterface $date, array $a, Stub $stub): array {
                $stub->class = 'DateTime';
                return ['date' => $date->format('d/m/Y')];
            },
        ];

        $flags = CliDumper::DUMP_LIGHT_ARRAY | CliDumper::DUMP_COMMA_SEPARATOR;

        // this configures the casters & flags to use for all the tests in this class.
        // If you need custom configurations per test rather than for the whole class,
        // call this setUpVarDumper() method from those tests instead.
        $this->setUpVarDumper($casters, $flags);
    }

    public function testWithDumpEquals(): void
    {
        $testedVar = [123, 'foo'];

        // the expected dump contents don't have the default VarDumper structure
        // because of the custom casters and flags used in the test
        $expectedDump = <<<EOTXT
[
  123,
  "foo",
]
EOTXT;

        // if the first argument is a string, it must be the whole expected dump
        $this->assertDumpEquals($expectedDump, $testedVar);

        // if the first argument is not a string, assertDumpEquals() dumps it
        // and compares it with the dump of the second argument
        $this->assertDumpEquals($testedVar, $testedVar);
    }
}

Dump 示例和输出

对于简单变量,读取输出应该很简单。以下是一些示例,首先显示在 PHP 中定义的变量,然后显示其 dump 表示形式

1
2
3
4
5
6
7
8
$var = [
    'a simple string' => "in an array of 5 elements",
    'a float' => 1.0,
    'an integer' => 1,
    'a boolean' => true,
    'an empty array' => [],
];
dump($var);
Dump output showing the array with length five and all keys and values.

注意

灰色箭头是用于隐藏/显示嵌套结构的子项的切换按钮。

1
2
3
4
5
6
7
$var = "This is a multi-line string.\n";
$var .= "Hovering a string shows its length.\n";
$var .= "The length of UTF-8 strings is counted in terms of UTF-8 characters.\n";
$var .= "Non-UTF-8 strings length are counted in octet size.\n";
$var .= "Because of this `\xE9` octet (\\xE9),\n";
$var .= "this string is not UTF-8 valid, thus the `b` prefix.\n";
dump($var);
Dump output showing the string on multiple lines in between three quotes.
1
2
3
4
5
6
7
8
9
class PropertyExample
{
    public string $publicProperty = 'The `+` prefix denotes public properties,';
    protected string $protectedProperty = '`#` protected ones and `-` private ones.';
    private string $privateProperty = 'Hovering a property shows a reminder.';
}

$var = new PropertyExample();
dump($var);
Dump output showing the PropertyExample object and all three properties with their values.

注意

#14 是内部对象句柄。它允许比较同一对象的两个连续 dumps。

1
2
3
4
5
6
7
8
class DynamicPropertyExample
{
    public string $declaredProperty = 'This property is declared in the class definition';
}

$var = new DynamicPropertyExample();
$var->undeclaredProperty = 'Runtime added dynamic properties have `"` around their name.';
dump($var);
Dump output showing the DynamicPropertyExample object and both declared and undeclared properties with their values.
1
2
3
4
5
6
7
class ReferenceExample
{
    public string $info = "Circular and sibling references are displayed as `#number`.\nHovering them highlights all instances in the same dump.\n";
}
$var = new ReferenceExample();
$var->aCircularReference = $var;
dump($var);
Dump output showing the "aCircularReference" property value referencing the parent object, instead of showing all properties again.
1
2
3
4
5
6
7
8
$var = new \ErrorException(
    "For some objects, properties have special values\n"
    ."that are best represented as constants, like\n"
    ."`severity` below. Hovering displays the value (`2`).\n",
    0,
    E_WARNING
);
dump($var);
Dump output with the "E_WARNING" constant shown as value of "severity".
1
2
3
4
5
6
7
8
$var = [];
$var[0] = 1;
$var[1] =& $var[0];
$var[1] += 1;
$var[2] = ["Hard references (circular or sibling)"];
$var[3] =& $var[2];
$var[3][] = "are dumped using `&number` prefixes.";
dump($var);
Dump output showing the referenced arrays.
1
2
3
4
5
$var = new \ArrayObject();
$var[] = "Some resources and special objects like the current";
$var[] = "one are sometimes best represented using virtual";
$var[] = "properties that describe their internal state.";
dump($var);
Dump output of the ArrayObject.
1
2
3
4
5
6
7
8
$var = new AcmeController(
    "When a dump goes over its maximum items limit,\n"
    ."or when some special objects are encountered,\n"
    ."children can be replaced by an ellipsis and\n"
    ."optionally followed by a number that says how\n"
    ."many have been removed; `9` in this case.\n"
);
dump($var);
Dump output where the children of the Container object are hidden.
1
2
3
4
5
6
7
8
9
class Foo
{
    // $foo is uninitialized, which is different from being null
    private int|float $foo;
    public ?string $baz = null;
}

$var = new Foo();
dump($var);
Dump output where the uninitialized property is represented by a question mark followed by the type definition.

高级用法

dump() 函数只是一个薄包装器,也是调用 VarDumper::dump() 的更方便方法。您可以通过调用 VarDumper::setHandler($callable) 来更改此函数的行为。dump() 的调用将转发到 $callable

通过添加处理程序,您可以自定义ClonerDumperCaster,如下所述。处理函数的一个简单实现可能如下所示

1
2
3
4
5
6
7
8
9
10
11
use Symfony\Component\VarDumper\Cloner\VarCloner;
use Symfony\Component\VarDumper\Dumper\CliDumper;
use Symfony\Component\VarDumper\Dumper\HtmlDumper;
use Symfony\Component\VarDumper\VarDumper;

VarDumper::setHandler(function (mixed $var): ?string {
    $cloner = new VarCloner();
    $dumper = 'cli' === PHP_SAPI ? new CliDumper() : new HtmlDumper();

    return $dumper->dump($cloner->cloneVar($var));
});

Cloner

Cloner 用于创建任何 PHP 变量的中间表示。它的输出是一个 Data 对象,该对象包装了此表示。

您可以按以下方式创建 Data 对象

1
2
3
4
5
6
7
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->dump($data);

无论克隆的数据结构如何,生成的 Data 对象始终是可序列化的。

Cloner 在创建表示形式时应用限制,以便可以仅表示克隆变量的子集。在调用 cloneVar() 之前,您可以配置这些限制

setMaxItems()
配置将要克隆的超出最小嵌套深度的项目最大数量。项目使用广度优先算法计数,以便较低级别的项目比深度嵌套的项目具有更高的优先级。指定 -1 将删除限制。
setMinDepth()
配置最小树深度,在该深度我们保证克隆所有项目。达到此深度后,将仅克隆 setMaxItems 个项目。默认值为 1,这与旧版本的 Symfony 一致。
setMaxString()
配置在切断过长字符串之前将克隆的最大字符数。指定 -1 将删除限制。

在 dump 之前,您可以使用以下方法进一步限制生成的 Data 对象

withMaxDepth()
限制深度维度中的 dumps。
withMaxItemsPerDepth()
限制每个深度级别的项目数。
withRefHandles()
删除内部对象的句柄以获得更稀疏的输出(对测试很有用)。
seek()
仅选择已克隆数组、对象或资源的子部分。

与先前有意删除数据的 cloner 限制不同,这些限制可以在 dump 之前来回更改,因为它们不会在内部影响中间表示。

注意

当未应用限制时,Data 对象与原生 serialize 函数一样准确,因此可以用于调试以外的目的。

Dumper

Dumper 负责输出 PHP 变量的字符串表示形式,使用 Data 对象作为输入。此输出的目标和格式随 dumper 而异。

此组件附带一个用于 HTML 输出的 HtmlDumper 和一个用于可选彩色命令行输出的 CliDumper

例如,如果您想 dump 一些 $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 将写入的输出流。默认情况下,CliDumper 写入 php://stdout,而 HtmlDumper 写入 php://output。但是任何 PHP 流(资源或 URL)都是可以接受的。

除了流目标之外,您还可以传递一个 callable,每次 dumper 生成一行时都会重复调用它。这个 callable 可以使用 dumper 构造函数的第一个参数进行配置,也可以使用 setOutput() 方法或 dump() 方法的第二个参数进行配置。

例如,要将 dump 作为字符串获取到变量中,您可以这样做

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
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 (string $line, int $depth) use (&$output): void {
        // 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

另一种实现相同目的的方法可以是

1
2
3
4
5
6
7
8
9
10
11
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

提示

您可以将 true 传递给 dump() 方法的第二个参数,使其返回作为字符串的 dump

1
$output = $dumper->dump($cloner->cloneVar($variable), true);

Dumpers 实现了 DataDumperInterface 接口,该接口指定了 dump(Data $data) 方法。它们通常也实现了 DumperInterface,这使得它们无需重新实现遍历 Data 对象的内部结构所需的逻辑。

HtmlDumper 默认使用深色主题。使用 setTheme() 方法来使用浅色主题

1
2
// ...
$htmlDumper->setTheme('light');

HtmlDumper 限制了字符串长度和输出的嵌套深度,以使其更具可读性。这些选项可以通过 dump(Data $data) 方法的第三个可选参数进行覆盖

1
2
3
4
5
6
7
8
9
10
use Symfony\Component\VarDumper\Dumper\HtmlDumper;

$output = fopen('php://memory', 'r+b');

$dumper = new HtmlDumper();
$dumper->dump($var, $output, [
    // 1 and 160 are the default values for these options
    'maxDepth' => 1,
    'maxStringLength' => 160,
]);

Dumper 的输出格式可以通过两个标志 DUMP_STRING_LENGTHDUMP_LIGHT_ARRAY 进行微调,这两个标志作为位图在第三个构造函数参数中传递。当在单元测试期间使用 assertDumpEquals($dump, $data, $filter, $message) 时,也可以通过环境变量设置它们。

assertDumpEquals()$filter 参数可以用来传递 Caster::EXCLUDE_* 常量的位字段,并影响不同 caster 生成的预期输出。

如果设置了 DUMP_STRING_LENGTH,则字符串的长度将显示在其内容旁边

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
use Symfony\Component\VarDumper\Cloner\VarCloner;
use Symfony\Component\VarDumper\Dumper\AbstractDumper;
use Symfony\Component\VarDumper\Dumper\CliDumper;

$varCloner = new VarCloner();
$var = ['test'];

$dumper = new CliDumper();
echo $dumper->dump($varCloner->cloneVar($var), true);

// array:1 [
//   0 => "test"
// ]

$dumper = new CliDumper(null, null, AbstractDumper::DUMP_STRING_LENGTH);
echo $dumper->dump($varCloner->cloneVar($var), true);

// (added string length before the string)
// array:1 [
//   0 => (4) "test"
// ]

如果设置了 DUMP_LIGHT_ARRAY,则数组将以类似于 PHP 短数组符号的缩短格式转储

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
use Symfony\Component\VarDumper\Cloner\VarCloner;
use Symfony\Component\VarDumper\Dumper\AbstractDumper;
use Symfony\Component\VarDumper\Dumper\CliDumper;

$varCloner = new VarCloner();
$var = ['test'];

$dumper = new CliDumper();
echo $dumper->dump($varCloner->cloneVar($var), true);

// array:1 [
//   0 => "test"
// ]

$dumper = new CliDumper(null, null, AbstractDumper::DUMP_LIGHT_ARRAY);
echo $dumper->dump($varCloner->cloneVar($var), true);

// (no more array:1 prefix)
// [
//   0 => "test"
// ]

如果您想同时使用这两个选项,则可以使用逻辑 OR 运算符 | 将它们组合起来

1
2
3
4
5
6
7
8
9
10
11
12
13
use Symfony\Component\VarDumper\Cloner\VarCloner;
use Symfony\Component\VarDumper\Dumper\AbstractDumper;
use Symfony\Component\VarDumper\Dumper\CliDumper;

$varCloner = new VarCloner();
$var = ['test'];

$dumper = new CliDumper(null, null, AbstractDumper::DUMP_STRING_LENGTH | AbstractDumper::DUMP_LIGHT_ARRAY);
echo $dumper->dump($varCloner->cloneVar($var), true);

// [
//   0 => (4) "test"
// ]

Caster

PHP 变量中嵌套的对象和资源在中间 Data 表示中被“强制转换”为数组。您可以通过将 Caster 挂钩到此过程中,为每个对象/资源自定义数组表示形式。该组件已经包含了许多用于基本 PHP 类和其他常用类的 casters。

如果您想构建自己的 Caster,您可以在克隆 PHP 变量之前注册一个。Casters 可以使用 Cloner 的构造函数或其 addCasters() 方法注册

1
2
3
4
5
6
7
8
use Symfony\Component\VarDumper\Cloner\VarCloner;

$myCasters = [...];
$cloner = new VarCloner($myCasters);

// or

$cloner->addCasters($myCasters);

提供的 $myCasters 参数是一个数组,它将类、接口或资源类型映射到一个 callable

1
2
3
4
$myCasters = [
    'FooClass' => $myFooClassCallableCaster,
    ':bar resource' => $myBarResourceCallableCaster,
];

您可能会注意到,资源类型以 : 为前缀,以防止与类名冲突。

由于一个对象有一个主类和潜在的许多父类或接口,因此许多 casters 可以应用于一个对象。在这种情况下,casters 会被一个接一个地调用,首先调用绑定到接口的 casters,然后是父类的 casters,最后是主类的 casters。也可以为同一个资源类型/类/接口注册多个 casters。它们按照注册顺序被调用。

Casters 负责返回被克隆对象或资源的属性,以数组形式返回。它们是接受五个参数的 callables

  • 被强制转换的对象或资源;
  • 一个为对象建模的数组,仿照 PHP 的原生 (array) 强制转换运算符;
  • 一个 Stub 对象,表示对象的主要属性(类、类型等);
  • 当 caster 在结构中嵌套调用时为 true,否则为 false;
  • 一个 Caster ::EXCLUDE_* 常量的位字段。

这是一个简单的 caster,什么都不做

1
2
3
4
5
6
7
8
use Symfony\Component\VarDumper\Cloner\Stub;

function myCaster(mixed $object, array $array, Stub $stub, bool $isNested, int $filter): array
{
    // ... populate/alter $array to your needs

    return $array;
}

对于对象,$array 参数预先填充了使用 PHP 原生 (array) 强制转换运算符或 $object->__debugInfo() 的返回值(如果该魔术方法存在)。然后,一个 Caster 的返回值作为数组参数传递给链中的下一个 Caster。

当使用 (array) 运算符进行强制转换时,PHP 会在受保护的属性前加上 \0*\0 前缀,并在私有属性前加上拥有该属性的类名。例如,\0Foobar\0 将是 Foobar 类型对象的所有私有属性的前缀。Casters 遵循此约定并添加两个更多前缀:\0~\0 用于虚拟属性,\0+\0 用于动态属性(运行时添加的、不在类声明中的属性)。

注意

尽管您可以这样做,但建议不要在 Caster 中强制转换对象时更改对象的状态。

提示

在编写自己的 casters 之前,您应该检查现有的 casters。

使用元数据添加语义

由于 casters 挂钩到特定的类或接口,因此它们了解它们操作的对象。通过更改 $stub 对象(任何 caster 的第三个参数),可以将此知识转移到结果 Data 对象,从而转移到 dumpers。为了帮助您做到这一点(请参阅源代码以了解其工作原理),该组件附带了一组用于常见附加语义的包装器。您可以使用

  • ConstStub 来包装最适合用 PHP 常量表示的值;
  • ClassStub 来包装 PHP 标识符( 类名、方法名、接口,等等);
  • CutStub 用省略号替换大的嘈杂对象/字符串/等等
  • CutArrayStub 仅保留数组的一些有用键;
  • ImgStub 来包装图像;
  • EnumStub 来包装一组虚拟值(,在原始 PHP 数据结构中不存在,但值得与实际值一起列出的值);
  • LinkStub 来包装可以被 dumpers 转换为链接的字符串;
  • TraceStub 及其
  • FrameStub
  • ArgsStub 相关项来包装 PHP 跟踪(由 ExceptionCaster 使用)。

例如,如果您知道您的 Product 对象有一个名为 brochure 的属性,该属性保存文件名或 URL,您可以将它们包装在 LinkStub 中,以告诉 HtmlDumper 将它们设为可点击

1
2
3
4
5
6
7
8
9
use Symfony\Component\VarDumper\Caster\LinkStub;
use Symfony\Component\VarDumper\Cloner\Stub;

function ProductCaster(Product $object, array $array, Stub $stub, bool $isNested, int $filter = 0): array
{
    $array['brochure'] = new LinkStub($array['brochure']);

    return $array;
}
这项工作,包括代码示例,已根据 Creative Commons BY-SA 3.0 许可获得许可。
TOC
    版本