29
29
30
30
final class Domain implements DomainName
31
31
{
32
- private const REGEXP_IDN_PATTERN = '/[^\x20-\x7f]/ ' ;
33
32
private const IDNA_2003 = 'IDNA_2003 ' ;
34
33
private const IDNA_2008 = 'IDNA_2008 ' ;
34
+ private const REGEXP_IDN_PATTERN = '/[^\x20-\x7f]/ ' ;
35
+
36
+ // Note that unreserved is purposely missing . as it is used to separate labels.
37
+ private const REGEXP_REGISTERED_NAME = '/(?(DEFINE)
38
+ (?<unreserved>[a-z0-9_~\-])
39
+ (?<sub_delims>[!$& \'()*+,;=])
40
+ (?<encoded>%[A-F0-9]{2})
41
+ (?<reg_name>(?:(?&unreserved)|(?&sub_delims)|(?&encoded)){1,63})
42
+ )
43
+ ^(?:(?®_name)\.){0,126}(?®_name)\.?$/ix ' ;
44
+
45
+ private const REGEXP_URI_DELIMITERS = '/[:\/?#\[\]@ ]/ ' ;
35
46
36
47
/**
37
48
* @var array<string>
@@ -45,56 +56,51 @@ final class Domain implements DomainName
45
56
/**
46
57
* @param null|mixed $domain
47
58
*/
48
- private function __construct ($ domain , string $ type )
59
+ private function __construct (string $ type, $ domain )
49
60
{
50
61
$ this ->type = $ type ;
51
- [$ this ->domain , $ this ->labels ] = $ this ->parseDomain ($ domain );
62
+ $ this ->domain = $ this ->parseDomain ($ domain );
63
+ $ this ->labels = null === $ this ->domain ? [] : array_reverse (explode ('. ' , $ this ->domain ));
52
64
}
53
65
54
66
/**
55
67
* @param array{domain:string|null, type:string} $properties
56
68
*/
57
69
public static function __set_state (array $ properties ): self
58
70
{
59
- return new self ($ properties ['domain ' ], $ properties ['type ' ]);
71
+ return new self ($ properties ['type ' ], $ properties ['domain ' ]);
60
72
}
61
73
62
74
/**
63
75
* @param null|mixed $domain
64
76
*/
65
77
public static function fromIDNA2003 ($ domain ): self
66
78
{
67
- return new self ($ domain , self ::IDNA_2003 );
79
+ return new self (self ::IDNA_2003 , $ domain );
68
80
}
69
81
70
82
/**
71
83
* @param null|mixed $domain
72
84
*/
73
85
public static function fromIDNA2008 ($ domain ): self
74
86
{
75
- return new self ($ domain , self ::IDNA_2008 );
87
+ return new self (self ::IDNA_2008 , $ domain );
76
88
}
77
89
78
90
/**
79
91
* @param mixed $domain a domain
80
- *
81
- * @return array{0:string|null, 1:array<string>}
82
92
*/
83
- private function parseDomain ($ domain ): array
93
+ private function parseDomain ($ domain ): ? string
84
94
{
85
95
if ($ domain instanceof DomainNameProvider) {
86
96
$ domain = $ domain ->domain ();
87
97
}
88
98
89
- if (!$ domain instanceof DomainName) {
90
- if ($ domain instanceof Host) {
91
- $ domain = $ domain ->toUnicode ()->value ();
92
- }
93
-
94
- return $ this ->parseValue ($ domain );
99
+ if ($ domain instanceof Host) {
100
+ return $ this ->parseValue ($ domain ->toUnicode ()->value ());
95
101
}
96
102
97
- return $ this ->parseValue ($ domain-> toUnicode ()-> value () );
103
+ return $ this ->parseValue ($ domain );
98
104
}
99
105
100
106
/**
@@ -108,13 +114,11 @@ private function parseDomain($domain): array
108
114
*
109
115
* @throws SyntaxError If the host is not a domain
110
116
* @throws SyntaxError If the domain is not a host
111
- *
112
- * @return array{0:string|null, 1:array<string>}
113
117
*/
114
- private function parseValue ($ domain ): array
118
+ private function parseValue ($ domain ): ? string
115
119
{
116
120
if (null === $ domain ) {
117
- return [ null , []] ;
121
+ return null ;
118
122
}
119
123
120
124
if (is_object ($ domain ) && method_exists ($ domain , '__toString ' )) {
@@ -127,7 +131,7 @@ private function parseValue($domain): array
127
131
128
132
$ domain = (string ) $ domain ;
129
133
if ('' === $ domain ) {
130
- return [ '' , [ '' ]] ;
134
+ return '' ;
131
135
}
132
136
133
137
$ res = filter_var ($ domain , FILTER_VALIDATE_IP , FILTER_FLAG_IPV4 );
@@ -136,24 +140,12 @@ private function parseValue($domain): array
136
140
}
137
141
138
142
$ formattedDomain = rawurldecode ($ domain );
139
-
140
- // Note that unreserved is purposely missing . as it is used to separate labels.
141
- static $ domainName = '/(?(DEFINE)
142
- (?<unreserved>[a-z0-9_~\-])
143
- (?<sub_delims>[!$& \'()*+,;=])
144
- (?<encoded>%[A-F0-9]{2})
145
- (?<reg_name>(?:(?&unreserved)|(?&sub_delims)|(?&encoded)){1,63})
146
- )
147
- ^(?:(?®_name)\.){0,126}(?®_name)\.?$/ix ' ;
148
- if (1 === preg_match ($ domainName , $ formattedDomain )) {
149
- $ formattedDomain = strtolower ($ formattedDomain );
150
-
151
- return [$ formattedDomain , array_reverse (explode ('. ' , $ formattedDomain ))];
143
+ if (1 === preg_match (self ::REGEXP_REGISTERED_NAME , $ formattedDomain )) {
144
+ return strtolower ($ formattedDomain );
152
145
}
153
146
154
147
// a domain name can not contains URI delimiters or space
155
- static $ genDelimiters = '/[:\/?#\[\]@ ]/ ' ;
156
- if (1 === preg_match ($ genDelimiters , $ formattedDomain )) {
148
+ if (1 === preg_match (self ::REGEXP_URI_DELIMITERS , $ formattedDomain )) {
157
149
throw SyntaxError::dueToInvalidCharacters ($ domain );
158
150
}
159
151
@@ -162,11 +154,7 @@ private function parseValue($domain): array
162
154
throw SyntaxError::dueToInvalidLength ($ domain );
163
155
}
164
156
165
- $ formattedDomain = $ this ->domainToUnicode ($ this ->domainToAscii ($ formattedDomain ));
166
-
167
- $ labels = array_reverse (explode ('. ' , $ formattedDomain ));
168
-
169
- return [$ formattedDomain , $ labels ];
157
+ return $ this ->domainToUnicode ($ this ->domainToAscii ($ formattedDomain ));
170
158
}
171
159
172
160
private function domainToAscii (string $ domain ): string
@@ -206,7 +194,7 @@ public function isAscii(): bool
206
194
207
195
public function jsonSerialize (): ?string
208
196
{
209
- return $ this ->value () ;
197
+ return $ this ->domain ;
210
198
}
211
199
212
200
public function count (): int
@@ -221,7 +209,7 @@ public function value(): ?string
221
209
222
210
public function toString (): string
223
211
{
224
- return (string ) $ this ->value () ;
212
+ return (string ) $ this ->domain ;
225
213
}
226
214
227
215
public function label (int $ key ): ?string
@@ -264,7 +252,7 @@ public function toAscii(): self
264
252
return $ this ;
265
253
}
266
254
267
- return new self ($ domain , $ this ->type );
255
+ return new self ($ this ->type , $ domain );
268
256
}
269
257
270
258
public function toUnicode (): self
@@ -278,7 +266,7 @@ public function toUnicode(): self
278
266
return $ this ;
279
267
}
280
268
281
- return new self ($ domain , $ this ->type );
269
+ return new self ($ this ->type , $ domain );
282
270
}
283
271
284
272
/**
@@ -330,13 +318,13 @@ public function append($label): self
330
318
331
319
public function withLabel (int $ key , $ label ): self
332
320
{
333
- $ nb_labels = count ($ this ->labels );
334
- if ($ key < - $ nb_labels - 1 || $ key > $ nb_labels ) {
321
+ $ nbLabels = count ($ this ->labels );
322
+ if ($ key < - $ nbLabels - 1 || $ key > $ nbLabels ) {
335
323
throw SyntaxError::dueToInvalidLabelKey ($ this , $ key );
336
324
}
337
325
338
326
if (0 > $ key ) {
339
- $ key = $ nb_labels + $ key ;
327
+ $ key = $ nbLabels + $ key ;
340
328
}
341
329
342
330
$ label = $ this ->normalize ($ label );
@@ -349,28 +337,28 @@ public function withLabel(int $key, $label): self
349
337
$ labels [$ key ] = $ label ;
350
338
ksort ($ labels );
351
339
352
- return new self (implode ('. ' , array_reverse ($ labels )), $ this -> type );
340
+ return new self ($ this -> type , implode ('. ' , array_reverse ($ labels )));
353
341
}
354
342
355
343
public function withoutLabel (int $ key , int ...$ keys ): self
356
344
{
357
345
array_unshift ($ keys , $ key );
358
- $ nb_labels = count ($ this ->labels );
346
+ $ nbLabels = count ($ this ->labels );
359
347
foreach ($ keys as &$ offset ) {
360
- if (- $ nb_labels > $ offset || $ nb_labels - 1 < $ offset ) {
348
+ if (- $ nbLabels > $ offset || $ nbLabels - 1 < $ offset ) {
361
349
throw SyntaxError::dueToInvalidLabelKey ($ this , $ key );
362
350
}
363
351
364
352
if (0 > $ offset ) {
365
- $ offset += $ nb_labels ;
353
+ $ offset += $ nbLabels ;
366
354
}
367
355
}
368
356
unset($ offset );
369
357
370
- $ deleted_keys = array_keys (array_count_values ($ keys ));
358
+ $ deletedKeys = array_keys (array_count_values ($ keys ));
371
359
$ labels = [];
372
360
foreach ($ this ->labels as $ offset => $ label ) {
373
- if (!in_array ($ offset , $ deleted_keys , true )) {
361
+ if (!in_array ($ offset , $ deletedKeys , true )) {
374
362
$ labels [] = $ label ;
375
363
}
376
364
}
@@ -388,13 +376,13 @@ public function clear(): self
388
376
return $ this ;
389
377
}
390
378
391
- return new self (null , $ this ->type );
379
+ return new self ($ this ->type , null );
392
380
}
393
381
394
382
public function slice (int $ offset , int $ length = null ): self
395
383
{
396
- $ nb_labels = count ($ this ->labels );
397
- if ($ offset < - $ nb_labels || $ offset > $ nb_labels ) {
384
+ $ nbLabels = count ($ this ->labels );
385
+ if ($ offset < - $ nbLabels || $ offset > $ nbLabels ) {
398
386
throw SyntaxError::dueToInvalidLabelKey ($ this , $ offset );
399
387
}
400
388
0 commit comments