Skip to content

Commit baf98b9

Browse files
feature #58989 [VarDumper] Add caster for AddressInfo objects (nicolas-grekas)
This PR was merged into the 7.3 branch. Discussion ---------- [VarDumper] Add caster for `AddressInfo` objects | Q | A | ------------- | --- | Branch? | 7.3 | Bug fix? | no | New feature? | yes | Deprecations? | no | Issues | - | License | MIT ![image](https://github.com/user-attachments/assets/d596aba6-aba7-4673-bf79-6314f215f324) Commits ------- 9d85c55 [VarDumper] Add caster for AddressInfo objects
2 parents 136bde3 + 9d85c55 commit baf98b9

File tree

4 files changed

+136
-0
lines changed

4 files changed

+136
-0
lines changed
Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Component\VarDumper\Caster;
13+
14+
use Symfony\Component\VarDumper\Cloner\Stub;
15+
16+
/**
17+
* @author Nicolas Grekas <p@tchwork.com>
18+
*/
19+
final class AddressInfoCaster
20+
{
21+
private const MAPS = [
22+
'ai_flags' => [
23+
1 => 'AI_PASSIVE',
24+
2 => 'AI_CANONNAME',
25+
4 => 'AI_NUMERICHOST',
26+
8 => 'AI_V4MAPPED',
27+
16 => 'AI_ALL',
28+
32 => 'AI_ADDRCONFIG',
29+
64 => 'AI_IDN',
30+
128 => 'AI_CANONIDN',
31+
1024 => 'AI_NUMERICSERV',
32+
],
33+
'ai_family' => [
34+
1 => 'AF_UNIX',
35+
2 => 'AF_INET',
36+
10 => 'AF_INET6',
37+
44 => 'AF_DIVERT',
38+
],
39+
'ai_socktype' => [
40+
1 => 'SOCK_STREAM',
41+
2 => 'SOCK_DGRAM',
42+
3 => 'SOCK_RAW',
43+
4 => 'SOCK_RDM',
44+
5 => 'SOCK_SEQPACKET',
45+
],
46+
'ai_protocol' => [
47+
1 => 'SOL_SOCKET',
48+
6 => 'SOL_TCP',
49+
17 => 'SOL_UDP',
50+
136 => 'SOL_UDPLITE',
51+
],
52+
];
53+
54+
public static function castAddressInfo(\AddressInfo $h, array $a, Stub $stub, bool $isNested): array
55+
{
56+
static $resolvedMaps;
57+
58+
if (!$resolvedMaps) {
59+
foreach (self::MAPS as $k => $map) {
60+
foreach ($map as $v => $name) {
61+
if (\defined($name)) {
62+
$resolvedMaps[$k][\constant($name)] = $name;
63+
} elseif (!isset($resolvedMaps[$k][$v])) {
64+
$resolvedMaps[$k][$v] = $name;
65+
}
66+
}
67+
}
68+
}
69+
70+
foreach (socket_addrinfo_explain($h) as $k => $v) {
71+
$a[Caster::PREFIX_VIRTUAL.$k] = match (true) {
72+
'ai_flags' === $k => ConstStub::fromBitfield($v, $resolvedMaps[$k]),
73+
isset($resolvedMaps[$k][$v]) => new ConstStub($resolvedMaps[$k][$v], $v),
74+
default => $v,
75+
};
76+
}
77+
78+
return $a;
79+
}
80+
}

src/Symfony/Component/VarDumper/Caster/ConstStub.php

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,4 +30,23 @@ public function __toString(): string
3030
{
3131
return (string) $this->value;
3232
}
33+
34+
/**
35+
* @param array<int, string> $values
36+
*/
37+
public static function fromBitfield(int $value, array $values): self
38+
{
39+
$names = [];
40+
foreach ($values as $v => $name) {
41+
if ($value & $v) {
42+
$names[] = $name;
43+
}
44+
}
45+
46+
if (!$names) {
47+
$names[] = $values[0] ?? 0;
48+
}
49+
50+
return new self(implode(' | ', $names), $value);
51+
}
3352
}

src/Symfony/Component/VarDumper/Cloner/AbstractCloner.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@ abstract class AbstractCloner implements ClonerInterface
2424
public static array $defaultCasters = [
2525
'__PHP_Incomplete_Class' => ['Symfony\Component\VarDumper\Caster\Caster', 'castPhpIncompleteClass'],
2626

27+
'AddressInfo' => ['Symfony\Component\VarDumper\Caster\AddressInfoCaster', 'castAddressInfo'],
28+
2729
'Symfony\Component\VarDumper\Caster\CutStub' => ['Symfony\Component\VarDumper\Caster\StubCaster', 'castStub'],
2830
'Symfony\Component\VarDumper\Caster\CutArrayStub' => ['Symfony\Component\VarDumper\Caster\StubCaster', 'castCutArray'],
2931
'Symfony\Component\VarDumper\Caster\ConstStub' => ['Symfony\Component\VarDumper\Caster\StubCaster', 'castStub'],
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Component\VarDumper\Tests\Caster;
13+
14+
use PHPUnit\Framework\TestCase;
15+
use Symfony\Component\VarDumper\Test\VarDumperTestTrait;
16+
17+
/**
18+
* @requires extension sockets
19+
*/
20+
class AddressInfoCasterTest extends TestCase
21+
{
22+
use VarDumperTestTrait;
23+
24+
public function testCaster()
25+
{
26+
$xDump = <<<EODUMP
27+
AddressInfo {
28+
ai_flags: 0
29+
ai_family: AF_INET%A
30+
}
31+
EODUMP;
32+
33+
$this->assertDumpMatchesFormat($xDump, socket_addrinfo_lookup('localhost')[0]);
34+
}
35+
}

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy