Skip to content

Commit 4a28267

Browse files
Introduce PHP 8.5 polyfill
1 parent 731f6e1 commit 4a28267

15 files changed

+998
-0
lines changed

composer.json

+2
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
"symfony/polyfill-php82": "self.version",
3434
"symfony/polyfill-php83": "self.version",
3535
"symfony/polyfill-php84": "self.version",
36+
"symfony/polyfill-php85": "self.version",
3637
"symfony/polyfill-iconv": "self.version",
3738
"symfony/polyfill-intl-grapheme": "self.version",
3839
"symfony/polyfill-intl-icu": "self.version",
@@ -62,6 +63,7 @@
6263
"src/Intl/Icu/Resources/stubs",
6364
"src/Intl/MessageFormatter/Resources/stubs",
6465
"src/Intl/Normalizer/Resources/stubs",
66+
"src/Php85/Resources/stubs",
6567
"src/Php84/Resources/stubs",
6668
"src/Php83/Resources/stubs",
6769
"src/Php82/Resources/stubs",
+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
<?php
2+
3+
namespace Symfony\Polyfill\Php85\Exception;
4+
5+
class ParsingException extends \RuntimeException
6+
{
7+
}

src/Php85/LICENSE

+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
Copyright (c) 2024-present Fabien Potencier
2+
3+
Permission is hereby granted, free of charge, to any person obtaining a copy
4+
of this software and associated documentation files (the "Software"), to deal
5+
in the Software without restriction, including without limitation the rights
6+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7+
copies of the Software, and to permit persons to whom the Software is furnished
8+
to do so, subject to the following conditions:
9+
10+
The above copyright notice and this permission notice shall be included in all
11+
copies or substantial portions of the Software.
12+
13+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19+
THE SOFTWARE.

src/Php85/README.md

+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
Symfony Polyfill / Php85
2+
========================
3+
4+
This component provides features added to PHP 8.5 core:
5+
6+
- [RFC3986 and WHATWG compliant URI parsing support](https://wiki.php.net/rfc/url_parsing_api)
7+
8+
More information can be found in the
9+
[main Polyfill README](https://github.com/symfony/polyfill/blob/main/README.md).
10+
11+
License
12+
=======
13+
14+
This library is released under the [MIT license](LICENSE).
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <[email protected]>
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 Uri;
13+
14+
if (\PHP_VERSION_ID < 80500) {
15+
class Rfc3986Uri extends \Symfony\Polyfill\Php85\Uri\Rfc3986Uri
16+
{
17+
}
18+
}

src/Php85/Resources/stubs/Uri/Uri.php

+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <[email protected]>
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 Uri;
13+
14+
use Symfony\Polyfill\Php85 as p;
15+
16+
if (\PHP_VERSION_ID < 80500) {
17+
abstract class Uri extends p\Uri\Uri
18+
{
19+
}
20+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <[email protected]>
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 Uri;
13+
14+
if (\PHP_VERSION_ID < 80500) {
15+
final class WhatWgError extends \Symfony\Polyfill\Php85\Uri\WhatWgError
16+
{
17+
}
18+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <[email protected]>
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 Uri;
13+
14+
if (\PHP_VERSION_ID < 80500) {
15+
class WhatWgUri extends \Symfony\Polyfill\Php85\Uri\WhatWgUri
16+
{
17+
}
18+
}

src/Php85/Uri/Rfc3986Uri.php

+121
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
1+
<?php
2+
3+
namespace Symfony\Polyfill\Php85\Uri;
4+
5+
use Symfony\Polyfill\Php85\Exception\ParsingException;
6+
7+
/**
8+
* @author Alexandre Daubois <[email protected]>
9+
*
10+
* @internal
11+
*/
12+
class Rfc3986Uri extends \Uri\Uri
13+
{
14+
public function __construct(string $uri, ?string $baseUrl = null)
15+
{
16+
if ('' === trim($uri)) {
17+
throw new \ValueError('Argument #1 ($uri) cannot be empty');
18+
}
19+
20+
if (null !== $baseUrl && '' === trim($baseUrl)) {
21+
throw new \ValueError('Argument #2 ($baseUrl) cannot be empty');
22+
}
23+
24+
try {
25+
$this->parse($uri, $baseUrl);
26+
} catch (ParsingException $exception) {
27+
throw new \Error('Argument #1 ($uri) must be a valid URI');
28+
}
29+
30+
$this->initialized = true;
31+
}
32+
33+
private function parse(string $uri, ?string $baseUrl): void
34+
{
35+
if (!preg_match('/^[a-zA-Z][a-zA-Z\d+\-.]*:/', $uri) && null !== $baseUrl) {
36+
// uri is a relative uri and bse url exists
37+
$this->parse(rtrim($baseUrl, '/').'/'.ltrim($uri, '/'), null);
38+
39+
return;
40+
}
41+
42+
if (preg_match('/[^\x20-\x7e]/', $uri)) {
43+
// the string contains non-ascii chars
44+
throw new ParsingException();
45+
}
46+
47+
preg_match(self::URI_GLOBAL_REGEX, $uri, $matches);
48+
if (!$matches || !isset($matches['scheme']) || '' === $matches['scheme']) {
49+
//throw new InvalidUriException($uri);
50+
}
51+
52+
if (preg_match('~'.$matches['scheme'].':/(?!/)~', $uri)) {
53+
//throw new InvalidUriException($uri);
54+
}
55+
56+
if (isset($matches['authority'])) {
57+
if (!str_contains($uri, '://') && '' !== $matches['authority']) {
58+
//throw new InvalidUriException($uri);
59+
}
60+
61+
preg_match(self::URI_AUTHORITY_REGEX, $matches['authority'], $authMatches);
62+
63+
$matches = array_merge($matches, $authMatches);
64+
unset($matches['authority']);
65+
}
66+
67+
$matches = array_filter($matches, function (string $value) { return '' !== $value; });
68+
69+
if (isset($matches['host']) && false === \filter_var($matches['host'], FILTER_VALIDATE_DOMAIN, FILTER_FLAG_HOSTNAME)) {
70+
// the host contains invalid code points
71+
throw new ParsingException();
72+
}
73+
74+
$this->scheme = $matches['scheme'] ?? null;
75+
$this->user = isset($matches['user']) ? rawurldecode($matches['user']) : null;
76+
$this->password = isset($matches['pass']) ? rawurldecode($matches['pass']) : null;
77+
$this->host = $matches['host'] ?? null;
78+
$this->port = $matches['port'] ?? null;
79+
$this->path = isset($matches['path']) ? ltrim($matches['path'], '/') : null;
80+
$this->query = $matches['query'] ?? null;
81+
$this->fragment = $matches['fragment'] ?? null;
82+
}
83+
84+
public function __toString()
85+
{
86+
$uri = '';
87+
88+
if (null !== $this->scheme) {
89+
$uri .= $this->scheme.':';
90+
}
91+
92+
if (null !== $this->host) {
93+
$uri .= '//';
94+
if (null !== $this->user) {
95+
$uri .= rawurlencode($this->user);
96+
if (null !== $this->password) {
97+
$uri .= ':'.rawurlencode($this->password);
98+
}
99+
$uri .= '@';
100+
}
101+
$uri .= $this->host;
102+
if (null !== $this->port) {
103+
$uri .= ':'.$this->port;
104+
}
105+
}
106+
107+
if (null !== $this->path) {
108+
$uri .= '/'.$this->path;
109+
}
110+
111+
if (null !== $this->query) {
112+
$uri .= '?'.$this->query;
113+
}
114+
115+
if (null !== $this->fragment) {
116+
$uri .= '#'.$this->fragment;
117+
}
118+
119+
return $uri;
120+
}
121+
}

0 commit comments

Comments
 (0)