[VarDumper] Wrong dumper output for Accept: aplication/json requests

This commit is contained in:
rfcdt
2026-03-12 14:49:05 +02:00
committed by Nicolas Grekas
parent 045321c440
commit a98c17e879
5 changed files with 105 additions and 19 deletions

View File

@@ -0,0 +1,19 @@
--TEST--
Test dd() with "Accept: application/json" uses CliDumper with php://output
--FILE--
<?php
putenv('NO_COLOR=1');
$vendor = __DIR__;
while (!file_exists($vendor.'/vendor')) {
$vendor = \dirname($vendor);
}
require $vendor.'/vendor/autoload.php';
$_SERVER['HTTP_ACCEPT'] = 'application/json';
dd(['foo1', 'foo2']);
--EXPECTF--
array:2 [
0 => "foo1"
1 => "foo2"
]

View File

@@ -0,0 +1,20 @@
--TEST--
Test dump() with "Accept: application/json" uses CliDumper with php://output
--FILE--
<?php
putenv('NO_COLOR=1');
$vendor = __DIR__;
while (!file_exists($vendor.'/vendor')) {
$vendor = \dirname($vendor);
}
require $vendor.'/vendor/autoload.php';
$_SERVER['HTTP_ACCEPT'] = 'application/json';
dump(['foo1', 'foo2']);
--EXPECTF--
array:2 [
0 => "foo1"
1 => "foo2"
]

View File

@@ -0,0 +1,21 @@
--TEST--
Test dump() with "Accept: application/json" uses CliDumper with php://output
--FILE--
<?php
putenv('NO_COLOR=1');
$vendor = __DIR__;
while (!file_exists($vendor.'/vendor')) {
$vendor = \dirname($vendor);
}
require $vendor.'/vendor/autoload.php';
$_SERVER['HTTP_ACCEPT'] = 'application/json';
dump(1, 'foo', ['foo1', 'foo2']);
--EXPECTF--
1 1
2 "foo"
3 array:2 [
0 => "foo1"
1 => "foo2"
]

View File

@@ -0,0 +1,16 @@
--TEST--
Test dump() with "Accept: application/json" uses CliDumper with php://output
--FILE--
<?php
putenv('NO_COLOR=1');
$vendor = __DIR__;
while (!file_exists($vendor.'/vendor')) {
$vendor = \dirname($vendor);
}
require $vendor.'/vendor/autoload.php';
$_SERVER['HTTP_ACCEPT'] = 'application/json';
dump('Test with string');
--EXPECTF--
"Test with string"

View File

@@ -21,6 +21,7 @@ use Symfony\Component\VarDumper\Dumper\ContextProvider\CliContextProvider;
use Symfony\Component\VarDumper\Dumper\ContextProvider\RequestContextProvider;
use Symfony\Component\VarDumper\Dumper\ContextProvider\SourceContextProvider;
use Symfony\Component\VarDumper\Dumper\ContextualizedDumper;
use Symfony\Component\VarDumper\Dumper\DataDumperInterface;
use Symfony\Component\VarDumper\Dumper\HtmlDumper;
use Symfony\Component\VarDumper\Dumper\ServerDumper;
@@ -66,30 +67,21 @@ class VarDumper
$cloner->addCasters(ReflectionCaster::UNSET_CLOSURE_FILE_INFO);
$format = $_SERVER['VAR_DUMPER_FORMAT'] ?? null;
switch (true) {
case 'html' === $format:
$dumper = new HtmlDumper();
break;
case 'cli' === $format:
$dumper = new CliDumper();
break;
case 'server' === $format:
case $format && 'tcp' === parse_url($format, \PHP_URL_SCHEME):
$host = 'server' === $format ? $_SERVER['VAR_DUMPER_SERVER'] ?? '127.0.0.1:9912' : $format;
$accept = $_SERVER['HTTP_ACCEPT'] ?? (\in_array(\PHP_SAPI, ['cli', 'phpdbg', 'embed'], true) ? 'txt' : 'html');
$dumper = str_contains($accept, 'html') || str_contains($accept, '*/*') ? new HtmlDumper() : new CliDumper();
$dumper = new ServerDumper($host, $dumper, self::getDefaultContextProviders());
break;
default:
$accept = $_SERVER['HTTP_ACCEPT'] ?? (\in_array(\PHP_SAPI, ['cli', 'phpdbg', 'embed'], true) ? 'txt' : 'html');
$dumper = str_contains($accept, 'html') || str_contains($accept, '*/*') ? new HtmlDumper() : new CliDumper();
}
$dumper = match ($format) {
'html' => new HtmlDumper(),
'cli' => new CliDumper(),
'server' => self::selectDumperForAccept($_SERVER['VAR_DUMPER_SERVER'] ?? '127.0.0.1:9912'),
default => self::selectDumperForAccept(
$format && 'tcp' === parse_url($format, \PHP_URL_SCHEME) ? $format : null,
),
};
if (!$dumper instanceof ServerDumper) {
$dumper = new ContextualizedDumper($dumper, [new SourceContextProvider()]);
}
self::$handler = function ($var, ?string $label = null) use ($cloner, $dumper) {
self::$handler = static function ($var, ?string $label = null) use ($cloner, $dumper) {
$var = $cloner->cloneVar($var);
if (null !== $label) {
@@ -100,6 +92,24 @@ class VarDumper
};
}
private static function selectDumperForAccept(?string $serverHost): DataDumperInterface
{
$isCliSapi = \in_array(\PHP_SAPI, ['cli', 'phpdbg', 'embed'], true);
$accept = $_SERVER['HTTP_ACCEPT'] ?? ($isCliSapi ? 'txt' : 'html');
$dumper = match (true) {
str_contains($accept, 'html'), str_contains($accept, '*/*') => new HtmlDumper(),
$isCliSapi => new CliDumper(),
default => new CliDumper('php://output'),
};
if (null !== $serverHost) {
$dumper = new ServerDumper($serverHost, $dumper, self::getDefaultContextProviders());
}
return $dumper;
}
private static function getDefaultContextProviders(): array
{
$contextProviders = [];