├── LICENSE ├── components ├── Components │ ├── Authority.php │ ├── Component.php │ ├── DataPath.php │ ├── Domain.php │ ├── Fragment.php │ ├── HierarchicalPath.php │ ├── Host.php │ ├── Path.php │ ├── Port.php │ ├── Query.php │ ├── Scheme.php │ ├── URLSearchParams.php │ └── UserInfo.php ├── IPv4Normalizer.php ├── LICENSE ├── Modifier.php ├── UriModifier.php └── composer.json ├── composer.json ├── docs ├── .markdownlint.yml ├── CNAME ├── _config.yml ├── _data │ ├── images.yml │ ├── manifest.yml │ ├── menu.yml │ ├── packages.yml │ └── project.yml ├── _layouts │ ├── default.html │ ├── index.html │ └── redirect.html ├── assets │ ├── fonts │ │ ├── IBM_Plex_Mono │ │ │ ├── IBMPlexMono-Bold.ttf │ │ │ ├── IBMPlexMono-BoldItalic.ttf │ │ │ ├── IBMPlexMono-ExtraLight.ttf │ │ │ ├── IBMPlexMono-ExtraLightItalic.ttf │ │ │ ├── IBMPlexMono-Italic.ttf │ │ │ ├── IBMPlexMono-Light.ttf │ │ │ ├── IBMPlexMono-LightItalic.ttf │ │ │ ├── IBMPlexMono-Medium.ttf │ │ │ ├── IBMPlexMono-MediumItalic.ttf │ │ │ ├── IBMPlexMono-Regular.ttf │ │ │ ├── IBMPlexMono-SemiBold.ttf │ │ │ ├── IBMPlexMono-SemiBoldItalic.ttf │ │ │ ├── IBMPlexMono-Thin.ttf │ │ │ ├── IBMPlexMono-ThinItalic.ttf │ │ │ └── OFL.txt │ │ └── Onest │ │ │ ├── OFL.txt │ │ │ ├── Onest-VariableFont_wght.ttf │ │ │ ├── README.txt │ │ │ └── static │ │ │ ├── Onest-Black.ttf │ │ │ ├── Onest-Bold.ttf │ │ │ ├── Onest-ExtraBold.ttf │ │ │ ├── Onest-ExtraLight.ttf │ │ │ ├── Onest-Light.ttf │ │ │ ├── Onest-Medium.ttf │ │ │ ├── Onest-Regular.ttf │ │ │ ├── Onest-SemiBold.ttf │ │ │ └── Onest-Thin.ttf │ └── img │ │ ├── csv-logo-big.svg │ │ ├── csv-logo.svg │ │ ├── period-logo-big.svg │ │ ├── period-logo.svg │ │ ├── uri-logo-big.svg │ │ └── uri-logo.svg ├── components │ ├── 1.0 │ │ ├── api.md │ │ ├── data-path.md │ │ ├── fragment.md │ │ ├── hierarchical-path.md │ │ ├── host.md │ │ ├── index.md │ │ ├── parsers.md │ │ ├── path.md │ │ ├── port.md │ │ ├── query.md │ │ ├── scheme.md │ │ └── userinfo.md │ ├── 2.0 │ │ ├── api.md │ │ ├── authority.md │ │ ├── data-path.md │ │ ├── domain.md │ │ ├── fragment.md │ │ ├── hierarchical-path.md │ │ ├── host.md │ │ ├── index.md │ │ ├── ipv4-normalizer.md │ │ ├── modifiers │ │ │ ├── host.md │ │ │ ├── index.md │ │ │ ├── path.md │ │ │ └── query.md │ │ ├── path.md │ │ ├── port.md │ │ ├── query-parser-builder.md │ │ ├── query.md │ │ ├── scheme.md │ │ ├── upgrading.md │ │ └── userinfo.md │ └── 7.0 │ │ ├── api.md │ │ ├── authority.md │ │ ├── data-path.md │ │ ├── domain.md │ │ ├── fragment.md │ │ ├── hierarchical-path.md │ │ ├── host.md │ │ ├── index.md │ │ ├── modifiers.md │ │ ├── path.md │ │ ├── port.md │ │ ├── query.md │ │ ├── scheme.md │ │ ├── upgrading.md │ │ ├── urlsearchparams.md │ │ └── userinfo.md ├── custom.css ├── custom.js ├── docker-compose.yml ├── domain-parser │ └── 1.0 │ │ ├── index.md │ │ ├── manager.md │ │ └── rules.md ├── homepage.css ├── index.md ├── input.css ├── interfaces │ ├── 2.0 │ │ └── index.md │ └── 7.0 │ │ ├── contracts.md │ │ ├── encoder.md │ │ ├── idn.md │ │ ├── index.md │ │ ├── ipv4.md │ │ ├── ipv6.md │ │ ├── query-parser-builder.md │ │ └── uri-parser-builder.md ├── manipulations │ └── 1.0 │ │ ├── formatter.md │ │ ├── index.md │ │ ├── middlewares.md │ │ └── references.md ├── parser │ └── 1.0 │ │ └── index.md ├── query-parser │ └── 1.0 │ │ └── index.md ├── releases.md ├── schemes │ └── 1.0 │ │ ├── api.md │ │ ├── extension.md │ │ ├── factory.md │ │ ├── index.md │ │ └── schemes │ │ ├── data.md │ │ ├── file.md │ │ ├── ftp.md │ │ ├── http.md │ │ ├── uri.md │ │ └── ws.md ├── scripts.0002.js ├── styles.0004.css ├── tailwind.config.js └── uri │ ├── 4.0 │ ├── components │ │ ├── datauri-path.md │ │ ├── fragment.md │ │ ├── hierarchical-path.md │ │ ├── host.md │ │ ├── overview.md │ │ ├── pass.md │ │ ├── path.md │ │ ├── port.md │ │ ├── query.md │ │ ├── scheme.md │ │ ├── user.md │ │ └── userinfo.md │ ├── definitions.md │ ├── index.md │ ├── installation.md │ ├── services │ │ ├── formatter.md │ │ ├── parser-query.md │ │ └── parser-uri.md │ └── uri │ │ ├── extension.md │ │ ├── instantiation.md │ │ ├── manipulation.md │ │ ├── manipulation │ │ ├── generic.md │ │ ├── host.md │ │ ├── path.md │ │ └── query.md │ │ ├── properties.md │ │ └── schemes │ │ ├── data-uri.md │ │ ├── ftp.md │ │ ├── http.md │ │ └── ws.md │ ├── 5.0 │ ├── index.md │ └── upgrading.md │ ├── 6.0 │ ├── index.md │ ├── info.md │ ├── parser-builder.md │ ├── psr7.md │ ├── resolver-relativizer.md │ ├── rfc3986.md │ ├── upgrading.md │ └── uri-template.md │ └── 7.0 │ ├── base-uri.md │ ├── index.md │ ├── psr-compliance.md │ ├── rfc3986.md │ ├── upgrading.md │ └── uri-template.md ├── interfaces ├── Contracts │ ├── AuthorityInterface.php │ ├── Conditionable.php │ ├── DataPathInterface.php │ ├── DomainHostInterface.php │ ├── FragmentInterface.php │ ├── HostInterface.php │ ├── IpHostInterface.php │ ├── PathInterface.php │ ├── PortInterface.php │ ├── QueryInterface.php │ ├── SegmentedPathInterface.php │ ├── UriAccess.php │ ├── UriComponentInterface.php │ ├── UriException.php │ ├── UriInspector.php │ ├── UriInterface.php │ ├── UriRenderer.php │ └── UserInfoInterface.php ├── Encoder.php ├── Exceptions │ ├── ConversionFailed.php │ ├── MissingFeature.php │ ├── OffsetOutOfBounds.php │ └── SyntaxError.php ├── FeatureDetection.php ├── IPv4 │ ├── BCMathCalculator.php │ ├── Calculator.php │ ├── Converter.php │ ├── GMPCalculator.php │ └── NativeCalculator.php ├── IPv6 │ └── Converter.php ├── Idna │ ├── Converter.php │ ├── Error.php │ ├── Option.php │ └── Result.php ├── KeyValuePair │ └── Converter.php ├── LICENSE ├── QueryString.php ├── UriString.php └── composer.json ├── test_files ├── hello-world.txt ├── john-doe.vcf └── red-nose.gif └── uri ├── BaseUri.php ├── Http.php ├── HttpFactory.php ├── LICENSE ├── Uri.php ├── UriInfo.php ├── UriResolver.php ├── UriTemplate.php ├── UriTemplate ├── Expression.php ├── Operator.php ├── Template.php ├── TemplateCanNotBeExpanded.php ├── VarSpecifier.php └── VariableBag.php └── composer.json /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 ignace nyamagana butera 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of 6 | this software and associated documentation files (the "Software"), to deal in 7 | the Software without restriction, including without limitation the rights to 8 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 9 | the Software, and to permit persons to whom the Software is furnished to do so, 10 | subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 17 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 18 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 19 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | -------------------------------------------------------------------------------- /components/Components/Component.php: -------------------------------------------------------------------------------- 1 | 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 | declare(strict_types=1); 13 | 14 | namespace League\Uri\Components; 15 | 16 | use League\Uri\Contracts\Conditionable; 17 | use League\Uri\Contracts\UriAccess; 18 | use League\Uri\Contracts\UriComponentInterface; 19 | use League\Uri\Contracts\UriInterface; 20 | use League\Uri\Encoder; 21 | use League\Uri\Exceptions\SyntaxError; 22 | use League\Uri\Uri; 23 | use Psr\Http\Message\UriInterface as Psr7UriInterface; 24 | use Stringable; 25 | use Uri\Rfc3986\Uri as Rfc3986Uri; 26 | 27 | use function is_bool; 28 | use function preg_match; 29 | use function sprintf; 30 | 31 | abstract class Component implements UriComponentInterface, Conditionable 32 | { 33 | protected const REGEXP_INVALID_URI_CHARS = '/[\x00-\x1f\x7f]/'; 34 | 35 | abstract public function value(): ?string; 36 | 37 | public function jsonSerialize(): ?string 38 | { 39 | return $this->value(); 40 | } 41 | 42 | public function toString(): string 43 | { 44 | return $this->value() ?? ''; 45 | } 46 | 47 | public function __toString(): string 48 | { 49 | return $this->toString(); 50 | } 51 | 52 | public function getUriComponent(): string 53 | { 54 | return $this->toString(); 55 | } 56 | 57 | final protected static function filterUri(Rfc3986Uri|Stringable|string $uri): UriInterface|Psr7UriInterface 58 | { 59 | return match (true) { 60 | $uri instanceof UriAccess => $uri->getUri(), 61 | $uri instanceof Psr7UriInterface, $uri instanceof UriInterface => $uri, 62 | default => Uri::new($uri), 63 | }; 64 | } 65 | 66 | /** 67 | * Validate the component content. 68 | */ 69 | protected function validateComponent(Stringable|int|string|null $component): ?string 70 | { 71 | return Encoder::decodeNecessary($component); 72 | } 73 | 74 | /** 75 | * Filter the input component. 76 | * 77 | * @throws SyntaxError If the component cannot be converted to a string or null 78 | */ 79 | final protected static function filterComponent(Stringable|int|string|null $component): ?string 80 | { 81 | return match (true) { 82 | $component instanceof UriComponentInterface => $component->value(), 83 | null === $component => null, 84 | 1 === preg_match(self::REGEXP_INVALID_URI_CHARS, (string) $component) => throw new SyntaxError(sprintf('Invalid component string: %s.', $component)), 85 | default => (string) $component, 86 | }; 87 | } 88 | 89 | final public function when(callable|bool $condition, callable $onSuccess, ?callable $onFail = null): static 90 | { 91 | if (!is_bool($condition)) { 92 | $condition = $condition($this); 93 | } 94 | 95 | return match (true) { 96 | $condition => $onSuccess($this), 97 | null !== $onFail => $onFail($this), 98 | default => $this, 99 | } ?? $this; 100 | } 101 | } 102 | -------------------------------------------------------------------------------- /components/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 ignace nyamagana butera 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of 6 | this software and associated documentation files (the "Software"), to deal in 7 | the Software without restriction, including without limitation the rights to 8 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 9 | the Software, and to permit persons to whom the Software is furnished to do so, 10 | subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 17 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 18 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 19 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | -------------------------------------------------------------------------------- /components/composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "league/uri-components", 3 | "type": "library", 4 | "description" : "URI components manipulation library", 5 | "keywords": [ 6 | "url", 7 | "uri", 8 | "rfc3986", 9 | "components", 10 | "scheme", 11 | "userinfo", 12 | "host", 13 | "port", 14 | "authority", 15 | "path", 16 | "query", 17 | "fragment", 18 | "modifier", 19 | "middleware" 20 | ], 21 | "license": "MIT", 22 | "homepage": "http://uri.thephpleague.com", 23 | "authors": [ 24 | { 25 | "name" : "Ignace Nyamagana Butera", 26 | "email" : "nyamsprod@gmail.com", 27 | "homepage" : "https://nyamsprod.com" 28 | } 29 | ], 30 | "require": { 31 | "php": "^8.1", 32 | "league/uri": "^7.6" 33 | }, 34 | "suggest": { 35 | "ext-bcmath": "to improve IPV4 host parsing", 36 | "ext-mbstring": "to use the sorting algorithm of URLSearchParams", 37 | "ext-fileinfo": "to create Data URI from file contennts", 38 | "ext-gmp": "to improve IPV4 host parsing", 39 | "ext-intl": "to handle IDN host with the best performance", 40 | "jeremykendall/php-domain-parser": "to resolve Public Suffix and Top Level Domain", 41 | "php-64bit": "to improve IPV4 host parsing", 42 | "symfony/polyfill-intl-idn": "to handle IDN host via the Symfony polyfill if ext-intl is not present", 43 | "rowbot/url": "to handle WHATWG URL", 44 | "bakame/aide-uri": "A polyfill for PHP8.1 until PHP8.4 to add support to PHP Native URI parser" 45 | }, 46 | "autoload": { 47 | "psr-4": { 48 | "League\\Uri\\": "" 49 | } 50 | }, 51 | "extra": { 52 | "branch-alias": { 53 | "dev-master": "7.x-dev" 54 | } 55 | }, 56 | "support": { 57 | "forum": "https://thephpleague.slack.com", 58 | "docs": "https://uri.thephpleague.com", 59 | "issues": "https://github.com/thephpleague/uri-src/issues" 60 | }, 61 | "config": { 62 | "sort-packages": true 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /docs/.markdownlint.yml: -------------------------------------------------------------------------------- 1 | default: true 2 | line-length: false 3 | no-inline-html: false # Ignore for fontawesome usage 4 | 5 | single-title: 6 | front_matter_title: '' # Ignore Jekyll titles as headers 7 | heading-style: 8 | style: atx 9 | 10 | ul-style: 11 | style: dash 12 | 13 | code-block-style: 14 | style: fenced 15 | code-fence-style: 16 | style: backtick 17 | 18 | no-hard-tabs: 19 | spaces_per_tab: 4 20 | 21 | no-duplicate-header: 22 | allow_different_nesting: true 23 | -------------------------------------------------------------------------------- /docs/CNAME: -------------------------------------------------------------------------------- 1 | uri.thephpleague.com 2 | -------------------------------------------------------------------------------- /docs/_config.yml: -------------------------------------------------------------------------------- 1 | --- 2 | permalink: pretty 3 | plugins: 4 | - jekyll-redirect-from -------------------------------------------------------------------------------- /docs/_data/images.yml: -------------------------------------------------------------------------------- 1 | # Path to project specific favicon.ico, leave blank to use default 2 | favicon: 3 | 4 | # Path to project specific apple-touch-icon-precomposed.png, leave blank to use default 5 | apple_touch: 6 | 7 | # Path to project logo 8 | logo: -------------------------------------------------------------------------------- /docs/_data/manifest.yml: -------------------------------------------------------------------------------- 1 | { 2 | "docs.css": "/styles.0004.css", 3 | "docs.js": "/scripts.0002.js" 4 | } 5 | -------------------------------------------------------------------------------- /docs/_data/packages.yml: -------------------------------------------------------------------------------- 1 | package: 2 | 'interfaces': 3 | name: 'uri-interfaces' 4 | description: 'The URI utility package' 5 | version: '7.0' 6 | latest: '7.4.1' 7 | status: maintained 8 | documentation: 9 | - '7.0' 10 | - '2.0' 11 | 'uri': 12 | name: 'uri' 13 | description: 'The URI manipulation package' 14 | version: '7.0' 15 | latest: '7.4.1' 16 | status: maintained 17 | documentation: 18 | - '7.0' 19 | - '6.0' 20 | - '5.0' 21 | - '4.0' 22 | 'components': 23 | name: 'uri-components' 24 | description: 'The URI components package' 25 | version: '7.0' 26 | latest: '7.4.1' 27 | status: maintained 28 | documentation: 29 | - '7.0' 30 | - '2.0' 31 | - '1.0' 32 | 'schemes': 33 | name: 'uri-schemes' 34 | description: 'The URI-scheme specific package' 35 | version: '1.0' 36 | latest: '1.2.1' 37 | status: eol 38 | replacedBy: 'https://uri.thephpleague.com/uri/' 39 | documentation: 40 | - '1.0' 41 | 'parser': 42 | name: 'uri-parser' 43 | description: 'The RFC3986 URI parser and builder' 44 | version: '1.0' 45 | latest: '1.4.1' 46 | status: eol 47 | replacedBy: 'https://uri.thephpleague.com/interfaces/' 48 | documentation: 49 | - '1.0' 50 | 'query-parser': 51 | name: 'uri-query-parser' 52 | description: 'Query string parser and builder' 53 | version: '1.0' 54 | latest: '1.0.1' 55 | status: eol 56 | replacedBy: 'https://uri.thephpleague.com/interfaces/' 57 | documentation: 58 | - '1.0' 59 | 'manipulations': 60 | name: 'uri-manipulations' 61 | description: 'Partially update and format URI' 62 | version: '1.0' 63 | latest: '1.5.0' 64 | status: eol 65 | replacedBy: 'https://uri.thephpleague.com/components/' 66 | documentation: 67 | - '1.0' 68 | 'domain-parser': 69 | name: 'uri-hostname-parser' 70 | description: 'Hostname Parser and Resolver' 71 | version: '1.0' 72 | latest: '1.1.1' 73 | status: eol 74 | replacedBy: 'https://github.com/jeremykendall/php-domain-parser' 75 | documentation: 76 | - '1.0' 77 | -------------------------------------------------------------------------------- /docs/_data/project.yml: -------------------------------------------------------------------------------- 1 | # Documentation website 2 | title: "URI" 3 | tagline: "Modern API to process URIs in PHP." 4 | description: "Modern API to process URIs in PHP" 5 | google_analytics_tracking_id: UA-46050814-14 6 | # Github repository 7 | author: 8 | name: 'Ignace Nyamagana Butera' 9 | twitter_account: 'nyamsprod' 10 | mastodon: 11 | url: 'https://phpc.social/@nyamsprod' 12 | account: '@nyamsprod@phpc.social' 13 | github_account: 'nyamsprod' 14 | support: 'Once a new major version is released, the previous stable release remains supported for six more months through patches and security fixes.' 15 | deprecated: 16 | 'schemes': 'https://uri.thephpleague.com/uri/' 17 | 'manipulations': 'https://uri.thephpleague.com/components/' 18 | 'domain-parser': 'https://github.com/jeremykendall/php-domain-parser' 19 | 'parser': 'https://uri.thephpleague.com/interfaces/' 20 | 'query-parser': 'https://uri.thephpleague.com/interfaces/' 21 | -------------------------------------------------------------------------------- /docs/assets/fonts/IBM_Plex_Mono/IBMPlexMono-Bold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thephpleague/uri-src/7081f6d332026d9ffdd453e9acb44342e331c0b1/docs/assets/fonts/IBM_Plex_Mono/IBMPlexMono-Bold.ttf -------------------------------------------------------------------------------- /docs/assets/fonts/IBM_Plex_Mono/IBMPlexMono-BoldItalic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thephpleague/uri-src/7081f6d332026d9ffdd453e9acb44342e331c0b1/docs/assets/fonts/IBM_Plex_Mono/IBMPlexMono-BoldItalic.ttf -------------------------------------------------------------------------------- /docs/assets/fonts/IBM_Plex_Mono/IBMPlexMono-ExtraLight.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thephpleague/uri-src/7081f6d332026d9ffdd453e9acb44342e331c0b1/docs/assets/fonts/IBM_Plex_Mono/IBMPlexMono-ExtraLight.ttf -------------------------------------------------------------------------------- /docs/assets/fonts/IBM_Plex_Mono/IBMPlexMono-ExtraLightItalic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thephpleague/uri-src/7081f6d332026d9ffdd453e9acb44342e331c0b1/docs/assets/fonts/IBM_Plex_Mono/IBMPlexMono-ExtraLightItalic.ttf -------------------------------------------------------------------------------- /docs/assets/fonts/IBM_Plex_Mono/IBMPlexMono-Italic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thephpleague/uri-src/7081f6d332026d9ffdd453e9acb44342e331c0b1/docs/assets/fonts/IBM_Plex_Mono/IBMPlexMono-Italic.ttf -------------------------------------------------------------------------------- /docs/assets/fonts/IBM_Plex_Mono/IBMPlexMono-Light.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thephpleague/uri-src/7081f6d332026d9ffdd453e9acb44342e331c0b1/docs/assets/fonts/IBM_Plex_Mono/IBMPlexMono-Light.ttf -------------------------------------------------------------------------------- /docs/assets/fonts/IBM_Plex_Mono/IBMPlexMono-LightItalic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thephpleague/uri-src/7081f6d332026d9ffdd453e9acb44342e331c0b1/docs/assets/fonts/IBM_Plex_Mono/IBMPlexMono-LightItalic.ttf -------------------------------------------------------------------------------- /docs/assets/fonts/IBM_Plex_Mono/IBMPlexMono-Medium.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thephpleague/uri-src/7081f6d332026d9ffdd453e9acb44342e331c0b1/docs/assets/fonts/IBM_Plex_Mono/IBMPlexMono-Medium.ttf -------------------------------------------------------------------------------- /docs/assets/fonts/IBM_Plex_Mono/IBMPlexMono-MediumItalic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thephpleague/uri-src/7081f6d332026d9ffdd453e9acb44342e331c0b1/docs/assets/fonts/IBM_Plex_Mono/IBMPlexMono-MediumItalic.ttf -------------------------------------------------------------------------------- /docs/assets/fonts/IBM_Plex_Mono/IBMPlexMono-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thephpleague/uri-src/7081f6d332026d9ffdd453e9acb44342e331c0b1/docs/assets/fonts/IBM_Plex_Mono/IBMPlexMono-Regular.ttf -------------------------------------------------------------------------------- /docs/assets/fonts/IBM_Plex_Mono/IBMPlexMono-SemiBold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thephpleague/uri-src/7081f6d332026d9ffdd453e9acb44342e331c0b1/docs/assets/fonts/IBM_Plex_Mono/IBMPlexMono-SemiBold.ttf -------------------------------------------------------------------------------- /docs/assets/fonts/IBM_Plex_Mono/IBMPlexMono-SemiBoldItalic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thephpleague/uri-src/7081f6d332026d9ffdd453e9acb44342e331c0b1/docs/assets/fonts/IBM_Plex_Mono/IBMPlexMono-SemiBoldItalic.ttf -------------------------------------------------------------------------------- /docs/assets/fonts/IBM_Plex_Mono/IBMPlexMono-Thin.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thephpleague/uri-src/7081f6d332026d9ffdd453e9acb44342e331c0b1/docs/assets/fonts/IBM_Plex_Mono/IBMPlexMono-Thin.ttf -------------------------------------------------------------------------------- /docs/assets/fonts/IBM_Plex_Mono/IBMPlexMono-ThinItalic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thephpleague/uri-src/7081f6d332026d9ffdd453e9acb44342e331c0b1/docs/assets/fonts/IBM_Plex_Mono/IBMPlexMono-ThinItalic.ttf -------------------------------------------------------------------------------- /docs/assets/fonts/Onest/Onest-VariableFont_wght.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thephpleague/uri-src/7081f6d332026d9ffdd453e9acb44342e331c0b1/docs/assets/fonts/Onest/Onest-VariableFont_wght.ttf -------------------------------------------------------------------------------- /docs/assets/fonts/Onest/README.txt: -------------------------------------------------------------------------------- 1 | Onest Variable Font 2 | =================== 3 | 4 | This download contains Onest as both a variable font and static fonts. 5 | 6 | Onest is a variable font with this axis: 7 | wght 8 | 9 | This means all the styles are contained in a single file: 10 | Onest-VariableFont_wght.ttf 11 | 12 | If your app fully supports variable fonts, you can now pick intermediate styles 13 | that aren’t available as static fonts. Not all apps support variable fonts, and 14 | in those cases you can use the static font files for Onest: 15 | static/Onest-Thin.ttf 16 | static/Onest-ExtraLight.ttf 17 | static/Onest-Light.ttf 18 | static/Onest-Regular.ttf 19 | static/Onest-Medium.ttf 20 | static/Onest-SemiBold.ttf 21 | static/Onest-Bold.ttf 22 | static/Onest-ExtraBold.ttf 23 | static/Onest-Black.ttf 24 | 25 | Get started 26 | ----------- 27 | 28 | 1. Install the font files you want to use 29 | 30 | 2. Use your app's font picker to view the font family and all the 31 | available styles 32 | 33 | Learn more about variable fonts 34 | ------------------------------- 35 | 36 | https://developers.google.com/web/fundamentals/design-and-ux/typography/variable-fonts 37 | https://variablefonts.typenetwork.com 38 | https://medium.com/variable-fonts 39 | 40 | In desktop apps 41 | 42 | https://theblog.adobe.com/can-variable-fonts-illustrator-cc 43 | https://helpx.adobe.com/nz/photoshop/using/fonts.html#variable_fonts 44 | 45 | Online 46 | 47 | https://developers.google.com/fonts/docs/getting_started 48 | https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Fonts/Variable_Fonts_Guide 49 | https://developer.microsoft.com/en-us/microsoft-edge/testdrive/demos/variable-fonts 50 | 51 | Installing fonts 52 | 53 | MacOS: https://support.apple.com/en-us/HT201749 54 | Linux: https://www.google.com/search?q=how+to+install+a+font+on+gnu%2Blinux 55 | Windows: https://support.microsoft.com/en-us/help/314960/how-to-install-or-remove-a-font-in-windows 56 | 57 | Android Apps 58 | 59 | https://developers.google.com/fonts/docs/android 60 | https://developer.android.com/guide/topics/ui/look-and-feel/downloadable-fonts 61 | 62 | License 63 | ------- 64 | Please read the full license text (OFL.txt) to understand the permissions, 65 | restrictions and requirements for usage, redistribution, and modification. 66 | 67 | You can use them in your products & projects – print or digital, 68 | commercial or otherwise. 69 | 70 | This isn't legal advice, please consider consulting a lawyer and see the full 71 | license for all details. 72 | -------------------------------------------------------------------------------- /docs/assets/fonts/Onest/static/Onest-Black.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thephpleague/uri-src/7081f6d332026d9ffdd453e9acb44342e331c0b1/docs/assets/fonts/Onest/static/Onest-Black.ttf -------------------------------------------------------------------------------- /docs/assets/fonts/Onest/static/Onest-Bold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thephpleague/uri-src/7081f6d332026d9ffdd453e9acb44342e331c0b1/docs/assets/fonts/Onest/static/Onest-Bold.ttf -------------------------------------------------------------------------------- /docs/assets/fonts/Onest/static/Onest-ExtraBold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thephpleague/uri-src/7081f6d332026d9ffdd453e9acb44342e331c0b1/docs/assets/fonts/Onest/static/Onest-ExtraBold.ttf -------------------------------------------------------------------------------- /docs/assets/fonts/Onest/static/Onest-ExtraLight.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thephpleague/uri-src/7081f6d332026d9ffdd453e9acb44342e331c0b1/docs/assets/fonts/Onest/static/Onest-ExtraLight.ttf -------------------------------------------------------------------------------- /docs/assets/fonts/Onest/static/Onest-Light.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thephpleague/uri-src/7081f6d332026d9ffdd453e9acb44342e331c0b1/docs/assets/fonts/Onest/static/Onest-Light.ttf -------------------------------------------------------------------------------- /docs/assets/fonts/Onest/static/Onest-Medium.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thephpleague/uri-src/7081f6d332026d9ffdd453e9acb44342e331c0b1/docs/assets/fonts/Onest/static/Onest-Medium.ttf -------------------------------------------------------------------------------- /docs/assets/fonts/Onest/static/Onest-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thephpleague/uri-src/7081f6d332026d9ffdd453e9acb44342e331c0b1/docs/assets/fonts/Onest/static/Onest-Regular.ttf -------------------------------------------------------------------------------- /docs/assets/fonts/Onest/static/Onest-SemiBold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thephpleague/uri-src/7081f6d332026d9ffdd453e9acb44342e331c0b1/docs/assets/fonts/Onest/static/Onest-SemiBold.ttf -------------------------------------------------------------------------------- /docs/assets/fonts/Onest/static/Onest-Thin.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thephpleague/uri-src/7081f6d332026d9ffdd453e9acb44342e331c0b1/docs/assets/fonts/Onest/static/Onest-Thin.ttf -------------------------------------------------------------------------------- /docs/assets/img/csv-logo-big.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /docs/assets/img/csv-logo.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /docs/assets/img/period-logo-big.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /docs/assets/img/period-logo.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /docs/assets/img/uri-logo-big.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /docs/assets/img/uri-logo.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /docs/components/1.0/fragment.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: default 3 | title: The Fragment component 4 | redirect_from: 5 | - /5.0/components/fragment/ 6 | --- 7 | 8 | # The Fragment component 9 | 10 | The library provides a `Fragment` class to ease fragment creation and manipulation. 11 | 12 | ## Creating a new object 13 | 14 | ~~~php 15 | submitted string is normalized to be RFC3986 compliant.

20 | 21 |

If the submitted value is not valid a League\Uri\Components\Exception exception is thrown.

22 | 23 | The `League\Uri\Components\Exception` extends PHP's SPL `InvalidArgumentException`. 24 | 25 | ## Properties and methods 26 | 27 | This URI component object only exposes the [package common API](/components/1.0/api/). 28 | 29 | ## Usage 30 | 31 | ~~~php 32 | isNull(); //returns false 38 | $fragment->isEmpty(); //return false 39 | echo $fragment->getContent(Fragment::RFC3986_ENCODING); //display '%E2%82%AC' 40 | echo $fragment->getContent(Fragment::RFC3987_ENCODING); //display '€' 41 | echo $fragment->getContent(Fragment::NO_ENCODING); //display '€' 42 | echo $fragment; //display '%E2%82%AC' 43 | echo $fragment->getUriComponent(); //display '#%E2%82%AC' 44 | 45 | $new_fragment = $fragment->getContent(null); 46 | $new_fragment->isNull(); //returns true 47 | $new_fragment->isEmpty(); //return true 48 | echo $new_fragment->getContent(); //display null 49 | echo $new_fragment; //display '' 50 | echo $new_fragment->getUriComponent(); //display '' 51 | 52 | $alt_fragment = $fragment->getContent(''); 53 | $alt_fragment->isNull(); //returns false 54 | $alt_fragment->isEmpty(); //return true 55 | echo $alt_fragment->getContent(); //display '' 56 | echo $alt_fragment; //display '' 57 | echo $alt_fragment->getUriComponent(); //display '#' 58 | ~~~ 59 | 60 |

The delimiter # is not part of the component value and must not be added.

61 | 62 |

If the submitted value is not valid a League\Uri\Components\Exception exception is thrown.

-------------------------------------------------------------------------------- /docs/components/1.0/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: default 3 | title: URI components 4 | --- 5 | 6 | Uri Components 7 | ======= 8 | 9 | [![Build Status](https://img.shields.io/travis/thephpleague/uri/master.svg?style=flat-square)](https://travis-ci.org/thephpleague/uri-components) 10 | [![Latest Version](https://img.shields.io/github/release/thephpleague/uri-components.svg?style=flat-square)](https://github.com/thephpleague/uri-components/releases) 11 | 12 | This package contains concrete URI components object represented as immutable value object as well as function to ease component parsing. 13 | 14 | 15 | List of URI component objects 16 | -------- 17 | 18 | Each URI component object implements the `League\Uri\Components\ComponentInterface` interface. 19 | 20 | All URI components objects are located under the following namespace : `League\Uri\Components` 21 | 22 | 23 | The following URI component objects are defined (order alphabetically): 24 | 25 | - [DataPath](/components/1.0/data-path/) : the Data Path component 26 | - [HierarchicalPath](/components/1.0/hierarchical-path/) : the hierarchical Path component 27 | - [Host](/components/1.0/host/) : the Host component 28 | - [Fragment](/components/1.0/fragment/) : the Fragment component 29 | - [Path](/components/1.0/path/) : the generic Path component 30 | - [Port](/components/1.0/port/) : the Port component 31 | - [Query](/components/1.0/query/) : the Query component 32 | - [Scheme](/components/1.0/scheme/) : the Scheme component 33 | - [UserInfo](/components/1.0/userinfo/) : the User Info component 34 | 35 | System Requirements 36 | ------- 37 | 38 | You need: 39 | 40 | - **PHP >= 7.0** but the latest stable version of PHP is recommended 41 | - the `intl` extension 42 | 43 | Installation 44 | -------- 45 | 46 | ~~~ 47 | $ composer require league/uri-components 48 | ~~~ 49 | 50 | Dependencies 51 | ------- 52 | 53 | Prior to version 1.4.0 54 | 55 | - [PHP Domain Parser](https://github.com/jeremykendall/php-domain-parser) 56 | 57 | Starting with version 1.4.0 58 | 59 | - [Uri Hostname parser](/5.0/publicsuffix/) 60 | 61 | The changes between dependencies was done to support `PHP7.2+` 62 | -------------------------------------------------------------------------------- /docs/components/1.0/port.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: default 3 | title: The Port component 4 | redirect_from: 5 | - /5.0/components/port/ 6 | --- 7 | 8 | # The Port component 9 | 10 | The library provides a `Port` class to ease port manipulation. 11 | 12 | ## Creating a new object 13 | 14 | ~~~php 15 | If the submitted value is not valid a League\Uri\Components\Exception exception is thrown.

20 | 21 | The `League\Uri\Components\Exception` extends PHP's SPL `InvalidArgumentException`. 22 | 23 | ## Properties and methods 24 | 25 | This URI component object only exposes the [package common API](/components/1.0/api/). 26 | 27 | ## Usage 28 | 29 | ~~~php 30 | isNull(); //return false 36 | $port->isEmpty(); //return false 37 | $port->getContent(); //return (int) 443 38 | $port->getContent(Port::RFC3986_ENCODING); //return (int) 443 39 | $port->getContent(Port::RFC3987_ENCODING); //return (int) 443 40 | $port->getContent(Port::NO_ENCODING); //return (int) 443 41 | echo $port; //display '443' 42 | echo $port->getUriComponent(); //display ':443' 43 | 44 | $new_port = $port->withContent(null); 45 | $new_port->isNull(); //return true 46 | $new_port->isEmpty(); //return true 47 | $new_port->getContent(); //return null 48 | echo $new_port; //display '' 49 | echo $new_port->getUriComponent(); //display '' 50 | ~~~ 51 | 52 |

The delimiter : is not part of the component value and must not be added.

53 | 54 |

If the submitted value is not valid a League\Uri\Components\Exception exception is thrown.

55 | -------------------------------------------------------------------------------- /docs/components/1.0/scheme.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: default 3 | title: The Scheme component 4 | redirect_from: 5 | - /5.0/components/scheme/ 6 | --- 7 | 8 | # The Scheme component 9 | 10 | The library provides a `Scheme` class to ease scheme creation and manipulation. 11 | 12 | ## Creating a new object 13 | 14 | ~~~php 15 | If the submitted value is not valid a League\Uri\Components\Exception exception is thrown.

20 | 21 | The `League\Uri\Components\Exception` extends PHP's SPL `InvalidArgumentException`. 22 | 23 | ## Properties and methods 24 | 25 | This URI component object only exposes the [package common API](/components/1.0/api/). 26 | 27 | ## Usage 28 | 29 | ~~~php 30 | isNull(); //return false 36 | $scheme->isEmpty(); //return false 37 | echo $scheme->getContent(); //display 'ftp' 38 | echo $scheme->getContent(Scheme::RFC3986_ENCODING); //display 'ftp' 39 | echo $scheme->getContent(Scheme::RFC3987_ENCODING); //display 'ftp' 40 | echo $scheme->getContent(Scheme::NO_ENCODING); //display 'ftp' 41 | echo $scheme; //display 'ftp' 42 | echo $scheme->getUriComponent(); //display 'ftp:' 43 | 44 | $new_scheme = $scheme->withContent(null); 45 | $new_scheme->isNull(); //return true 46 | $new_scheme->isEmpty(); //return true 47 | echo $new_scheme->getContent(); //display null 48 | echo $new_scheme; //display '' 49 | echo $new_scheme->getUriComponent(); //display '' 50 | ~~~ 51 | 52 |

The delimiter : is not part of the component value and must not be added.

53 | 54 |

If the submitted value is not valid a League\Uri\Components\Exception exception is thrown.

55 | -------------------------------------------------------------------------------- /docs/components/1.0/userinfo.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: default 3 | title: The User information component 4 | redirect_from: 5 | - /5.0/components/userinfo/ 6 | --- 7 | 8 | The UserInfo 9 | ======= 10 | 11 | The library provides a `UserInfo` class to ease user information creation and manipulation. This URI component object exposes the [package common API](/components/1.0/api/), but also provide specific methods to work with the URI user information part. 12 | 13 | ## Creating a new object 14 | 15 | ~~~php 16 | submitted string is normalized to be RFC3986 compliant.

21 | 22 |

If the submitted value is not valid a League\Uri\Components\Exception exception is thrown.

23 | 24 | The `League\Uri\Components\Exception` extends PHP's SPL `InvalidArgumentException`. 25 | 26 | ## Accessing User information content 27 | 28 | ~~~php 29 | getUser(); //return 'foo' 44 | $info->getPass(); //return 'bar' 45 | ~~~ 46 | 47 | Just like the `ComponentInterface::getContent` method both `UserInfo::getUser` and `UserInfo::getPass` accept an optional `$enc_type` argument to specify how to encode the specify how to encode the returned value. 48 | 49 | ~~~php 50 | getUser(UserInfo::RFC3987_ENCODING); //return 'bébé' 56 | $info->getUser(UserInfo::RFC3986_ENCODING); //return 'b%C3%A9b%C3%A9' 57 | $info->getUser(); //return 'b%C3%A9b%C3%A9' 58 | ~~~ 59 | 60 | ## Modifying the user information 61 | 62 | ~~~php 63 | If the modifications do not change the current object, it is returned as is, otherwise, a new modified object is returned.

69 | 70 | Because the `UserInfo` is composed of at most two components the `UserInfo::withUserInfo` method is introduced to ease modify the object content. 71 | 72 | ~~~php 73 | withUserInfo('john', 'doe'); 79 | echo $new_info; //displays john:doe 80 | echo $info; //displays foo:bar 81 | ~~~ 82 | 83 |

If the modification is invalid a League\Uri\Components\Exception exception is thrown.

84 | -------------------------------------------------------------------------------- /docs/components/2.0/fragment.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: default 3 | title: The Fragment component 4 | --- 5 | 6 | # The Fragment component 7 | 8 | The library provides a `Fragment` class to ease fragment creation and manipulation. 9 | 10 | ## Creating a new object 11 | 12 | ~~~php 13 | submitted string is normalized to be RFC3986 compliant.

18 | 19 |

If the submitted value is not valid a League\Uri\Exceptions\SyntaxError exception is thrown.

20 | 21 | ## Properties and methods 22 | 23 | This URI component object only exposes the [package common API](/components/2.0/api/). 24 | 25 | An additional `decoded` method returns the component value safely decoded. 26 | 27 | ~~~php 28 | public Fragment::decoded(): ?string 29 | ~~~ 30 | 31 | ## Usage 32 | 33 | ~~~php 34 | getContent(); //display '%E2%82%AC' 40 | echo $fragment->decoded(); //display '€' 41 | echo $fragment; //display '%E2%82%AC' 42 | echo $fragment->getUriComponent(); //display '#%E2%82%AC' 43 | 44 | $new_fragment = $fragment->getContent(null); 45 | echo $new_fragment->getContent(); //display null 46 | echo $new_fragment; //display '' 47 | echo $new_fragment->getUriComponent(); //display '' 48 | 49 | $alt_fragment = $fragment->getContent(''); 50 | echo $alt_fragment->getContent(); //display '' 51 | echo $alt_fragment; //display '' 52 | echo $alt_fragment->getUriComponent(); //display '#' 53 | ~~~ 54 | 55 |

The delimiter # is not part of the component value and must not be added.

56 | 57 |

If the submitted value is not valid a League\Uri\Exceptions\SyntaxError exception is thrown.

58 | -------------------------------------------------------------------------------- /docs/components/2.0/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: default 3 | title: URI components 4 | --- 5 | 6 | Uri Components 7 | ======= 8 | 9 | [![Latest Version](https://img.shields.io/github/release/thephpleague/uri-components.svg?style=flat-square)](https://github.com/thephpleague/uri-components/releases) 10 | 11 | This package contains classes to help parsing and modifying URI components. 12 | 13 | - Simple interface for building and parsing URI components; 14 | - Interact with implementing PSR-7 `UriInterface` objects; 15 | 16 | ~~~php 17 | use League\Uri\Components\Query; 18 | use League\Uri\Uri; 19 | use League\Uri\UriModifier; 20 | 21 | $uri = Uri::createFromString('http://example.com?q=value#fragment'); 22 | $newUri = UriModifier::appendQuery($uri, 'q=new.Value'); 23 | echo $newUri; // 'http://example.com?q=value&q=new.Value#fragment'; 24 | 25 | $query = Query::createFromUri($newUri); 26 | $query->get('q'); // returns 'value' 27 | $query->getAll('q'); // returns ['value', 'new.Value'] 28 | $query->params('q'); // returns 'new.Value' 29 | ~~~ 30 | 31 | System Requirements 32 | ------- 33 | 34 | You need **PHP >= 7.2** but the latest stable version of PHP is recommended 35 | 36 | If you want to handle: 37 | 38 | - IDN host you are **required** to install the `intl` extension; 39 | - IPv4 host in octal or hexadecimal form, out of the box, you **need** at least one of the following extension: 40 | 41 | - install the `GMP` extension **or** 42 | - install the `BCMath` extension 43 | 44 | or you should be using 45 | 46 | - a `64-bits` PHP version 47 | 48 | Trying to process such hosts without meeting those minimal requirements will trigger a `RuntimeException`. 49 | - Data URI creation from a filepath, Since version `2.2.0`, the `fileinfo` extension is **required**. 50 | 51 | Installation 52 | -------- 53 | 54 | ~~~ 55 | $ composer require league/uri-components 56 | ~~~ 57 | 58 | Dependencies 59 | ------- 60 | 61 | - [League Uri Interfaces](https://github.com/thephpleague/uri-interfaces) 62 | - [PSR-7](http://www.php-fig.org/psr/psr-7/) 63 | 64 | What you will be able to do 65 | -------- 66 | 67 | - Build and parse query with [QueryString](/components/2.0/query-parser-builder/) 68 | - Partially modify URI with [URI Modifiers](/components/2.0/modifiers/) 69 | - Create and Manipulate URI components objects with a [Common API](/components/2.0/api/) 70 | -------------------------------------------------------------------------------- /docs/components/2.0/ipv4-normalizer.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: default 3 | title: IPv4 Normalizer 4 | --- 5 | 6 | IPv4 Normalizer 7 | ======= 8 | 9 | The `League\Uri\IPv4Normalizer` is a userland PHP IPv4 Host Normalizer. 10 | 11 | ```php 12 | normalizeHost($host); 20 | echo $host; // returns 0 21 | echo $normalizedHost; // returns 0.0.0.0 22 | ``` 23 | 24 | Usage 25 | -------- 26 | 27 |

The normalization algorithms uses the WHATWG rules to parse and format IPv4 multiple string representations into a valid IPv4 decimal representation.

28 | 29 | ### Description 30 | 31 | ```php 32 | normalizeAuthority($authority); 71 | 72 | echo $authority->getHost(); // returns '0300.0250.0000.0001' 73 | echo $normalizedAuthority->getHost(); // returns '192.168.0.1' 74 | ``` 75 | -------------------------------------------------------------------------------- /docs/components/2.0/modifiers/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: default 3 | title: URI partial modifiers 4 | --- 5 | 6 | URI modifiers 7 | ======= 8 | 9 | ## Example 10 | 11 | For instance here's how you would update the query string from a given URI object: 12 | 13 | ~~~php 14 | getQuery(), $params); 23 | parse_str($queryToMerge, $paramsToMerge); 24 | $query = http_build_query( 25 | array_merge($params, $paramsToMerge), 26 | '', 27 | '&', 28 | PHP_QUERY_RFC3986 29 | ); 30 | 31 | $newUri = $uri->withQuery($query); 32 | echo $newUri; // display http://www.example.com?fo_o=bar&taz=#~typo 33 | ~~~ 34 | 35 | Using the provided `League\Uri\UriModifier::mergeQuery` modifier the code becomes 36 | 37 | ~~~php 38 | Because each modification is done after parsing and building, the 12 | resulting query string may update the component character encoding. These changes are expected because of 13 | the rules governing parsing and building query string.

14 | 15 | ## UriModifier::sortQuery 16 | 17 | Sorts the query according to its key values. The sorting rules are the same uses by WHATWG `URLSearchParams::sort` method. 18 | 19 | ~~~php 20 | $uriString = "http://example.com/?kingkong=toto&foo=bar%20baz&kingkong=ape"; 21 | $uri = Http::createFromString($uriString); 22 | $newUri = UriModifier::sortQuery($uri); 23 | 24 | echo $uri->getQuery(); //display "kingkong=toto&foo=bar%20baz&kingkong=ape" 25 | echo $newUri->getQuery(); //display "kingkong=toto&kingkong=ape&foo=bar%20baz" 26 | ~~~ 27 | 28 | ## UriModifier::mergeQuery 29 | 30 | Merges a submitted query string to the URI object to be modified. When merging two query strings with the same key value the submitted query string value takes precedence over the URI query string value. 31 | 32 | ~~~php 33 | $uriString = "http://example.com/test.php?kingkong=toto&foo=bar+baz#doc3"; 34 | $uri = Http::createFromString($uriString); 35 | $newUri = UriModifier::mergeQuery($uri, 'kingkong=godzilla&toto'); 36 | 37 | echo $uri->getQuery(); //display "kingkong=toto&foo=bar+baz" 38 | echo $newUri->getQuery(); //display "kingkong=godzilla&foo=bar%20baz&toto" 39 | ~~~ 40 | 41 | ## UriModifier::appendQuery 42 | 43 | Appends a submitted query string to the URI object to be modified. When appending two query strings with the same key value the submitted query string value is added to the return query string without modifying the URI query string value. 44 | 45 | ~~~php 46 | $uriString = "http://example.com/test.php?kingkong=toto&foo=bar+baz#doc3"; 47 | $uri = Http::createFromString($uriString); 48 | $newUri = UriModifier::appendQuery($uri, 'kingkong=godzilla&toto'); 49 | 50 | echo $uri->getQuery(); //display "kingkong=toto&foo=bar+baz" 51 | echo $newUri->getQuery(); //display "kingkong=toto&kingkong=godzilla&foo=bar%20baz&toto" 52 | ~~~ 53 | 54 | ## UriModifier::removePairs 55 | 56 | Removes query pairs from the current URI query string by providing the pairs key. 57 | 58 | ~~~php 59 | $uriString = "http://example.com/test.php?kingkong=toto&foo=bar+baz&bar=baz#doc3") 60 | $uri = Http::createFromString($uriString); 61 | $newUri = UriModifier::removePairs($uri, 'foo', 'bar'); 62 | 63 | echo $uri->getQuery(); //display "kingkong=toto&foo=bar+baz&bar=baz" 64 | echo $newUri->getQuery(); //display "kingkong=toto" 65 | ~~~ 66 | 67 | ## UriModifier::removeParams 68 | 69 | Removes query params from the current URI query string by providing the param name. The removal preserves mangled key params. 70 | 71 | ~~~php 72 | $uriString = "http://example.com/test.php?kingkong=toto&fo.o=bar&fo_o=bar"; 73 | $uri = Http::createFromString($uriString); 74 | $newUri = UriModifier::removeParams($uri, 'fo.o'); 75 | 76 | echo $uri->getQuery(); //display "kingkong=toto&fo.o=bar&fo_o=bar" 77 | echo $newUri->getQuery(); //display "kingkong=toto&fo_o=bar" 78 | ~~~ 79 | -------------------------------------------------------------------------------- /docs/components/2.0/port.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: default 3 | title: The Port component 4 | --- 5 | 6 | # The Port component 7 | 8 | The library provides a `Port` class to ease port manipulation. 9 | 10 | ## Creating a new object 11 | 12 | ~~~php 13 | public Port::__construct(?int $content = null): void 14 | ~~~ 15 | 16 |

If the submitted value is not valid a League\Uri\Exceptions\SyntaxError exception is thrown.

17 | 18 | ## Properties and methods 19 | 20 | This URI component object exposes the [package common API](/components/2.0/api/). 21 | 22 | An additional `toInt` method returns the component value as an integer or `null` if the component is not defined. 23 | 24 | ~~~php 25 | public Port::toInt(): ?int 26 | ~~~ 27 | 28 | ## Usage 29 | 30 | ~~~php 31 | getContent(); //returns (int) 443 37 | 38 | echo $port; //displays '443' 39 | echo $port->getUriComponent(); //displays ':443' 40 | $port->toInt(); // returns 443 41 | 42 | $new_port = $port->withContent(null); 43 | $new_port->getContent(); //returns null 44 | $new_port->toInt(); //returns null 45 | echo $new_port; //displays '' 46 | echo $new_port->getUriComponent(); //displays '' 47 | ~~~ 48 | 49 |

The delimiter : is not part of the component value and must not be added.

50 | 51 |

If the submitted value is not valid a League\Uri\Exceptions\SyntaxError exception is thrown.

52 | -------------------------------------------------------------------------------- /docs/components/2.0/scheme.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: default 3 | title: The Scheme component 4 | --- 5 | 6 | # The Scheme component 7 | 8 | The `Scheme` class eases scheme creation and manipulation. This URI component object only exposes the [package common API](/components/2.0/api/). 9 | 10 | ## Usage 11 | 12 | ~~~php 13 | getContent(); //display 'ftp' 19 | echo $scheme; //display 'ftp' 20 | echo $scheme->getUriComponent(); //display 'ftp:' 21 | 22 | $new_scheme = $scheme->withContent(null); 23 | echo $new_scheme->getContent(); //display null 24 | echo $new_scheme; //display '' 25 | echo $new_scheme->getUriComponent(); //display '' 26 | ~~~ 27 | 28 |

The delimiter : is not part of the component value and must not be added.

29 | 30 |

If the submitted value is not valid a League\Uri\Exceptions\SyntaxError exception is thrown.

31 | -------------------------------------------------------------------------------- /docs/components/2.0/upgrading.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: default 3 | title: Upgrading from 1.x to 2.x 4 | --- 5 | 6 | # Upgrading from 1.x to 2.x 7 | 8 | `uri-components:2.0` is a new major version that comes with backward compatibility breaks. 9 | 10 | This guide will help you migrate from a 1.x version to 2.0. It will only explain backward incompatibility breaks, it will not present the new features ([read the documentation for that](/components/2.0/)). 11 | 12 | ## Installation 13 | 14 | If you are using composer then you should update the require section of your `composer.json` file. 15 | 16 | ~~~ 17 | composer require league/uri-components:^2.0 18 | ~~~ 19 | 20 | This will edit (or create) your `composer.json` file. 21 | 22 | ## PHP version requirement 23 | 24 | `uri-components:2.0` requires a PHP version greater or equal than 7.2.0 (was previously 7.0.0). 25 | 26 | ## Package replacements and conflicts 27 | 28 | This package: 29 | 30 | - replaces and deprecates without conflicting the `uri-query-parser` package. 31 | - partially replaces and deprecates without conflicting the `uri-manipulation` package. 32 | 33 | ## Removed features 34 | 35 | ### Host Public Suffix Resolution 36 | 37 | This package no longer expose API to resolve Public Suffix List in Host. We recommend using a dedicated package for that like [PHP Domain Parser](https://github.com/jeremykendall/php-domain-parser). 38 | 39 | ### Everything is final 40 | 41 | Components objects are now all marked as final and implements at least one interface. 42 | 43 | To use them you can either typehint against their interfaces or against a specific implementation but you can no longer extend them. 44 | 45 | ### UriComponentInterface 46 | 47 | Because this new package targets PHP7.2+ the: 48 | 49 | - `UriComponentInterface::isEmpty`; 50 | - `UriComponentInterface::isNull`; 51 | 52 | methods are removed in favor of `UriComponentInterface::getContent()` method. 53 | 54 | Also, the `UriComponentInterface::getContent()` method no longer takes any parameter and always returns the RFC3986 version of the URI component. 55 | 56 | ### Host 57 | 58 | The `Host` object no longer is iterable or exposes label related methods. To be able to access the host lables you need to instantiate a `Domain` object. 59 | All information regarding Public Suffix information has been removed from the package. 60 | 61 | ### Query 62 | 63 | The `Query` object public API has been updated to better match the [WHATWG URL living standard URLSearchParams class](https://url.spec.whatwg.org/#interface-urlsearchparams). 64 | You will need to upgrade your code to match this specification expected values. 65 | -------------------------------------------------------------------------------- /docs/components/2.0/userinfo.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: default 3 | title: The User information component 4 | --- 5 | 6 | The UserInfo 7 | ======= 8 | 9 | The `League\Uri\Components\UserInfo` class eases user information creation and manipulation. 10 | This URI component object exposes the [package common API](/components/2.0/api/), 11 | but also provide specific methods to work with the URI user information part. 12 | 13 | ## Creating a new object 14 | 15 | ~~~php 16 | public UserInfo::__construct($user, $pass = null): void 17 | ~~~ 18 | 19 |

submitted string is normalized to be RFC3986 compliant.

20 | 21 |

If the submitted value is not valid a League\Uri\Exceptions\SyntaxError exception is thrown.

22 | 23 | ## Accessing User information content 24 | 25 | ~~~php 26 | public UserInfo::getUser(): ?string 27 | public UserInfo::getPass(): ?string 28 | ~~~ 29 | 30 | To access the user login and password information you need to call the respective `UserInfo::getUser` and `UserInfo::getPass` methods like shown below. 31 | 32 | ~~~php 33 | $info = new UserInfo('foo', 'bar'); 34 | $info->getUser(); //return 'foo' 35 | $info->getPass(); //return 'bar' 36 | ~~~ 37 | 38 | ## Modifying the user information 39 | 40 | ~~~php 41 | public UserInfo::withUserInfo($user, $password = null): self 42 | ~~~ 43 | 44 |

If the modifications do not change the current object, it is returned as is, otherwise, a new modified object is returned.

45 | 46 | Because the `UserInfo` is composed of at most two components the `UserInfo::withUserInfo` method is introduced to ease modify the object content. 47 | 48 | ~~~php 49 | $info = new UserInfo('foo', 'bar'); 50 | $new_info = $info->withUserInfo('john', 'doe'); 51 | echo $new_info; //displays john:doe 52 | echo $info; //displays foo:bar 53 | ~~~ 54 | 55 |

If the submitted value is not valid a League\Uri\Exceptions\SyntaxError exception is thrown.

56 | -------------------------------------------------------------------------------- /docs/components/7.0/fragment.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: default 3 | title: The Fragment component 4 | --- 5 | 6 | # The Fragment component 7 | 8 | The `Fragment` class represents the URI fragment component. Apart from the [package common API](/components/7.0/), 9 | the class exposes an additional `decoded` method to return the component value safely decoded. 10 | 11 | ~~~php 12 | value(); //display '%E2%82%AC' 18 | echo $fragment->decoded(); //display '€' 19 | echo $fragment->toString(); //display '%E2%82%AC' 20 | echo $fragment->getUriComponent(); //display '#%E2%82%AC' 21 | echo $fragment; //display '%E2%82%AC' 22 | 23 | $newFragment = Fragment::new(); 24 | echo $newFragment->value(); //display null 25 | echo $newFragment->decoded(); //display '' 26 | echo $newFragment->toString(); //display '' 27 | echo $newFragment->getUriComponent(); //display '' 28 | echo $newFragment; //display '' 29 | 30 | $altFragment = Fragment::fromUri('https://thephpleague.com#'); 31 | echo $altFragment->value(); //display '' 32 | echo $altFragment->decoded(); //display '' 33 | echo $altFragment->toString(); //display '' 34 | echo $altFragment->getUriComponent(); //display '#' 35 | echo $altFragment; //display '' 36 | ~~~ 37 | 38 |

The object can not be modified, you are required to instantiate a new object.

39 |

The delimiter : is not part of the component value and must not be added.

40 |

If the submitted value is not valid a League\Uri\Exceptions\SyntaxError exception is thrown.

41 | -------------------------------------------------------------------------------- /docs/components/7.0/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: default 3 | title: URI components 4 | redirect_from: 5 | - /components/ 6 | --- 7 | 8 | Uri Components 9 | ======= 10 | 11 | Introduction 12 | ------- 13 | 14 | [![Author](https://img.shields.io/badge/author-@nyamsprod-blue.svg?style=flat-square)](https://twitter.com/nyamsprod) 15 | [![Latest Version](https://img.shields.io/github/release/thephpleague/uri-components.svg?style=flat-square)](https://github.com/thephpleague/uri-components/releases) 16 | [![Software License](https://img.shields.io/badge/license-MIT-brightgreen.svg?style=flat-square)](LICENSE.md)
17 | [![Total Downloads](https://img.shields.io/packagist/dt/league/uri.svg?style=flat-square)](https://packagist.org/packages/league/uri) 18 | 19 | While working with URI, you may stumble on some tasks, such as parsing its query string or updating its host, 20 | that are not covered by the [URI package](/uri/7.0/). 21 | Thankfully, the URI component package allows you to easily parse, create, manipulate URI components as well as partially 22 | update URIs. By using the package, your application can safely perform tasks around your URIs and provide a better 23 | user experience to your developers. 24 | 25 | ~~~php 26 | use League\Uri\Components\Query; 27 | use League\Uri\Modifier; 28 | 29 | $newUri = Modifier::from('http://example.com?q=value#fragment') 30 | ->appendQuery('q=new.Value'); 31 | echo $newUri; // 'http://example.com?q=value&q=new.Value#fragment'; 32 | 33 | $query = Query::fromUri($newUri); 34 | $query->get('q'); // returns 'value' 35 | $query->getAll('q'); // returns ['value', 'new.Value'] 36 | $query->parameter('q'); // returns 'new.Value' 37 | ~~~ 38 | 39 | The package provides easy to use classes [to partially modify a URI](/components/7.0/modifiers/) 40 | and at the same time a complete set of class and tools [to specifically interact](/components/7.0/api/) 41 | with each component of a RFC3986 URI. 42 | 43 | System Requirements 44 | ------- 45 | 46 | You need **PHP >= 8.1.0** but the latest stable version of PHP is recommended 47 | 48 | Handling of an IDN host requires the presence of the `intl` 49 | extension or a polyfill for the `intl` IDN functions like the 50 | `symfony/polyfill-intl-idn` otherwise an exception will be thrown 51 | when attempting to validate or interact with such a host. 52 | 53 | IPv4 conversion requires at least one of the following: 54 | 55 | - the `GMP` extension, 56 | - the `BCMatch` extension or 57 | - a `64-bits` PHP version 58 | 59 | otherwise an exception will be thrown when attempting to convert a host 60 | as an IPv4 address. 61 | 62 | In order to create Data URI from the content of a file you are required to also 63 | install the `fileinfo` extension otherwise an exception will be thrown. 64 | 65 | Installation 66 | -------- 67 | 68 | ~~~ 69 | $ composer require league/uri-components:^7.0 70 | ~~~ 71 | 72 | Dependencies 73 | ------- 74 | 75 | - [League Uri Interfaces](https://github.com/thephpleague/uri-interfaces) 76 | - [League Uri](https://github.com/thephpleague/uri) 77 | - [PSR-7](http://www.php-fig.org/psr/psr-7/) 78 | -------------------------------------------------------------------------------- /docs/components/7.0/path.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: default 3 | title: Path Component 4 | --- 5 | 6 | Path Component 7 | ======= 8 | 9 | The `Path` class represents a generic path component. Apart from the [package common API](/components/7.0/) the class 10 | exposes basic properties and method to manipulate any type of path. 11 | 12 | ## Path leading and trailing slash 13 | 14 | Most of the time, regardless of the type of Path, you will want to get information around the nature of your path. Is it 15 | absolute or relative ? Does it expose a trailing slash or not ? To answer those questions and to manipulate its statuses 16 | you can at any given time get or update the path status. 17 | 18 | ~~~php 19 | isAbsolute(); //return true 25 | $absolutePath->hasTrailingSlash(); //return true 26 | echo $absolutePath-; //displays '/path/to/the/sky/' 27 | 28 | $relativePath = $absolutePath->withoutTrailingSlash(); 29 | $relativePath->isAbsolute(); //return true; 30 | $relativePath->hasTrailingSlash(); //return false 31 | echo $relativePath; //displays '/path/to/the/sky' 32 | 33 | $noSlash = $relativePath->withLeadingSlash(); 34 | $noSlash->isAbsolute(); //return false; 35 | $noSlash->hasTrailingSlash(); //return false 36 | echo $noSlash; //displays 'path/to/the/sky' 37 | ~~~ 38 | 39 | ## Path modifications 40 | 41 |

If the modifications do not change the current object, it is returned as is, otherwise, a new modified object is returned.

42 |

When a modification fails a League\Uri\Contracts\UriException exception is thrown.

43 | 44 | Out of the box, the `Path` object operates a number of non-destructive normalizations. For instance, the path is correctly URI encoded against the RFC3986 rules. 45 | 46 | ### Removing dot segments 47 | 48 | To remove dot segment as per [RFC3986](https://tools.ietf.org/html/rfc3986#section-6) you need to explicitly call the `Path::withoutDotSegments` method as the result can be destructive. The method takes no argument and returns a new `Path` object which represents the current object without dot segments. 49 | 50 | ~~~php 51 | withoutDotSegments(); 57 | echo $path; //displays 'path/to/./the/../the/sky%7bfoo%7d' 58 | echo $newPath; //displays 'path/to/the/sky%7Bfoo%7D' 59 | ~~~ 60 | 61 | ## Specialized Path Object 62 | 63 | What makes a URI specific apart from the scheme is how the path is parse and manipulated. This simple path class 64 | although functional will not ease parsing a Data URI path or an HTTP Uri path. That's why the library comes bundles 65 | with two specialized Path objects that decorates the current object and adds more specific methods in accordance 66 | to the path usage: 67 | 68 | - the [HierarchicalPath](/components/7.0/hierarchical-path/) object to work with Hierarchical paths component 69 | - the [DataPath](/components/7.0/data-path/) object to work with the Data URIs path 70 | -------------------------------------------------------------------------------- /docs/components/7.0/port.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: default 3 | title: The Port component 4 | --- 5 | 6 | # The Port component 7 | 8 | The `Port` class represents the URI Port component. Apart from the [package common API](/components/7.0/), 9 | the class exposes an additional `toInt` method which returns the component value as an integer or `null` 10 | if the component is not defined. 11 | 12 | ~~~php 13 | value(); //returns '443' 19 | $port->toInt(); //returns 443 20 | echo $port; //displays '443' 21 | echo $port->toString(); //displays '443' 22 | echo $port->getUriComponent(); //displays ':443' 23 | 24 | $nullPort = Port::new(); 25 | $nullPort->value(); //returns null 26 | $nullPort->toInt(); //returns null 27 | echo $nullPort; //displays '' 28 | echo $nullPort->toString(); //displays '' 29 | echo $nullPort->getUriComponent(); //displays '' 30 | ~~~ 31 | 32 |

The object can not be modified, you are required to instantiate a new object.

33 |

The delimiter : is not part of the component value and must not be added.

34 |

If the submitted value is not valid a League\Uri\Exceptions\SyntaxError exception is thrown.

35 | -------------------------------------------------------------------------------- /docs/components/7.0/scheme.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: default 3 | title: The Scheme component 4 | --- 5 | 6 | # The Scheme component 7 | 8 | The `Scheme` class represents the URI scheme component and exposes the [package common API](/components/7.0/). 9 | 10 | ~~~php 11 | value(); //display 'ftp' 17 | echo $scheme->toString(); //display 'ftp' 18 | echo $scheme; //display 'ftp' 19 | echo $scheme->getUriComponent(); //display 'ftp:' 20 | 21 | $new_scheme = Scheme::new(); 22 | echo $new_scheme->value(); //display null 23 | echo $new_scheme->toString(); //display '' 24 | echo $new_scheme; //display '' 25 | echo $new_scheme->getUriComponent(); //display '' 26 | 27 | $alt_scheme = Scheme::fromUri('email:toto@example.com'); 28 | echo $alt_scheme->value(); //display 'email' 29 | echo $alt_scheme->toString(); //display 'email' 30 | echo $alt_scheme; //display 'email' 31 | echo $alt_scheme->getUriComponent(); //display 'email' 32 | ~~~ 33 | 34 |

The object can not be modified, you are required to instantiate a new object.

35 |

The delimiter : is not part of the component value and must not be added.

36 |

If the submitted value is not valid a League\Uri\Exceptions\SyntaxError exception is thrown.

37 | 38 | Starting with version `7.5.0` the scheme object give a bit more information around the selected scheme. It will let you know: 39 | 40 | if you are using an HTTP protocol via its `Scheme::isHttp` method: 41 | 42 | ~~~php 43 | Scheme::new('FtP')->isHttp(); // return false 44 | Scheme::new('HttPs')->isHttp(); // return true 45 | ~~~ 46 | 47 | if you are using a websocket scheme via its `Scheme::isWebsocket` method: 48 | 49 | ~~~php 50 | Scheme::new('ws')->isWebsocket(); // return true 51 | Scheme::new('HttPs')->isWebsocket(); // return false 52 | ~~~ 53 | 54 | if you are using a SSL scheme via its `Scheme::isSsl` method: 55 | 56 | ~~~php 57 | Scheme::new('wss')->isSsl(); // return true 58 | Scheme::new('Http')->isWebsocket(); // return false 59 | ~~~ 60 | 61 | if you are using a special scheme via its `Scheme::isSpecial` method: 62 | 63 | ~~~php 64 | Scheme::new('ldap')->isSpecial(); // return false 65 | Scheme::new('file')->isSpecial(); // return true 66 | ~~~ 67 | 68 | the default port used by a special scheme via the `Scheme::defaultPort` method: 69 | 70 | ~~~php 71 | Scheme::new('https')->defaultPort(); // Port::new(443); 72 | Scheme::new('file')->defaultPort(); // Port::new(null); 73 | ~~~ 74 | 75 | If the scheme is not special the method will return a `Port` object equivalent to the `null` 76 | port value. 77 | -------------------------------------------------------------------------------- /docs/components/7.0/userinfo.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: default 3 | title: The User information component 4 | --- 5 | 6 | The UserInfo 7 | ======= 8 | 9 | The `UserInfo` class represents a URI authority component. Apart from the [package common API](/components/7.0/) the class 10 | exposes basic properties and method to manipulate its different component. 11 | 12 |

If the modifications do not change the current object, it is returned as is, otherwise, a new modified object is returned.

13 |

If the submitted value is not valid a League\Uri\Exceptions\SyntaxError exception is thrown.

14 | 15 | ## Creating a new object 16 | 17 | The `UserInfo` class comes with named constructors to ease instantiation. The following examples show 18 | how to instantiate the class: 19 | 20 |

submitted string is normalized to be RFC3986 compliant.

21 | 22 | ~~~php 23 | toString(); //returns 'user:pass' 30 | 31 | UserInfo::new('user:pass')->value(); //returns 'user:pass' 32 | UserInfo::fromUri("http://www.example.com/path/to/the/sky")->getUser(); //return null; 33 | UserInfo::new()->value(); //return null; 34 | UserInfo::fromComponents( 35 | UriString::parse("http://user:pass@example.com:42/5.0/uri/api") 36 | )->value(); //returns 'user:pass' 37 | ~~~ 38 | 39 |

submitted string is normalized to be RFC3986 compliant.

40 |

If the submitted value is not valid a League\Uri\Exceptions\SyntaxError exception is thrown.

41 | 42 | ## Accessing User information content 43 | 44 | To access the user login and password information you need to call the respective `UserInfo::getUser` 45 | and `UserInfo::getPass` methods like shown below. 46 | 47 | ~~~php 48 | use League\Uri\Components\UserInfo; 49 | 50 | $info = new UserInfo('user', 'p@ss'); 51 | $info->getUser(); //returns 'user' 52 | $info->getPass(); //returns 'p@ss' 53 | $info->getUsername(); //returns 'user' 54 | $info->getPassword(); //returns 'p%40ss' 55 | $info->components(); //returns array {"user" => "user", "pass" => "p@ss"} 56 | ~~~ 57 | 58 |

getUsername and getPassword are added in version 7.5.0

59 | 60 | ## Modifying the user information 61 | 62 |

If the modifications do not change the current object, it is returned as is, otherwise, a new modified object is returned.

63 | 64 | ~~~php 65 | use League\Uri\Components\UserInfo; 66 | 67 | $info = UserInfo::fromUri('https://login:pass@thephpleague.com/path/to/heaven'); 68 | echo $info; //displays login:pass 69 | echo $info->withUser('john')->withPass('doe'); //displays john:doe 70 | ~~~ 71 | 72 |

If the user part is `null`, trying to give the password any other value than the `null` value with throw an Exception.

73 | 74 | ~~~php 75 | new UserInfo(null, 'bar'); // throws a SyntaxError 76 | UserInfo::fromAuthority('thephpleague:443')->withPass('foo'); // throws a SyntaxError 77 | ~~~ 78 | 79 |

If the submitted value is not valid a League\Uri\Exceptions\SyntaxError exception is thrown.

80 | -------------------------------------------------------------------------------- /docs/custom.js: -------------------------------------------------------------------------------- 1 | (() => { 2 | 3 | let headers = document.querySelector('header nav h2'); 4 | if (headers) { 5 | headers.addEventListener('click', function() { 6 | this.parentNode.querySelector('ul').classList.toggle('show'); 7 | }, false); 8 | } 9 | 10 | let contentHeaders = document.querySelectorAll("main h2[id]"); 11 | if (!document.querySelector('html').classList.contains('homepage') && contentHeaders) { 12 | const uri = new URL(location.href); 13 | contentHeaders.forEach((header) => { 14 | uri.hash = header.id; 15 | let link = document.createElement("a"); 16 | link.classList.add("header-permalink"); 17 | link.title = "Permalink"; 18 | link.href = uri.toString(); 19 | link.innerHTML = "¶"; 20 | header.appendChild(link); 21 | }); 22 | } 23 | 24 | const sponsorBanner = document.querySelector('.sponsors'); 25 | if (sponsorBanner) { 26 | let hideUntil = localStorage.getItem('hideSponsorUntil'); 27 | if (hideUntil === null || hideUntil < (new Date().getTime())) { 28 | localStorage.removeItem('hideSponsorUntil'); 29 | sponsorBanner.classList.remove('hide'); 30 | } 31 | 32 | let closeButton = document.createElement('a'); 33 | closeButton.classList.add('close'); 34 | closeButton.innerHTML = 'close me'; 35 | closeButton.addEventListener('click', () => { 36 | localStorage.setItem('hideSponsorUntil', new Date().getTime() + (7 * 86400 * 1e4)); 37 | sponsorBanner.classList.add('hide'); 38 | }, false); 39 | 40 | sponsorBanner.firstElementChild.appendChild(closeButton); 41 | } 42 | })(); 43 | -------------------------------------------------------------------------------- /docs/docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: '3' 2 | 3 | services: 4 | jekyll: 5 | image: jekyll/jekyll:latest 6 | command: jekyll serve --watch --force_polling --verbose 7 | ports: 8 | - 4000:4000 9 | volumes: 10 | - .:/srv/jekyll 11 | -------------------------------------------------------------------------------- /docs/domain-parser/1.0/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: default 3 | title: ICANN Section Public Suffix Resolver 4 | redirect_from: 5 | - /domain-parser/ 6 | - /5.0/publicsuffix/ 7 | --- 8 | 9 | URI Hostname Parser 10 | ======= 11 | 12 | [![Build Status](https://img.shields.io/travis/thephpleague/uri-hostname-parser/master.svg?style=flat-square)](https://travis-ci.org/thephpleague/uri-hostname-parser) 13 | [![Latest Version](https://img.shields.io/github/release/thephpleague/uri-hostname-parser.svg?style=flat-square)](https://github.com/thephpleague/uri-hostname-parser/releases) 14 | 15 |

This library replaces PHP Domain Parser starting with version 5.2.0

16 | 17 | This library contains 18 | 19 | - a ICANN Section [Public Suffix List](https://publicsuffix.org/) Manager. 20 | - a [Public Suffix Finder](/domain-parser/1.0/rules/) class to resolve domain names. 21 | - a helper function to ease resolving domain names with default options. 22 | 23 | This library contains a lightweight domain parser using the [Public Suffix List (PSL) ICANN section](http://publicsuffix.org/) based on the excellent [PHP Domain Parser](https://github.com/jeremykendall/php-domain-parser/) by [Jeremy Kendall](https://github.com/jeremykendall). 24 | 25 | The main differences with [PHP Domain Parser](https://github.com/jeremykendall/php-domain-parser/) are: 26 | 27 | - This library **only** uses the ICANN Section of the Public Suffix List data 28 | - This library supports PHP7.2+ 29 | - This library does not validate the hostname nor the cookie header host part 30 | 31 | To validate your hostname please refer to [URI components](https://github.com/thephpleague/uri-components/) 32 | To validate your cookie headers please use [PHP Domain Parser](https://github.com/jeremykendall/php-domain-parser/). 33 | 34 | This library depends on [PSR-16](http://www.php-fig.org/psr/psr-16/). 35 | 36 | System Requirements 37 | ------- 38 | 39 | You require: 40 | 41 | - **PHP >= 7.0** but the latest stable version of PHP is recommended 42 | - the `intl` extension 43 | 44 | Installation 45 | -------- 46 | 47 | ~~~bash 48 | $ composer require league/uri-hostname-parser 49 | ~~~ 50 | -------------------------------------------------------------------------------- /docs/domain-parser/1.0/rules.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: default 3 | title: Public Suffix Resolver 4 | redirect_from: 5 | - /publicsuffix/rules/ 6 | --- 7 | 8 | Public Suffix Resolver 9 | ======= 10 | 11 | ## Rules and Domain 12 | 13 | 14 | The `Rules` constructor expects a `array` representation of the Public Suffix List. This `array` representation is constructed by the `ICANNSectionManager` and stored using a PSR-16 compliant cache. 15 | 16 | The `Rules` class resolves the submitted domain against the parsed rules from the PSL. This is done using the `Rules::resolve` method which returns a `League\Uri\PublicSuffix\Domain` object. 17 | 18 | The `Domain` getters method always return normalized value according to the domain status against the PSL rules. 19 | 20 |

Domain::isValid status depends on the PSL rules used. For the same domain, depending on the rules used a domain public suffix may be valid or not. Since this package only deals with the ICANN Section rules, the validity will be tested only against said rules.

21 | 22 | ~~~php 23 | getRules('https://raw.githubusercontent.com/publicsuffix/list/master/public_suffix_list.dat'); 31 | //$icann_rules is a League\Uri\PublicSuffix\Rules object 32 | 33 | $domain = $icann_rules->resolve('www.bbc.co.uk'); 34 | $domain->getDomain(); //returns 'www.bbc.co.uk' 35 | $domain->getPublicSuffix(); //returns 'co.uk' 36 | $domain->getRegistrableDomain(); //returns 'bbc.co.uk' 37 | $domain->getSubDomain(); //returns 'www' 38 | $domain->isValid(); //returns true 39 | ~~~ 40 | 41 |

Warning: Some people use the PSL to determine what is a valid domain name and what isn't. This is dangerous, particularly in these days where new gTLDs are arriving at a rapid pace, if your software does not regularly receive PSL updates, because it will erroneously think new gTLDs are not valid. The DNS is the proper source for this innormalizeion. If you must use it for this purpose, please do not bake static copies of the PSL into your software with no update mechanism.

42 | 43 | ## Helper function 44 | 45 | ~~~php 46 | getDomain(); //returns 'www.bbc.co.uk' 77 | $domain->getPublicSuffix(); //returns 'co.uk' 78 | $domain->getRegistrableDomain(); //returns 'bbc.co.uk' 79 | $domain->getSubDomain(); //returns 'www' 80 | $domain->isValid(); //returns true 81 | ~~~ -------------------------------------------------------------------------------- /docs/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: index 3 | title: The URI toolkit For PHP Developers 4 | --- 5 | 6 | The URI toolkit For PHP Developers 7 | --- 8 | 9 | Suite of packages which provide intuitive features to parse, validate, format and manipulate URIs and 10 | their components. Built to enable working with any kind of [RFC3986](https://tools.ietf.org/html/rfc3986) 11 | compliant URI and follow closely the latest [WHATWG URL Living Standard](https://url.spec.whatwg.org/) 12 | specification. It provides an enhanced replacement for PHP's `parse_url`, `http_build_query`, PECL's 13 | `http_build_url` functions, as well as [PSR-7](https://www.php-fig.org/psr/psr-7/) 14 | and [PSR-17](https://www.php-fig.org/psr/psr-17/) adapters. 15 | 16 | ```php 17 | use League\Uri\Components\Query; 18 | use League\Uri\Modifier; 19 | use League\Uri\Uri; 20 | 21 | $uri = Uri::new('https://example.com?q=value#fragment'); 22 | $uri->getScheme(); // returns 'http' 23 | $uri->getHost(); // returns 'example.com' 24 | 25 | $newUri = Modifier::from($uri)->appendQuery('q=new.Value'); 26 | echo $newUri; // 'https://example.com?q=value&q=new.Value#fragment' 27 | 28 | $query = Query::fromUri($newUri); 29 | $query->get('q'); // returns 'value' 30 | $query->getAll('q'); // returns ['value', 'new.Value'] 31 | $query->parameter('q'); // returns 'new.Value' 32 | ``` 33 | 34 | Choose the package that suits your needs 35 | ==== 36 | 37 | ### [URI-INTERFACES](/interfaces/7.0/) 38 | 39 | The URI utility package 40 | 41 | - URI parser and builder 42 | - Query parser and builder 43 | - IDNA, IPv4 and IPv6 converter 44 | - Encode/decode URI components 45 | 46 | ### [URI](/uri/7.0/) 47 | 48 | The URI manipulation package 49 | 50 | - URI object with complete validation 51 | - Resolves and Relativizes URIs 52 | - Expands URI Templates 53 | - PSR-7 and PSR-17 URI adapters 54 | 55 | ### [URI-COMPONENTS](/uri-components/7.0/) 56 | 57 | The URI components package 58 | 59 | - Provides URI components objects 60 | - URLSearchParams for PHP 61 | - Partial modifiers for URI. 62 | 63 | **Once a new major version is released, the previous stable release remains supported 64 | for six more months with patches and security fixes.** 65 | -------------------------------------------------------------------------------- /docs/interfaces/7.0/encoder.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: default 3 | title: URI component encoder and decoder 4 | --- 5 | 6 | URI component encoder and decoder 7 | ======= 8 | 9 | In order to safely encode and/or decode a URI component, we need a tool to correctly perform the conversion. 10 | To do so the package provides an enhanced OOP wrapper around PHP's `rawurlencode` and `rawurldecode` functions 11 | using the `League\Uri\Encoder` helper class. 12 | 13 | The class provides encoding mechanism for the following URI components: 14 | 15 | ```php 16 | The scheme and port do not requires a specific class to be correctly 63 | encoded. While host can be urlencoded and urldecoded, modern host encoding/decoding mechanism 64 | relies on a much more strict and documented process like the one use for instance wit the 65 | League\Uri\Idna\Converter class.

66 | 67 |

The Encoder::decodeAll may produce component representation that are not valid 68 | (containing white spaces or representing the null value) in the context of a full URI creation.

69 | -------------------------------------------------------------------------------- /docs/interfaces/7.0/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: default 3 | title: URI common interfaces and tools 4 | redirect_from: 5 | - /interfaces/ 6 | --- 7 | 8 | Uri Common tools 9 | ======= 10 | 11 | This package contains: 12 | 13 | - interface to represent [URI and components objects](/interfaces/7.0/contracts/) 14 | - parsers to parse and build [URI](/interfaces/7.0/uri-parser-builder/) and [Query](/interfaces/7.0/query-parser-builder/) strings that provide enhanced replacement for PHP's `parse_url` and PECL's `http_build_url` functions via its [UriString](/uri/7.0/parser-builder) class. 15 | - tools to help in processing URIs ([IPv4 Converter](/interfaces/7.0/ipv4/), [IPv6 Converter](/interfaces/7.0/ipv6/) and [IDN converter](/interfaces/7.0/idn/)) and their components in various ways. 16 | 17 | System Requirements 18 | ------- 19 | 20 | You need **PHP >= 8.1** but the latest stable version of PHP is recommended. 21 | 22 | Handling of an IDN host requires the presence of the `intl` 23 | extension or a polyfill for the `intl` IDN functions like the 24 | `symfony/polyfill-intl-idn` otherwise an exception will be thrown 25 | when attempting to validate or interact with such a host. 26 | 27 | IPv4 conversion requires at least one of the following: 28 | 29 | - the `GMP` extension, 30 | - the `BCMatch` extension or 31 | - a `64-bits` PHP version 32 | 33 | otherwise an exception will be thrown when attempting to convert a host 34 | as an IPv4 address. 35 | 36 | Install 37 | -------- 38 | 39 | ``` 40 | $ composer require league/uri-interfaces:^7.0 41 | ``` 42 | -------------------------------------------------------------------------------- /docs/interfaces/7.0/ipv6.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: default 3 | title: IPv6 Converter 4 | --- 5 | 6 | IPv6 Converter 7 | ======= 8 | 9 | The `League\Uri\IPv6\Converter` is a IPv6 Converter. 10 | 11 | ```php 12 | The returned string MAY no longer be a valid URI

24 | 25 | ### setEncoding 26 | 27 | By default the formatter encode each URI component using RFC3986 rules. You can change the component encoding algorithm by specifying one of the predefined constant: 28 | 29 | - `Formatter::RFC3986_ENCODING` to encode the URI and its component according to RFC3986; 30 | - `Formatter::RFC3987_ENCODING` to encode the URI and its component according to RFC3987; 31 | - `Formatter::NO_ENCODING` to remove any encoding from each URI component; 32 | 33 | ### setQuerySeparator 34 | 35 | If you want to generate an URI string compatible with HTML rules you need for instance to convert the `&` to its HTML entity `&`. This setter enables you to change the query separator in the return URI string. 36 | 37 | ### preserveQuery and preserveFragment 38 | 39 | By default PSR-7 `UriInterface` does not preserve query and fragment delimiters in the string representation. If you want to keep them you need to specify this behaviour to the `Formatter` object. By default, the `Formatter` does not keep them too. 40 | 41 | ## Example 42 | 43 | ~~~php 44 | setHostEncoding(Formatter::RFC3987_ENCODING); 51 | $formatter->setQuerySeparator('&'); 52 | $formatter->preserveFragment(true); 53 | 54 | $uri = new DiactorosUri('https://xn--p1ai.ru:81?foo=ba%20r&baz=bar'); 55 | echo $formatter($uri); 56 | //displays 'https://рф.ru:81?foo=ba r&baz=bar#' 57 | ~~~ 58 | 59 | ## Function alias 60 | 61 |

available since version 1.1.0

62 | 63 | ~~~php 64 | = 7.0** but the latest stable version of PHP is recommended 34 | 35 | Installation 36 | -------- 37 | 38 | ~~~ 39 | $ composer require league/uri-manipulations 40 | ~~~ 41 | 42 | Dependencies 43 | ------- 44 | 45 | - [PSR-7 UriInterface](http://php-fig.org/psr/psr-7/) 46 | - [League URI Interfaces](https://github.com/thephpleague/uri-interfaces) 47 | - [League URI Components](/5.0/components/) -------------------------------------------------------------------------------- /docs/releases.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: default 3 | title: Releases and Changelog 4 | redirect_from: 5 | - /changelog/ 6 | - /upgrading/ 7 | - /upgrading/changelog/ 8 | --- 9 | 10 | # Releases 11 | 12 | These are the release notes from `Uri`. We’ve tried to cover all changes, including backward compatible breaks from 4.0 through to the current stable release. If we’ve missed anything, feel free to create an issue, or send a pull request. 13 | 14 | {% for release in site.github.releases %} 15 | ## [{{ release.name }}]({{ release.html_url }}) - {{ release.published_at | date: "%Y-%m-%d" }} 16 | {{ release.body | markdownify }} 17 | {% endfor %} -------------------------------------------------------------------------------- /docs/schemes/1.0/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: default 3 | title: Uri objects scheme specific 4 | redirect_from: 5 | - /5.0/uri/ 6 | - /schemes/ 7 | --- 8 | 9 | Uri Schemes 10 | ======= 11 | 12 | [![Build Status](https://img.shields.io/travis/thephpleague/uri-schemes/master.svg?style=flat-square)](https://travis-ci.org/thephpleague/uri-schemes) 13 | [![Latest Version](https://img.shields.io/github/release/thephpleague/uri-schemes.svg?style=flat-square)](https://github.com/thephpleague/uri-components/schemes) 14 | 15 | This package contains concrete URI objects represented as immutable value object. Each URI object implements the `League\Uri\Interfaces\Uri` interface as defined in the [uri-interfaces package](https://github.com/thephpleague/uri-interfaces). 16 | 17 | The following URI objects are defined (order alphabetically): 18 | 19 | - [Data](/5.0/uri/schemes/data/) : represents a Data scheme URI 20 | - [File](/5.0/uri/schemes/file/) : represents a File scheme URI 21 | - [FTP](/5.0/uri/schemes/ftp/) : represents a FTP scheme URI 22 | - [Http](/5.0/uri/schemes/http/) : represents a HTTP/HTTPS scheme URI, implements PSR-7 `UriInterface` 23 | - [URI](/5.0/uri/schemes/uri/) : represents a generic RFC3986 URI object 24 | - [Ws](/5.0/uri/schemes/ws/) : represents a WS/WSS scheme URI 25 | 26 | 27 |

But you can easily create your own class to manage others scheme specific URI.

28 | 29 | To ease URI objects creation a [Factory](/5.0/uri/factory) is introduced as well as a [create](/5.0/uri/functions) function. 30 | 31 | System Requirements 32 | ------- 33 | 34 | You need: 35 | 36 | - **PHP >= 7.0.13** but the latest stable version of PHP is recommended 37 | 38 | While the library no longer requires out of the box the `intl` extension starting with version `1.2.0`, you should still require it if you are dealing with URIs containing non-ASCII host. Without it, URI creation or manipulation action will throw an exception if such hosts are used. 39 | 40 | Installation 41 | -------- 42 | 43 | ~~~ 44 | $ composer require league/uri-schemes 45 | ~~~ 46 | 47 | Dependencies 48 | ------- 49 | 50 | - [PSR-7](http://www.php-fig.org/psr/psr-7/) 51 | - [League Uri Interfaces](https://github.com/thephpleague/uri-interfaces) 52 | - [League Uri Parser](/5.0/parser/) -------------------------------------------------------------------------------- /docs/schemes/1.0/schemes/data.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: default 3 | title: Data URIs 4 | redirect_from: 5 | - /5.0/uri/schemes/data/ 6 | --- 7 | 8 | # Data URI 9 | 10 |

Starting with version 1.1.0 all URI objects are defined in the League\Uri namespace. The League\Uri\Schemes namespace is deprecated and will be removed in the next major release.

11 | 12 | To ease working with Data URIs, the library comes bundle with a URI specific Data class. This class follows [RFC2397](http://tools.ietf.org/html/rfc2397) 13 | 14 | ## Instantiation 15 | 16 | In addition to the defined named constructors, because data URI represents files, you can also instantiate a new data URI object from a file path using the `createFromPath` named constructor 17 | 18 | ~~~php 19 | getHost(); //return '' an empty string 41 | $uri->withHost('example.com'); // will throw an League\Uri\UriException 42 | ~~~ -------------------------------------------------------------------------------- /docs/schemes/1.0/schemes/file.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: default 3 | title: File URIs 4 | redirect_from: 5 | - /5.0/uri/schemes/file/ 6 | --- 7 | 8 | # File URI 9 | 10 |

Starting with version 1.1.0 all URI objects are defined in the League\Uri namespace. The League\Uri\Schemes namespace is deprecated and will be removed in the next major release.

11 | 12 | To ease working with File URIs, the library comes bundle with a URI specific File class. 13 | 14 | ## Instantiation 15 | 16 | In addition to the defined named constructors, because file path depends on the underlying OS, you can also instantiate a new File URI object from a file path using: 17 | 18 | - the `createFromUnixPath` named constructor 19 | - the `createFromWindowsPath` named constructor 20 | 21 | ~~~php 22 | withQuery('foo=bar'); // will throw an League\Uri\UriException 41 | ~~~ 42 | 43 | ## URI normalization 44 | 45 | If the host file is the empty string it will be converted to `localhost`. 46 | 47 | ~~~php 48 | Starting with version 1.1.0 all URI objects are defined in the League\Uri namespace. The League\Uri\Schemes namespace is deprecated and will be removed in the next major release.

11 | 12 | To ease working with FTP URIs, the library comes bundle with a URI specific FTP class `League\Uri\Ftp`. 13 | 14 | ## Validation 15 | 16 | The scheme of a FTP URI must be equal to `ftp` or be undefined. It can not contains a query and or a fragment component. 17 | 18 |

Adding contents to the fragment or query components throws an UriException exception

19 | 20 | ~~~php 21 | withQuery('p=1'); // will throw an League\Uri\UriException 27 | ~~~ 28 | 29 | Apart from the fragment, the query components and the scheme definition, the FTP URIs share the same [validation rules](/5.0/uri/schemes/http/#validation) as Http URIs. -------------------------------------------------------------------------------- /docs/schemes/1.0/schemes/http.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: default 3 | title: Http URIs 4 | redirect_from: 5 | - /5.0/uri/schemes/http/ 6 | --- 7 | 8 | # Http, Https URI 9 | 10 |

Starting with version 1.1.0 all URI objects are defined in the League\Uri namespace. The League\Uri\Schemes namespace is deprecated and will be removed in the next major release.

11 | 12 | ## Instantiation 13 | 14 | To work with Http URIs you can use the `League\Uri\Http` class. This class handles secure and insecure Http URI. In addition to the default named constructors, the `Http` class can be instantiated using the server variables. 15 | 16 | ~~~php 17 | The method only relies on the server's safe parameters to determine the current URI. If you are using the library behind a proxy the result may differ from your expectation as no $_SERVER['HTTP_X_*'] header is taken into account for security reasons.

26 | 27 | ## Validation 28 | 29 | The scheme of a HTTP(s) URI must be equal to `http`, `https` or be equal to `null`. 30 | 31 | ### Authority presence 32 | 33 | If a scheme is present and the scheme specific part of a Http URI is not empty the URI can not contain an empty authority. Thus, some Http URI modifications must be applied in a specific order to preserve the URI validation. 34 | 35 | ~~~php 36 | withHost('')->withScheme(''); 42 | // will throw an League\Uri\UriException 43 | // you can not remove the Host if a scheme is present 44 | ~~~ 45 | 46 | Instead you are required to proceed as below 47 | 48 | ~~~php 49 | withScheme('')->withHost(''); //displays "/" 55 | ~~~ 56 | 57 |

When an invalid URI object is created an UriException exception is thrown

58 | 59 | 60 | ### Path validity 61 | 62 | According to RFC3986, if an HTTP URI contains a non empty authority part, the URI path must be the empty string or absolute. Thus, some modification may trigger an UriException. 63 | 64 | ~~~php 65 | withPath('uri/schemes/http'); 71 | // will throw an League\Uri\UriException 72 | ~~~ 73 | 74 | Instead you are required to submit a absolute path 75 | 76 | ~~~php 77 | withPath('/uri/schemes/http'); // displays 'http://uri.thephpleague.com/uri/schemes/http' 83 | ~~~ 84 | 85 | Of note this does not mean that rootless path are forbidden, the following code is fine. 86 | 87 | ~~~php 88 | withPath('uri/schemes/http'); // displays 'uri/schemes/http?foo=bar' 94 | ~~~ 95 | 96 | ## Relation with PSR-7 97 | 98 | The `Http` class implements the PSR-7 `UriInterface` interface. This means that you can use this class anytime you need a PSR-7 compliant URI object. -------------------------------------------------------------------------------- /docs/schemes/1.0/schemes/uri.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: default 3 | title: Generic URIs 4 | redirect_from: 5 | - /5.0/uri/schemes/uri/ 6 | --- 7 | 8 | # Generic URIs 9 | 10 |

Starting with version 1.1.0 all URI objects are defined in the League\Uri namespace. The League\Uri\Schemes namespace is deprecated and will be removed in the next major release.

11 | 12 |

available since version 1.1.0

13 | 14 | A generic URI object `League\Uri\Uri` is introduced to represent any `RFC3986` compatible URI. This URI object wil only validate RFC3986 rules so depending on the URI scheme the returned URI may not be valid. 15 | 16 | ~~~php 17 | Starting with version 1.1.0 all URI objects are defined in the League\Uri namespace. The League\Uri\Schemes namespace is deprecated and will be removed in the next major release.

11 | 12 | To work with websockets URIs you can use the `League\Uri\Ws` class. This class handles secure and non secure websockets URI. 13 | 14 | ## Validation 15 | 16 | The scheme of a Websocket URI must be equal to `ws`, `wss` or be undefined. It can not contain a fragment component as per [RFC6455](https://tools.ietf.org/html/rfc6455#section-3). 17 | 18 |

Adding contents to the fragment component throws an UriException exception

19 | 20 | ~~~php 21 | { 2 | let contentHeaders= document.querySelectorAll("main h2[id]"); 3 | if (!document.querySelector('html').classList.contains('homepage') && contentHeaders) { 4 | const uri = new URL(location.href); 5 | contentHeaders.forEach((header) => { 6 | uri.hash = header.id; 7 | let link = document.createElement("a"); 8 | link.classList.add("header-permalink"); 9 | link.title = "Permalink"; 10 | link.href = uri.toString(); 11 | link.innerHTML = "¶"; 12 | header.appendChild(link); 13 | }); 14 | } 15 | 16 | let codeSnippet = document.querySelectorAll('.content .language-php.highlighter-rouge'); 17 | codeSnippet.forEach((snippet) => { 18 | let notification = document.createElement("div"); 19 | notification.classList.add('copy-snippet-notification', 'hidden', 'rounded', 'p-2'); 20 | snippet.appendChild(notification); 21 | 22 | let link = document.createElement("span"); 23 | link.classList.add("copy-snippet"); 24 | link.innerHTML = "copy 📋"; 25 | link.addEventListener('click', function (e) { 26 | let snippetParent = e.target.parentNode; 27 | let notification = snippetParent.querySelector('.copy-snippet-notification'); 28 | let content = snippetParent.querySelector('pre').textContent; 29 | try { 30 | navigator.clipboard.writeText(content); 31 | notification.innerHTML = 'Copied!'; 32 | notification.classList.add('bg-black'); 33 | notification.classList.remove('hidden'); 34 | setTimeout(() => { 35 | notification.classList.add('hidden'); 36 | notification.classList.remove('bg-black'); 37 | }, 500); 38 | } catch (err) { 39 | console.error('Failed to copy: ', err); 40 | notification.innerHTML = 'Copy failed!'; 41 | notification.classList.add('bg-red-800'); 42 | notification.classList.remove('hidden'); 43 | setTimeout(() => { 44 | notification.classList.add('hidden'); 45 | notification.classList.remove('bg-red-800'); 46 | }, 500); 47 | } 48 | }, false); 49 | snippet.appendChild(link); 50 | }); 51 | 52 | const dropDownList = document.getElementById('packageDropdownList'); 53 | const dropDownButton = document.getElementById('packageDropdown'); 54 | 55 | dropDownButton.addEventListener('click', () => { 56 | dropDownList.classList.toggle('hidden'); 57 | }); 58 | 59 | document.addEventListener('click', (event) => { 60 | if (!dropDownButton.contains(event.target) && !dropDownList.contains(event.target)) { 61 | dropDownList.classList.add('hidden'); 62 | } 63 | }); 64 | })(); 65 | 66 | 67 | -------------------------------------------------------------------------------- /docs/tailwind.config.js: -------------------------------------------------------------------------------- 1 | /** @type {import('tailwindcss').Config} */ 2 | module.exports = { 3 | content: ["./**/*.{html,js}"], 4 | theme: { 5 | extend: { 6 | fontFamily: { 7 | 'onest': ['"Onest"', 'sans-serif'], 8 | 'mono': ['"IBM Plex Mono"', 'mono', 'source-code-pro', 'ui-monospace', 'SFMono-Regular', 'Menlo', 'Monaco', 'Consolas', 'Liberation Mono', 'Courier New', 'monospace'] 9 | }, 10 | colors: { 11 | 'csv': { 12 | light: '#74D492', 13 | base: '#38C163', 14 | dark: '#278745' 15 | }, 16 | 'uri': { 17 | light: '#739AFF', 18 | base: '#376FFF', 19 | dark: '#274EB2' 20 | }, 21 | 'period': { 22 | light: '#FFDD77', 23 | base: '#FFC61D', 24 | dark: '#B28B14' 25 | }, 26 | 'dark': '#2C2C2C', 27 | 'light': '#808080' 28 | } 29 | }, 30 | }, 31 | plugins: [], 32 | } 33 | 34 | -------------------------------------------------------------------------------- /docs/uri/4.0/components/fragment.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: default 3 | title: The Fragment component 4 | redirect_from: 5 | - /4.0/components/fragment/ 6 | --- 7 | 8 | # The Fragment component 9 | 10 | The library provides a `Fragment` class to ease fragment creation and manipulation. 11 | 12 | ## Instantiation 13 | 14 | ### Using the default constructor. 15 | 16 | ~~~php 17 | getContent(); //display 'eur%20o' 34 | echo $fragment; //display 'eur%20o' 35 | echo $fragment->getUriComponent(); //display '#eur%20o' 36 | 37 | $fragment = new Fragment(); 38 | echo $fragment->getContent(); //display null 39 | echo $fragment; //display '' 40 | echo $fragment->getUriComponent(); //display '' 41 | 42 | $fragment = new Fragment(''); 43 | echo $fragment->getContent(); //display '' 44 | echo $fragment; //display '' 45 | echo $fragment->getUriComponent(); //display '#' 46 | ~~~ 47 | 48 |

If the submitted value is not a valid, an InvalidArgumentException exception is thrown.

49 | 50 |

On instantiation the submitted string is normalized using RFC3986 rules.

51 | 52 | ### Using a League Uri object 53 | 54 | You can acces a `League\Uri\Components\Fragment` object with an already instantiated League Uri object. 55 | 56 | ~~~php 57 | fragment; // $fragment is a League\Uri\Components\Fragment object; 63 | ~~~ 64 | 65 | ## Properties 66 | 67 | The component representation, comparison and manipulation is done using the package [UriPart](/uri/4.0/components/overview/#uri-part-interface) and the [Component](/uri/4.0/components/overview/#uri-component-interface) interfaces. 68 | 69 | ### Fragment::getDecoded 70 | 71 |

New since version 4.2

72 | 73 | Returns the decoded value of a fragment component 74 | 75 | ~~~php 76 | getUriComponent(); //displays '#%E2%82%AC' 90 | echo $component->getDecoded(); //displays '€' 91 | ~~~ -------------------------------------------------------------------------------- /docs/uri/4.0/components/pass.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: default 3 | title: The Pass component 4 | - /4.0/components/pass/ 5 | --- 6 | 7 | # The Pass component 8 | 9 | The library provides a `Pass` class to ease user creation and manipulation. 10 | 11 | ## Instantiation 12 | 13 | ### Using the default constructor. 14 | 15 | ~~~php 16 | getContent(); //display 'jo%40hn' 35 | echo $user; //display 'jo%40hn' 36 | echo $user->getUriComponent(); //display 'jo%40hn' 37 | 38 | $user = new Pass(); 39 | echo $user->getContent(); //display null 40 | echo $user; //display '' 41 | echo $user->getUriComponent(); //display '' 42 | ~~~ 43 | 44 |

If the submitted value is not a valid an InvalidArgumentException exception is thrown.

45 | 46 |

On instantiation the submitted string is normalized using RFC3986 rules.

47 | 48 | ### Using a League Uri object 49 | 50 | You can access a `Pass` object with an already instantiated `Uri` object. 51 | 52 | ~~~php 53 | pass; // $user is a League\Uri\Components\Pass object; 59 | ~~~ 60 | 61 | ## Properties and Methods 62 | 63 | The component representation, comparison and manipulation is done using the package [UriPart](/uri/4.0/components/overview/#uri-part-interface) and the [Component](/uri/4.0/components/overview/#uri-component-interface) interfaces methods. 64 | 65 | ### Pass::getDecoded 66 | 67 |

New in version 4.2

68 | 69 | ~~~php 70 | getContent(); // display 'frag%40ment' 85 | $user->getDecoded(); // display 'frag@ment' 86 | ~~~ -------------------------------------------------------------------------------- /docs/uri/4.0/components/port.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: default 3 | title: The Port component 4 | - /4.0/components/port/ 5 | --- 6 | 7 | # The Port component 8 | 9 | The library provides a `Port` class to ease port manipulation. 10 | 11 | ## Instantiation 12 | 13 | ### Using the default constructor. 14 | 15 | ~~~php 16 | getContent(); //return (int) 443 36 | echo $port; //display '443' 37 | echo $port->getUriComponent(); //display ':443' 38 | 39 | $string_port = new Port('443'); 40 | $string_port->getContent(); //return (int) 443 41 | echo $string_port; //display '443' 42 | echo $string_port->getUriComponent(); //display ':443' 43 | 44 | $empty_port = new Port(); 45 | $empty_port->getContent(); //return null 46 | echo $empty_port; //display '' 47 | echo $empty_port->getUriComponent(); //display '' 48 | ~~~ 49 | 50 |

If the submitted value is not a valid port number an InvalidArgumentException exception is thrown.

51 | 52 |

On instantiation the submitted string is normalized using RFC3986 rules.

53 | 54 | ### Using a League Uri object 55 | 56 | You can acces a `Port` object with an already instantiated League `Uri` object. 57 | 58 | ~~~php 59 | port; // $port is a League\Uri\Components\Port object; 65 | ~~~ 66 | 67 | ## Properties and Methods 68 | 69 | The component representation, comparison and manipulation is done using the package [UriPart](/uri/4.0/components/overview/#uri-part-interface) and the [Component](/uri/4.0/components/overview/#uri-component-interface) interfaces methods. 70 | 71 | ### Port::toInt 72 | 73 |

Since version 4.2 this method is deprecated please use Port::getContent instead.

74 | 75 | Return an integer if the port was defined or `null` otherwise. 76 | 77 | ~~~php 78 | toInt(); //return (int) 81 84 | 85 | $empty_port = new Port(); 86 | $empty_port->toInt(); //return null 87 | ~~~ -------------------------------------------------------------------------------- /docs/uri/4.0/components/scheme.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: default 3 | title: The Scheme component 4 | - /4.0/components/scheme/ 5 | --- 6 | 7 | # The Scheme component 8 | 9 | The library provides a `Scheme` class to ease scheme creation and manipulation. 10 | 11 | ## Instantiation 12 | 13 | ### Using the default constructor. 14 | 15 | ~~~php 16 | getContent(); //display 'ftp' 35 | echo $scheme; //display 'ftp' 36 | echo $scheme->getUriComponent(); //display 'ftp:' 37 | 38 | $scheme = new Scheme(); 39 | echo $scheme->getContent(); //display null 40 | echo $scheme; //display '' 41 | echo $scheme->getUriComponent(); //display '' 42 | ~~~ 43 | 44 |

If the submitted value is not a valid an InvalidArgumentException exception is thrown.

45 | 46 |

On instantiation the submitted string is normalized using RFC3986 rules.

47 | 48 | ### Using a League Uri object 49 | 50 | You can access a `Scheme` object with an already instantiated Uri object. 51 | 52 | ~~~php 53 | scheme; // $scheme is a League\Uri\Components\Scheme object; 59 | ~~~ 60 | 61 | ## Properties and Methods 62 | 63 | The component representation, comparison and manipulation is done using the package [UriPart](/uri/4.0/components/overview/#uri-part-interface) and the [Component](/uri/4.0/components/overview/#uri-component-interface) interfaces. -------------------------------------------------------------------------------- /docs/uri/4.0/components/user.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: default 3 | title: The User component 4 | - /4.0/components/user/ 5 | --- 6 | 7 | # The User component 8 | 9 | The library provides a `User` class to ease user creation and manipulation. 10 | 11 | ## Instantiation 12 | 13 | ### Using the default constructor. 14 | 15 | ~~~php 16 | getContent(); //display 'john' 35 | echo $user; //display 'john' 36 | echo $user->getUriComponent(); //display 'john' 37 | 38 | $user = new User(); 39 | echo $user->getContent(); //display null 40 | echo $user; //display '' 41 | echo $user->getUriComponent(); //display '' 42 | ~~~ 43 | 44 |

If the submitted value is not a valid an InvalidArgumentException exception is thrown.

45 | 46 |

On instantiation the submitted string is normalized using RFC3986 rules.

47 | 48 | ### Using a League Uri object 49 | 50 | You can access a `User` object with an already instantiated `Uri` object. 51 | 52 | ~~~php 53 | user; // $user is a League\Uri\Components\User object; 59 | ~~~ 60 | 61 | ## Properties and Methods 62 | 63 | The component representation, comparison and manipulation is done using the package [UriPart](/uri/4.0/components/overview/#uri-part-interface) and the [Component](/uri/4.0/components/overview/#uri-component-interface) interfaces methods. 64 | 65 | ### User::getDecoded 66 | 67 |

New in version 4.2

68 | 69 | ~~~php 70 | getContent(); // display 'frag%3Ament' 85 | $user->getDecoded(); // display 'frag:ment' 86 | ~~~ -------------------------------------------------------------------------------- /docs/uri/4.0/definitions.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: default 3 | title: URIs as Value Objects 4 | redirect_from: 5 | - /4.0/definitions/ 6 | --- 7 | 8 | # Terminology 9 | 10 | The library models URIs and URIs components as [immutable](http://en.wikipedia.org/wiki/Immutable_object) [value objects](http://en.wikipedia.org/wiki/Value_object). 11 | 12 | ## URI, URL and URN 13 | 14 | Often you will encounter in the public spaces the following terms: 15 | 16 | - URI which stands for *Uniform Resource Identifier*; 17 | - URL which stands for *Uniform Resource Locator*; 18 | - URN which stands for *Uniform Resource Name*; 19 | 20 | But according to [RFC3986](http://tools.ietf.org/html/rfc3986#section-1.1.3) 21 | 22 | > Future specifications and related documentation should use the general term "URI" rather than the more restrictive terms "URL" and "URN". 23 | 24 | This is the reason why you will only encounter the term URI throughout the documentation to highlight the fact that the package is not limited to HTTP(S) URI or any other scheme specific URI. 25 | 26 | ## Value Objects 27 | 28 | > The term "Uniform Resource Locator" (URL) refers to the subset of URIs that, in addition to identifying a resource, provide a means of locating the resource by describing its primary access mechanism. [RFC3986](http://tools.ietf.org/html/rfc3986#section-1.1.3) 29 | 30 | This means that an URI is like a street address, if you omit or change even a single character in it, you won't be able to clearly identify what your are looking for. This means that the equality between instances of URI objects is not based on identity but rather on content. 31 | 32 | ~~~php 33 | __toString() === $uri2->__toString(); //return true; 41 | //even if their identities are different 42 | $uri === $uri2; //return false; 43 | ~~~ 44 | 45 | ## Immutability 46 | 47 | To ensure the integrity of the value, when a component is altered instead of modifying its current value, we return a new component with the changed value. This practice is called immutability. 48 | 49 | ~~~php 50 | withPort(82); 56 | echo $uri1; //still displays "http://example.com:81/toto" 57 | echo $uri2; //displays "http://example.com:82/toto" 58 | ~~~ 59 | 60 | Using these concepts, the package enforces stronger and efficient manipulation of URIs and URI components. -------------------------------------------------------------------------------- /docs/uri/4.0/installation.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: default 3 | title: Installation 4 | redirect_from: 5 | - /4.0/installation/ 6 | --- 7 | 8 | # Installation 9 | 10 | ## System Requirements 11 | 12 | * **PHP >= 5.5.9** but the latest stable version of PHP is recommended; 13 | * `mbstring` extension; 14 | * `intl` extension; 15 | 16 | ## Install 17 | 18 | The library is available on [Packagist][] and should be installed using [Composer][]. This can be done by running the following command on a composer installed box: 19 | 20 | ~~~ 21 | $ composer require league/uri 22 | ~~~ 23 | 24 | Most modern frameworks will include Composer out of the box, but ensure the following file is included: 25 | 26 | ~~~php 27 | If a new instance can not be created an InvalidArgumentException exception is thrown

15 | 16 | ### From a string 17 | 18 | ~~~php 19 | 55 | It is not recommend to instantiate an URI object using the default constructor. It is easier to always use the documentated named constructors since each URI object requires a specific set of URI components objects. 56 | 57 | 58 | ## Generic URI Handling 59 | 60 | Out of the box the library provides the following specialized classes: 61 | 62 | - `League\Uri\Schemes\Data` which deals with [Data URIs](/uri/4.0/uri/schemes/data-uri/); 63 | - `League\Uri\Schemes\Ftp` which deals with the [FTP URIs](/uri/4.0/uri/schemes/ftp/); 64 | - `League\Uri\Schemes\Http` which deals with [HTTP and HTTPS URIs](/uri/4.0/uri/schemes/http/); 65 | - `League\Uri\Schemes\Ws` which deals with [WS and WSS (websocket) URIs](/uri/4.0/uri/schemes/ws/); 66 | 67 |

But you can easily create your own class to manage others scheme specific URI.

68 | 69 | ## URI normalization 70 | 71 | Out of the box the package normalizes any given URI according to the non destructive rules of RFC3986. 72 | 73 | These non destructives rules are: 74 | 75 | - scheme and host components are lowercased; 76 | - query, path, fragment components are URI encoded if needed; 77 | - the port number is removed from the URI string representation if the standard port is used; 78 | 79 | ~~~php 80 | getHost(); //return '' an empty string 39 | $uri->withHost('example.com'); //thrown an InvalidArgumentException 40 | ~~~ 41 | 42 | ## Properties 43 | 44 | The data URI class uses the [DataPath](/uri/4.0/components/datauri-path/) class to represents its path. using PHP's magic `__get` method you can access the object path and get more informations about the underlying file. 45 | 46 | ~~~php 47 | path->getMediaType(); //display 'text/plain;charset=us-ascii' 54 | echo $uri->path->getMimeType(); //display 'text/plain' 55 | echo $uri->path->getParameters(); //display 'charset=us-ascii' 56 | echo $uri->path->getData(); //display 'Hello%20World%21' 57 | $uri->path->isBinaryData(); //returns false 58 | $fileObject = $uri->path->save('/path/where/to/save/data', 'w'); 59 | //$fileObject is a \SplFileObject reference 60 | ~~~ -------------------------------------------------------------------------------- /docs/uri/4.0/uri/schemes/ftp.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: default 3 | title: Ftp URIs 4 | redirect_from: 5 | - /4.0/uri/schemes/ftp/ 6 | --- 7 | 8 | # Ftp URI 9 | 10 | To ease working with FTP URIs, the library comes bundle with a URI specific FTP class `League\Uri\Schemes\Ftp`. 11 | 12 | ## Validation 13 | 14 | A FTP URI must contain the `ftp` scheme. It can not contains a query and or a fragment component. 15 | 16 |

Adding contents to the fragment or query components throws an InvalidArgumentException exception

17 | 18 | ~~~php 19 | withQuery('p=1'); //throw an InvalidArgumentException - a query component was given 25 | ~~~ 26 | 27 |

Starting with version 4.2 schemeless FTP Uri will no longer trigger an InvalidArgumentException exception

28 | 29 | Apart from the fragment and the query components, the Ftp URIs share the same [host validation limitation](/uri/4.0/uri/schemes/http/#validation) as Http URIs. 30 | 31 | ## Properties 32 | 33 | The FTP URI class uses the specialized [HierarchicalPath](/uri/4.0/components/hierarchical-path/) class to represents its path. using PHP's magic `__get` method you can access the object path and get more informations about the underlying path. 34 | 35 | ~~~php 36 | path->getBasename(); //display 'image.png;type=i' 42 | echo $uri->path->getDirname(); //display '/path/to' 43 | echo $uri->path->getExtension(); //display 'png' 44 | $uri->path->getSegments(); //returns an array representation of the path segments 45 | ~~~ -------------------------------------------------------------------------------- /docs/uri/4.0/uri/schemes/http.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: default 3 | title: Http URIs 4 | redirect_from: 5 | - /4.0/uri/schemes/http/ 6 | --- 7 | 8 | # Http, Https URI 9 | 10 | ## Instantiation 11 | 12 | To work with Http URIs you can use the `League\Uri\Schemes\Http` class. This class handles secure and insecure Http URI. In addition to the [defined named constructors](/uri/4.0/uri/instantiation/#uri-instantiation), the `Http` class can be instantiated using the server variables. 13 | 14 | ~~~php 15 | The method only relies on the server's safe parameters to determine the current URI. If you are using the library behind a proxy the result may differ from your expectation as no $_SERVER['HTTP_X_*'] header is taken into account for security reasons.

24 | 25 | ## Validation 26 | 27 | If a scheme is present and the scheme specific part of a Http URI is not empty the URI can not contain an empty authority. Thus, some Http URI modifications must be applied in a specific order to preserve the URI validation. 28 | 29 | ~~~php 30 | withHost('')->withScheme('')->__toString(); 36 | // will throw an InvalidArgumentException 37 | // you can not remove the Host if a scheme is present 38 | ~~~ 39 | 40 | Instead you are required to proceed as below 41 | 42 | ~~~php 43 | withScheme('')->withHost('')->__toString(); //displays "/" 49 | ~~~ 50 | 51 |

When an invalid URI object is created an InvalidArgumentException exception is thrown

52 | 53 | ## Relation with PSR-7 54 | 55 | The `Http` class is compliant with PSR-7 `UriInterface` interface. This means that you can use this class anytime you need a PSR-7 compliant URI object. 56 | 57 | ## Properties 58 | 59 | The Http URI class uses the specialized [HierarchicalPath](/uri/4.0/components/hierarchical-path/) class to represents its path. using PHP's magic `__get` method you can access the object path and get more informations about the underlying path. 60 | 61 | ~~~php 62 | path->getBasename(); //display 'http.md' 68 | echo $uri->path->getDirname(); //display '/uri/schemes' 69 | echo $uri->path->getExtension(); //display 'md' 70 | $uri->path->getSegments(); //returns an array representation of the path segments 71 | ~~~ 72 | -------------------------------------------------------------------------------- /docs/uri/4.0/uri/schemes/ws.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: default 3 | title: Websocket URIs 4 | redirect_from: 5 | - /4.0/uri/schemes/ws/ 6 | --- 7 | 8 | # Websockets URI 9 | 10 | To work with websockets URIs you can use the `League\Uri\Schemes\Ws` class. 11 | This class handles secure and non secure websockets URI. 12 | 13 | ## Validation 14 | 15 | Websockets URIs must contain a `ws` or the `wss` scheme. It can not contain a fragment component as per [RFC6455](https://tools.ietf.org/html/rfc6455#section-3). 16 | 17 |

Adding contents to the fragment component throws an InvalidArgumentException exception

18 | 19 | ~~~php 20 | Starting with version 4.2 schemeless FTP Uri will no longer trigger an InvalidArgumentException exception

31 | 32 | ## Properties 33 | 34 | Websockets URIs objects uses the specialized [HierarchicalPath](/uri/4.0/components/hierarchical-path/) class to represents its path. using PHP's magic `__get` method you can access the object path and get more informations about the underlying path. 35 | 36 | ~~~php 37 | path->getBasename(); //display '/path' 43 | echo $uri->path->getDirname(); //display 'to' 44 | echo $uri->path->getExtension(); //display '' 45 | $uri->path->getSegments(); //returns an array representation of the path segments 46 | ~~~ -------------------------------------------------------------------------------- /docs/uri/5.0/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: default 3 | title: Uri 4 | --- 5 | 6 | # Overview 7 | 8 | [![Author](//img.shields.io/badge/author-@nyamsprod-blue.svg?style=flat-square)](https://twitter.com/nyamsprod) 9 | [![Source Code](//img.shields.io/badge/source-league/uri-blue.svg?style=flat-square)](https://github.com/thephpleague/uri) 10 | [![Latest Stable Version](//img.shields.io/github/release/thephpleague/uri.svg?style=flat-square)](https://packagist.org/packages/league/uri) 11 | [![Software License](//img.shields.io/badge/license-MIT-brightgreen.svg?style=flat-square)](LICENSE.md) 12 | [![Build Status](//img.shields.io/travis/thephpleague/uri/master.svg?style=flat-square)](https://travis-ci.org/thephpleague/uri) 13 | [![Total Downloads](//img.shields.io/packagist/dt/league/uri.svg?style=flat-square)](https://packagist.org/packages/league/uri) 14 | 15 | The library is a **meta package** which provides simple and intuitive classes to parse, validate and manipulate URIs and their components in PHP. 16 | 17 |

We no longer recommend installing this package directly.

18 | 19 | ## System Requirements 20 | 21 | * **PHP >= 7.0.13** but the latest stable version of PHP is recommended; 22 | * `mbstring` extension; 23 | * `intl` extension; 24 | 25 | ## Install 26 | 27 | The package is a metapackage that aggregates all components related to processing and manipulating URI in PHP; in most cases, you will want a subset, and these may be installed separately. 28 | 29 | The following components are part of the metapackage: 30 | 31 | - [League Uri Parser](/parser/1.0/) 32 | - [League Uri Schemes](/schemes/1.0/) 33 | - [League Uri Components](/components/1.0/) 34 | - [League Uri Manipulations](/manipulations/1.0/) 35 | - [League Uri Hostname Parser](/domain-parser/1.0/) *since version 5.2 in replacement of PHP Domain Parser version 3.0* 36 | 37 | The primary use case for installing the entire suite is when upgrading from a version 4 release. 38 | 39 | If you decide you still want to install the entire [suite]( https://packagist.org/packages/league/uri) use [Composer](https://getcomposer.org/). This can be done by running the following command on a composer installed box: 40 | 41 | ~~~bash 42 | $ composer require league/uri 43 | ~~~ 44 | 45 | Most modern frameworks will include Composer out of the box, but ensure the following file is included: 46 | 47 | ~~~php 48 | 13 | [![Build](https://github.com/thephpleague/uri/workflows/build/badge.svg)](https://github.com/thephpleague/uri/actions?query=workflow%3A%22build%22) 14 | [![Total Downloads](//img.shields.io/packagist/dt/league/uri.svg?style=flat-square)](https://packagist.org/packages/league/uri) 15 | 16 | This package contains concrete objects to ease creating and manipulating URI objects represented as immutable value objects. 17 | 18 | The following URI objects are defined (order alphabetically): 19 | 20 | - [Http](/uri/6.0/psr7/) : represents an URI object implementing PSR-7 `UriInterface` 21 | - [URI](/uri/6.0/rfc3986/) : represents a generic RFC3986 URI object 22 | 23 | To ease URI objects creation and manipulation, the following helper classes are added (order alphabetically): 24 | 25 | - the [UriInfo](/uri/6.0/info) : retrieves RFC3986 related info from an URI object; 26 | - the [UriResolver](/uri/6.0/resolver-relativizer) : resolves or relativizes an URI against a base URI; 27 | - the [UriString](/uri/6.0/parser-builder) : parses or builds an URI string into or from its components; 28 | - the [UriTemplate](/uri/6.0/uri-template) : expands an URI template string into an URI object; 29 | 30 | System Requirements 31 | ------- 32 | 33 | You need **PHP >= 7.2** but the latest stable version of PHP is recommended. 34 | 35 | In order to handle IDN host you are required to also install the `intl` extension otherwise an exception will be thrown when attempting to validate such host. 36 | 37 | In order to create Data URI from a filepath, since version `6.2`, you are required to also install the `fileinfo` extension otherwise an exception will be thrown. 38 | 39 | Installation 40 | -------- 41 | 42 | ~~~ 43 | $ composer require league/uri:^6.0 44 | ~~~ 45 | 46 | Dependencies 47 | ------- 48 | 49 | - [League Uri Interfaces](https://github.com/thephpleague/uri-interfaces) 50 | - [PSR-7](http://www.php-fig.org/psr/psr-7/) 51 | -------------------------------------------------------------------------------- /docs/uri/6.0/resolver-relativizer.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: default 3 | title: URI resolver - relativizer 4 | --- 5 | 6 | URI resolver - relativizer 7 | ======= 8 | 9 | The `League\Uri\UriResolver` class enable resolving or relativizing a URI object based on a base URI. 10 | 11 | ## Resolving a relative URI 12 | 13 | The `UriResolver::resolve` public static method provides the mean for resolving an URI as a browser would for a relative URI. When performing URI resolution the returned URI is normalized according to RFC3986 rules. The uri to resolved must be another Uri object. 14 | 15 | ~~~php 16 | 15 | [![Total Downloads](https://img.shields.io/packagist/dt/league/uri.svg?style=flat-square)](https://packagist.org/packages/league/uri) 16 | 17 | This package contains features and capabilities to ease manipulating URIs. 18 | 19 | `league\uri` allows straightforward URI manipulation and exposes a complete API around 20 | URI creation and modification using the [UriTemplate](/uri/7.0/uri-template) and the [URI](/uri/7.0/rfc3986/) class. 21 | The latter represents a generic RFC3986 compliant URI object with support for RFC3987 IDN host. 22 | 23 | For interoperability, the package also provide [PSR-7 and PSR-17](/uri/7.0/psr-compliance/) compliant implementations 24 | around URI access and creation. 25 | 26 | System Requirements 27 | ------- 28 | 29 | You need **PHP >= 8.1** but the latest stable version of PHP is recommended. 30 | 31 | Handling of an IDN host requires the presence of the `intl` 32 | extension or a polyfill for the `intl` IDN functions like the 33 | `symfony/polyfill-intl-idn` otherwise an exception will be thrown 34 | when attempting to validate or interact with such a host. 35 | 36 | IPv4 conversion requires at least one of the following: 37 | 38 | - the `GMP` extension, 39 | - the `BCMatch` extension or 40 | - a `64-bits` PHP version 41 | 42 | otherwise an exception will be thrown when attempting to convert a host 43 | as an IPv4 address. 44 | 45 | In order to create Data URI from the content of a file you are required to also 46 | install the `fileinfo` extension otherwise an exception will be thrown. 47 | 48 | To convert a URI into an HTML anchor tag you need to have the `ext-dom` extension 49 | installed in your system. 50 | 51 | Installation 52 | -------- 53 | 54 | ~~~ 55 | $ composer require league/uri:^7.0 56 | ~~~ 57 | 58 | Dependencies 59 | ------- 60 | 61 | - [League Uri Interfaces](https://github.com/thephpleague/uri-interfaces) 62 | - [PSR-7](http://www.php-fig.org/psr/psr-7/) 63 | -------------------------------------------------------------------------------- /interfaces/Contracts/AuthorityInterface.php: -------------------------------------------------------------------------------- 1 | 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 | declare(strict_types=1); 13 | 14 | namespace League\Uri\Contracts; 15 | 16 | use League\Uri\Exceptions\MissingFeature; 17 | use League\Uri\Exceptions\SyntaxError; 18 | use Stringable; 19 | 20 | interface AuthorityInterface extends UriComponentInterface 21 | { 22 | /** 23 | * Returns the host component of the authority. 24 | */ 25 | public function getHost(): ?string; 26 | 27 | /** 28 | * Returns the port component of the authority. 29 | */ 30 | public function getPort(): ?int; 31 | 32 | /** 33 | * Returns the user information component of the authority. 34 | */ 35 | public function getUserInfo(): ?string; 36 | 37 | /** 38 | * Returns an associative array containing all the Authority components. 39 | * 40 | * The returned a hashmap similar to PHP's parse_url return value 41 | * 42 | * @link https://tools.ietf.org/html/rfc3986 43 | * 44 | * @return array{user: ?string, pass : ?string, host: ?string, port: ?int} 45 | */ 46 | public function components(): array; 47 | 48 | /** 49 | * Return an instance with the specified host. 50 | * 51 | * This method MUST retain the state of the current instance, and return 52 | * an instance that contains the specified host. 53 | * 54 | * A null value provided for the host is equivalent to removing the host 55 | * information. 56 | * 57 | * @throws SyntaxError for invalid component or transformations 58 | * that would result in an object in invalid state. 59 | * @throws MissingFeature for component or transformations 60 | * requiring IDN support when IDN support is not present 61 | * or misconfigured. 62 | */ 63 | public function withHost(Stringable|string|null $host): self; 64 | 65 | /** 66 | * Return an instance with the specified port. 67 | * 68 | * This method MUST retain the state of the current instance, and return 69 | * an instance that contains the specified port. 70 | * 71 | * A null value provided for the port is equivalent to removing the port 72 | * information. 73 | * 74 | * @throws SyntaxError for invalid component or transformations 75 | * that would result in an object in invalid state. 76 | */ 77 | public function withPort(?int $port): self; 78 | 79 | /** 80 | * Return an instance with the specified user information. 81 | * 82 | * This method MUST retain the state of the current instance, and return 83 | * an instance that contains the specified user information. 84 | * 85 | * Password is optional, but the user information MUST include the 86 | * user; a null value for the user is equivalent to removing user 87 | * information. 88 | * 89 | * @throws SyntaxError for invalid component or transformations 90 | * that would result in an object in invalid state. 91 | */ 92 | public function withUserInfo(Stringable|string|null $user, Stringable|string|null $password = null): self; 93 | } 94 | -------------------------------------------------------------------------------- /interfaces/Contracts/Conditionable.php: -------------------------------------------------------------------------------- 1 | 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 | declare(strict_types=1); 13 | 14 | namespace League\Uri\Contracts; 15 | 16 | interface Conditionable 17 | { 18 | /** 19 | * Apply the callback if the given "condition" is (or resolves to) true. 20 | * 21 | * @param (callable(static): bool)|bool $condition 22 | * @param callable(static): (static|null) $onSuccess 23 | * @param ?callable(static): (static|null) $onFail 24 | */ 25 | public function when(callable|bool $condition, callable $onSuccess, ?callable $onFail = null): static; 26 | } 27 | -------------------------------------------------------------------------------- /interfaces/Contracts/DataPathInterface.php: -------------------------------------------------------------------------------- 1 | 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 | declare(strict_types=1); 13 | 14 | namespace League\Uri\Contracts; 15 | 16 | use SplFileObject; 17 | use Stringable; 18 | 19 | interface DataPathInterface extends PathInterface 20 | { 21 | /** 22 | * Retrieve the data mime type associated to the URI. 23 | * 24 | * If no mimetype is present, this method MUST return the default mimetype 'text/plain'. 25 | * 26 | * @see http://tools.ietf.org/html/rfc2397#section-2 27 | */ 28 | public function getMimeType(): string; 29 | 30 | /** 31 | * Retrieve the parameters associated with the Mime Type of the URI. 32 | * 33 | * If no parameters is present, this method MUST return the default parameter 'charset=US-ASCII'. 34 | * 35 | * @see http://tools.ietf.org/html/rfc2397#section-2 36 | */ 37 | public function getParameters(): string; 38 | 39 | /** 40 | * Retrieve the mediatype associated with the URI. 41 | * 42 | * If no mediatype is present, this method MUST return the default parameter 'text/plain;charset=US-ASCII'. 43 | * 44 | * @see http://tools.ietf.org/html/rfc2397#section-3 45 | * 46 | * @return string The URI scheme. 47 | */ 48 | public function getMediaType(): string; 49 | 50 | /** 51 | * Retrieves the data string. 52 | * 53 | * Retrieves the data part of the path. If no data part is provided return 54 | * an empty string 55 | */ 56 | public function getData(): string; 57 | 58 | /** 59 | * Tells whether the data is binary safe encoded. 60 | */ 61 | public function isBinaryData(): bool; 62 | 63 | /** 64 | * Save the data to a specific file. 65 | */ 66 | public function save(string $path, string $mode = 'w'): SplFileObject; 67 | 68 | /** 69 | * Returns an instance where the data part is base64 encoded. 70 | * 71 | * This method MUST retain the state of the current instance, and return 72 | * an instance where the data part is base64 encoded 73 | */ 74 | public function toBinary(): self; 75 | 76 | /** 77 | * Returns an instance where the data part is url encoded following RFC3986 rules. 78 | * 79 | * This method MUST retain the state of the current instance, and return 80 | * an instance where the data part is url encoded 81 | */ 82 | public function toAscii(): self; 83 | 84 | /** 85 | * Return an instance with the specified mediatype parameters. 86 | * 87 | * This method MUST retain the state of the current instance, and return 88 | * an instance that contains the specified mediatype parameters. 89 | * 90 | * Users must provide encoded characters. 91 | * 92 | * An empty parameters value is equivalent to removing the parameter. 93 | */ 94 | public function withParameters(Stringable|string $parameters): self; 95 | } 96 | -------------------------------------------------------------------------------- /interfaces/Contracts/FragmentInterface.php: -------------------------------------------------------------------------------- 1 | 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 | declare(strict_types=1); 13 | 14 | namespace League\Uri\Contracts; 15 | 16 | /** 17 | * @method self normalize() returns the normalized string representation of the component 18 | */ 19 | interface FragmentInterface extends UriComponentInterface 20 | { 21 | /** 22 | * Returns the decoded fragment. 23 | */ 24 | public function decoded(): ?string; 25 | } 26 | -------------------------------------------------------------------------------- /interfaces/Contracts/HostInterface.php: -------------------------------------------------------------------------------- 1 | 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 | declare(strict_types=1); 13 | 14 | namespace League\Uri\Contracts; 15 | 16 | /** 17 | * @method string|null encoded() returns RFC3986 encoded host 18 | */ 19 | interface HostInterface extends UriComponentInterface 20 | { 21 | /** 22 | * Returns the ascii representation. 23 | */ 24 | public function toAscii(): ?string; 25 | 26 | /** 27 | * Returns the unicode representation. 28 | */ 29 | public function toUnicode(): ?string; 30 | 31 | /** 32 | * Returns the IP version. 33 | * 34 | * If the host is a not an IP this method will return null 35 | */ 36 | public function getIpVersion(): ?string; 37 | 38 | /** 39 | * Returns the IP component If the Host is an IP address. 40 | * 41 | * If the host is a not an IP this method will return null 42 | */ 43 | public function getIp(): ?string; 44 | 45 | /** 46 | * Tells whether the host is a domain name. 47 | */ 48 | public function isDomain(): bool; 49 | 50 | /** 51 | * Tells whether the host is an IP Address. 52 | */ 53 | public function isIp(): bool; 54 | 55 | /** 56 | * Tells whether the host is a registered name. 57 | */ 58 | public function isRegisteredName(): bool; 59 | } 60 | -------------------------------------------------------------------------------- /interfaces/Contracts/IpHostInterface.php: -------------------------------------------------------------------------------- 1 | 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 | declare(strict_types=1); 13 | 14 | namespace League\Uri\Contracts; 15 | 16 | interface IpHostInterface extends HostInterface 17 | { 18 | /** 19 | * Tells whether the host is an IPv4 address. 20 | */ 21 | public function isIpv4(): bool; 22 | 23 | /** 24 | * Tells whether the host is an IPv6 address. 25 | */ 26 | public function isIpv6(): bool; 27 | 28 | /** 29 | * Tells whether the host is an IPv6 address. 30 | */ 31 | public function isIpFuture(): bool; 32 | 33 | /** 34 | * Tells whether the host has a ZoneIdentifier. 35 | * 36 | * @see http://tools.ietf.org/html/rfc6874#section-4 37 | */ 38 | public function hasZoneIdentifier(): bool; 39 | 40 | /** 41 | * Returns a host without its zone identifier according to RFC6874. 42 | * 43 | * This method MUST retain the state of the current instance, and return 44 | * an instance without the host zone identifier according to RFC6874 45 | * 46 | * @see http://tools.ietf.org/html/rfc6874#section-4 47 | */ 48 | public function withoutZoneIdentifier(): self; 49 | } 50 | -------------------------------------------------------------------------------- /interfaces/Contracts/PathInterface.php: -------------------------------------------------------------------------------- 1 | 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 | declare(strict_types=1); 13 | 14 | namespace League\Uri\Contracts; 15 | 16 | use League\Uri\Exceptions\SyntaxError; 17 | 18 | /** 19 | * @method static normalize() returns the normalized string representation of the component 20 | */ 21 | interface PathInterface extends UriComponentInterface 22 | { 23 | /** 24 | * Returns the decoded path. 25 | */ 26 | public function decoded(): string; 27 | 28 | /** 29 | * Tells whether the path is absolute or relative. 30 | */ 31 | public function isAbsolute(): bool; 32 | 33 | /** 34 | * Tells whether the path has a trailing slash. 35 | */ 36 | public function hasTrailingSlash(): bool; 37 | 38 | /** 39 | * Returns an instance without dot segments. 40 | * 41 | * This method MUST retain the state of the current instance, and return 42 | * an instance that contains the path component normalized by removing 43 | * the dot segment. 44 | * 45 | * @throws SyntaxError for invalid component or transformations 46 | * that would result in a object in invalid state. 47 | */ 48 | public function withoutDotSegments(): self; 49 | 50 | /** 51 | * Returns an instance with a leading slash. 52 | * 53 | * This method MUST retain the state of the current instance, and return 54 | * an instance that contains the path component with a leading slash 55 | * 56 | * @throws SyntaxError for invalid component or transformations 57 | * that would result in a object in invalid state. 58 | */ 59 | public function withLeadingSlash(): self; 60 | 61 | /** 62 | * Returns an instance without a leading slash. 63 | * 64 | * This method MUST retain the state of the current instance, and return 65 | * an instance that contains the path component without a leading slash 66 | * 67 | * @throws SyntaxError for invalid component or transformations 68 | * that would result in a object in invalid state. 69 | */ 70 | public function withoutLeadingSlash(): self; 71 | 72 | /** 73 | * Returns an instance with a trailing slash. 74 | * 75 | * This method MUST retain the state of the current instance, and return 76 | * an instance that contains the path component with a trailing slash 77 | * 78 | * @throws SyntaxError for invalid component or transformations 79 | * that would result in a object in invalid state. 80 | */ 81 | public function withTrailingSlash(): self; 82 | 83 | /** 84 | * Returns an instance without a trailing slash. 85 | * 86 | * This method MUST retain the state of the current instance, and return 87 | * an instance that contains the path component without a trailing slash 88 | * 89 | * @throws SyntaxError for invalid component or transformations 90 | * that would result in a object in invalid state. 91 | */ 92 | public function withoutTrailingSlash(): self; 93 | } 94 | -------------------------------------------------------------------------------- /interfaces/Contracts/PortInterface.php: -------------------------------------------------------------------------------- 1 | 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 | declare(strict_types=1); 13 | 14 | namespace League\Uri\Contracts; 15 | 16 | interface PortInterface extends UriComponentInterface 17 | { 18 | /** 19 | * Returns the integer representation of the Port. 20 | */ 21 | public function toInt(): ?int; 22 | } 23 | -------------------------------------------------------------------------------- /interfaces/Contracts/UriAccess.php: -------------------------------------------------------------------------------- 1 | 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 | declare(strict_types=1); 13 | 14 | namespace League\Uri\Contracts; 15 | 16 | use Psr\Http\Message\UriInterface as Psr7UriInterface; 17 | 18 | /** 19 | * @method self when(callable|bool $condition, callable $onSuccess, ?callable $onFail = null) conditionally return a new instance 20 | */ 21 | interface UriAccess 22 | { 23 | public function getUri(): UriInterface|Psr7UriInterface; 24 | 25 | /** 26 | * Returns the RFC3986 string representation of the complete URI. 27 | */ 28 | public function getUriString(): string; 29 | } 30 | -------------------------------------------------------------------------------- /interfaces/Contracts/UriComponentInterface.php: -------------------------------------------------------------------------------- 1 | 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 | declare(strict_types=1); 13 | 14 | namespace League\Uri\Contracts; 15 | 16 | use JsonSerializable; 17 | use Stringable; 18 | 19 | /** 20 | * @method static when(callable|bool $condition, callable $onSuccess, ?callable $onFail = null) conditionally return a new instance 21 | */ 22 | interface UriComponentInterface extends JsonSerializable, Stringable 23 | { 24 | /** 25 | * Returns the instance string representation. 26 | * 27 | * If the instance is defined, the value returned MUST be percent-encoded, 28 | * but MUST NOT double-encode any characters. To determine what characters 29 | * to encode, please refer to RFC 3986, Sections 2 and 3. 30 | * 31 | * If the instance is not defined null is returned 32 | */ 33 | public function value(): ?string; 34 | 35 | /** 36 | * Returns the instance string representation. 37 | * 38 | * If the instance is defined, the value returned MUST be percent-encoded, 39 | * but MUST NOT double-encode any characters. To determine what characters 40 | * to encode, please refer to RFC 3986, Sections 2 and 3. 41 | * 42 | * If the instance is not defined an empty string is returned 43 | */ 44 | public function toString(): string; 45 | 46 | /** 47 | * Returns the instance string representation. 48 | * 49 | * If the instance is defined, the value returned MUST be percent-encoded, 50 | * but MUST NOT double-encode any characters. To determine what characters 51 | * to encode, please refer to RFC 3986, Sections 2 and 3. 52 | * 53 | * If the instance is not defined an empty string is returned 54 | */ 55 | public function __toString(): string; 56 | 57 | /** 58 | * Returns the instance json representation. 59 | * 60 | * If the instance is defined, the value returned MUST be percent-encoded, 61 | * but MUST NOT double-encode any characters. To determine what characters 62 | * to encode, please refer to RFC 3986 or RFC 1738. 63 | * 64 | * If the instance is not defined null is returned 65 | */ 66 | public function jsonSerialize(): ?string; 67 | 68 | /** 69 | * Returns the instance string representation with its optional URI delimiters. 70 | * 71 | * The value returned MUST be percent-encoded, but MUST NOT double-encode any 72 | * characters. To determine what characters to encode, please refer to RFC 3986, 73 | * Sections 2 and 3. 74 | * 75 | * If the instance is not defined an empty string is returned 76 | */ 77 | public function getUriComponent(): string; 78 | } 79 | -------------------------------------------------------------------------------- /interfaces/Contracts/UriException.php: -------------------------------------------------------------------------------- 1 | 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 | declare(strict_types=1); 13 | 14 | namespace League\Uri\Contracts; 15 | 16 | use Throwable; 17 | 18 | interface UriException extends Throwable 19 | { 20 | } 21 | -------------------------------------------------------------------------------- /interfaces/Contracts/UriInspector.php: -------------------------------------------------------------------------------- 1 | 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 | declare(strict_types=1); 13 | 14 | namespace League\Uri\Contracts; 15 | 16 | interface UriInspector 17 | { 18 | /** 19 | * Tells whether the URI instance represents an opaque URI. 20 | */ 21 | public function isOpaque(): bool; 22 | 23 | /** 24 | * Tells whether the URI represents an absolute URI. 25 | */ 26 | public function isAbsolute(): bool; 27 | 28 | /** 29 | * Tells whether the URI represents a network path URI. 30 | */ 31 | public function isNetworkPath(): bool; 32 | 33 | /** 34 | * Tells whether the URI represents an absolute URI path. 35 | */ 36 | public function isAbsolutePath(): bool; 37 | 38 | /** 39 | * Tells whether the given URI object represents a relative path. 40 | */ 41 | public function isRelativePath(): bool; 42 | 43 | /** 44 | * Tells whether the given URI object represents the same document. 45 | * 46 | * It never takes the fragment into account 47 | */ 48 | public function isSameDocument(UriInterface $uri): bool; 49 | 50 | /** 51 | * Tells whether the given URI object represents the same document. 52 | * 53 | * It can take the fragment into account if it is explicitly specified 54 | */ 55 | public function equals(UriInterface $uri, bool $excludeFragment): bool; 56 | 57 | /** 58 | * Tells whether the `file` scheme base URI represents a local file. 59 | */ 60 | public function isLocalFile(): bool; 61 | 62 | /** 63 | * Tells whether the URI comes from a different origin than the current instance. 64 | */ 65 | public function isCrossOrigin(UriInterface $uri): bool; 66 | 67 | /** 68 | * Tells whether the URI shares the same origin as the current instance. 69 | */ 70 | public function isSameOrigin(UriInterface $uri): bool; 71 | 72 | /** 73 | * Returns the URI origin as described in the WHATWG URL Living standard specification. 74 | */ 75 | public function getOrigin(): ?string; 76 | } 77 | -------------------------------------------------------------------------------- /interfaces/Contracts/UriRenderer.php: -------------------------------------------------------------------------------- 1 | 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 | declare(strict_types=1); 13 | 14 | namespace League\Uri\Contracts; 15 | 16 | use DOMException; 17 | use JsonSerializable; 18 | use League\Uri\UriString; 19 | use RuntimeException; 20 | use SplFileInfo; 21 | use SplFileObject; 22 | use Stringable; 23 | 24 | /** 25 | * @phpstan-import-type ComponentMap from UriString 26 | */ 27 | interface UriRenderer extends JsonSerializable 28 | { 29 | /** 30 | * Returns the string representation as a URI reference. 31 | * 32 | * @see http://tools.ietf.org/html/rfc3986#section-4.1 33 | */ 34 | public function toString(): string; 35 | 36 | /** 37 | * Returns the human-readable string representation of the URI as an IRI. 38 | * 39 | * @see https://datatracker.ietf.org/doc/html/rfc3987 40 | */ 41 | public function toDisplayString(): string; 42 | 43 | /** 44 | * Returns the string representation as a URI reference. 45 | * 46 | * @see http://tools.ietf.org/html/rfc3986#section-4.1 47 | * @see ::toString 48 | */ 49 | public function jsonSerialize(): string; 50 | 51 | /** 52 | * Returns the markdown string representation of the anchor tag with the current instance as its href attribute. 53 | */ 54 | public function toMarkdownAnchor(?string $linkTextTemplate = null): string; 55 | 56 | /** 57 | * Returns the HTML string representation of the anchor tag with the current instance as its href attribute. 58 | * 59 | * @param iterable $attributes an ordered map of key value. you must quote the value if needed 60 | * 61 | * @throws DOMException 62 | */ 63 | public function toHtmlAnchor(?string $linkTextTemplate = null, iterable $attributes = []): string; 64 | 65 | /** 66 | * Returns the Unix filesystem path. The method returns null for any other scheme except the file scheme. 67 | */ 68 | public function toUnixPath(): ?string; 69 | 70 | /** 71 | * Returns the Windows filesystem path. The method returns null for any other scheme except the file scheme. 72 | */ 73 | public function toWindowsPath(): ?string; 74 | 75 | /** 76 | * Returns an associative array containing all the URI components. 77 | * 78 | * @return ComponentMap 79 | */ 80 | public function toComponents(): array; 81 | 82 | /** 83 | * Returns a string representation of a File URI according to RFC8089. 84 | * 85 | * The method will return null if the URI scheme is not the `file` scheme 86 | * 87 | * @see https://datatracker.ietf.org/doc/html/rfc8089 88 | */ 89 | public function toRfc8089(): ?string; 90 | 91 | /** 92 | * Save the data to a specific file. 93 | * 94 | * The method returns the number of bytes written to the file 95 | * or null for any other scheme except the data scheme 96 | * 97 | * @param SplFileInfo|SplFileObject|resource|Stringable|string $destination 98 | * @param ?resource $context 99 | * 100 | * @throws RuntimeException if the content can not be stored. 101 | */ 102 | public function toFileContents(mixed $destination, $context = null): ?int; 103 | } 104 | -------------------------------------------------------------------------------- /interfaces/Contracts/UserInfoInterface.php: -------------------------------------------------------------------------------- 1 | 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 | declare(strict_types=1); 13 | 14 | namespace League\Uri\Contracts; 15 | 16 | use Stringable; 17 | 18 | interface UserInfoInterface extends UriComponentInterface 19 | { 20 | /** 21 | * Returns the user component part. 22 | */ 23 | public function getUser(): ?string; 24 | 25 | /** 26 | * Returns the pass component part. 27 | */ 28 | public function getPass(): ?string; 29 | 30 | /** 31 | * Returns an associative array containing all the User Info components. 32 | * 33 | * The returned a hashmap similar to PHP's parse_url return value 34 | * 35 | * @link https://tools.ietf.org/html/rfc3986 36 | * 37 | * @return array{user: ?string, pass : ?string} 38 | */ 39 | public function components(): array; 40 | 41 | /** 42 | * Returns an instance with the specified user and/or pass. 43 | * 44 | * This method MUST retain the state of the current instance, and return 45 | * an instance that contains the specified new username 46 | * otherwise it returns the same instance unchanged. 47 | * 48 | * A variable equal to null is equivalent to removing the complete user information. 49 | */ 50 | public function withUser(Stringable|string|null $username): self; 51 | 52 | /** 53 | * Returns an instance with the specified user and/or pass. 54 | * 55 | * This method MUST retain the state of the current instance, and return 56 | * an instance that contains the specified password if the user is specified 57 | * otherwise it returns the same instance unchanged. 58 | * 59 | * An empty user is equivalent to removing the user information. 60 | */ 61 | public function withPass(Stringable|string|null $password): self; 62 | } 63 | -------------------------------------------------------------------------------- /interfaces/Exceptions/ConversionFailed.php: -------------------------------------------------------------------------------- 1 | 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 | declare(strict_types=1); 13 | 14 | namespace League\Uri\Exceptions; 15 | 16 | use League\Uri\Idna\Error; 17 | use League\Uri\Idna\Result; 18 | use Stringable; 19 | 20 | final class ConversionFailed extends SyntaxError 21 | { 22 | private function __construct( 23 | string $message, 24 | private readonly string $host, 25 | private readonly Result $result 26 | ) { 27 | parent::__construct($message); 28 | } 29 | 30 | public static function dueToIdnError(Stringable|string $host, Result $result): self 31 | { 32 | $reasons = array_map(fn (Error $error): string => $error->description(), $result->errors()); 33 | 34 | return new self('Host `'.$host.'` is invalid: '.implode('; ', $reasons).'.', (string) $host, $result); 35 | } 36 | 37 | public function getHost(): string 38 | { 39 | return $this->host; 40 | } 41 | 42 | public function getResult(): Result 43 | { 44 | return $this->result; 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /interfaces/Exceptions/MissingFeature.php: -------------------------------------------------------------------------------- 1 | 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 | declare(strict_types=1); 13 | 14 | namespace League\Uri\Exceptions; 15 | 16 | use League\Uri\Contracts\UriException; 17 | use RuntimeException; 18 | 19 | class MissingFeature extends RuntimeException implements UriException 20 | { 21 | } 22 | -------------------------------------------------------------------------------- /interfaces/Exceptions/OffsetOutOfBounds.php: -------------------------------------------------------------------------------- 1 | 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 | declare(strict_types=1); 13 | 14 | namespace League\Uri\Exceptions; 15 | 16 | class OffsetOutOfBounds extends SyntaxError 17 | { 18 | } 19 | -------------------------------------------------------------------------------- /interfaces/Exceptions/SyntaxError.php: -------------------------------------------------------------------------------- 1 | 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 | declare(strict_types=1); 13 | 14 | namespace League\Uri\Exceptions; 15 | 16 | use InvalidArgumentException; 17 | use League\Uri\Contracts\UriException; 18 | 19 | class SyntaxError extends InvalidArgumentException implements UriException 20 | { 21 | } 22 | -------------------------------------------------------------------------------- /interfaces/FeatureDetection.php: -------------------------------------------------------------------------------- 1 | 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 | declare(strict_types=1); 13 | 14 | namespace League\Uri; 15 | 16 | use finfo; 17 | use League\Uri\Exceptions\MissingFeature; 18 | use League\Uri\IPv4\Calculator; 19 | 20 | use function class_exists; 21 | use function defined; 22 | use function extension_loaded; 23 | use function function_exists; 24 | 25 | use const PHP_INT_SIZE; 26 | 27 | /** 28 | * Allow detecting features needed to make the packages work. 29 | */ 30 | final class FeatureDetection 31 | { 32 | public static function supportsFileDetection(): void 33 | { 34 | static $isSupported = null; 35 | $isSupported = $isSupported ?? class_exists(finfo::class); 36 | 37 | if (!$isSupported) { 38 | throw new MissingFeature('Support for file type detection requires the `fileinfo` extension.'); 39 | } 40 | } 41 | 42 | public static function supportsIdn(): void 43 | { 44 | static $isSupported = null; 45 | $isSupported = $isSupported ?? (function_exists('\idn_to_ascii') && defined('\INTL_IDNA_VARIANT_UTS46')); 46 | 47 | if (!$isSupported) { 48 | throw new MissingFeature('Support for IDN host requires the `intl` extension for best performance or run "composer require symfony/polyfill-intl-idn" to install a polyfill.'); 49 | } 50 | } 51 | 52 | public static function supportsIPv4Conversion(): void 53 | { 54 | static $isSupported = null; 55 | $isSupported = $isSupported ?? (extension_loaded('gmp') || extension_loaded('bcmath') || (4 < PHP_INT_SIZE)); 56 | 57 | if (!$isSupported) { 58 | throw new MissingFeature('A '.Calculator::class.' implementation could not be automatically loaded. To perform IPv4 conversion use a x.64 PHP build or install one of the following extension GMP or BCMath. You can also ship your own implmentation.'); 59 | } 60 | } 61 | 62 | public static function supportsDom(): void 63 | { 64 | static $isSupported = null; 65 | $isSupported = $isSupported ?? extension_loaded('dom'); 66 | 67 | if (!$isSupported) { 68 | throw new MissingFeature('To use a DOM related feature, the DOM extension must be installed in your system.'); 69 | } 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /interfaces/IPv4/BCMathCalculator.php: -------------------------------------------------------------------------------- 1 | 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 | declare(strict_types=1); 13 | 14 | namespace League\Uri\IPv4; 15 | 16 | use function bcadd; 17 | use function bccomp; 18 | use function bcdiv; 19 | use function bcmod; 20 | use function bcmul; 21 | use function bcpow; 22 | use function bcsub; 23 | use function str_split; 24 | 25 | final class BCMathCalculator implements Calculator 26 | { 27 | private const SCALE = 0; 28 | private const CONVERSION_TABLE = [ 29 | '0' => '0', '1' => '1', '2' => '2', '3' => '3', 30 | '4' => '4', '5' => '5', '6' => '6', '7' => '7', 31 | '8' => '8', '9' => '9', 'a' => '10', 'b' => '11', 32 | 'c' => '12', 'd' => '13', 'e' => '14', 'f' => '15', 33 | ]; 34 | 35 | public function baseConvert(mixed $value, int $base): string 36 | { 37 | $value = (string) $value; 38 | if (10 === $base) { 39 | return $value; 40 | } 41 | 42 | $base = (string) $base; 43 | $decimal = '0'; 44 | foreach (str_split($value) as $char) { 45 | $decimal = bcadd($this->multiply($decimal, $base), self::CONVERSION_TABLE[$char], self::SCALE); 46 | } 47 | 48 | return $decimal; 49 | } 50 | 51 | public function pow(mixed $value, int $exponent): string 52 | { 53 | return bcpow((string) $value, (string) $exponent, self::SCALE); 54 | } 55 | 56 | public function compare(mixed $value1, mixed $value2): int 57 | { 58 | return bccomp((string) $value1, (string) $value2, self::SCALE); 59 | } 60 | 61 | public function multiply(mixed $value1, mixed $value2): string 62 | { 63 | return bcmul((string) $value1, (string) $value2, self::SCALE); 64 | } 65 | 66 | public function div(mixed $value, mixed $base): string 67 | { 68 | return bcdiv((string) $value, (string) $base, self::SCALE); 69 | } 70 | 71 | public function mod(mixed $value, mixed $base): string 72 | { 73 | return bcmod((string) $value, (string) $base, self::SCALE); 74 | } 75 | 76 | public function add(mixed $value1, mixed $value2): string 77 | { 78 | return bcadd((string) $value1, (string) $value2, self::SCALE); 79 | } 80 | 81 | public function sub(mixed $value1, mixed $value2): string 82 | { 83 | return bcsub((string) $value1, (string) $value2, self::SCALE); 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /interfaces/IPv4/Calculator.php: -------------------------------------------------------------------------------- 1 | 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 | declare(strict_types=1); 13 | 14 | namespace League\Uri\IPv4; 15 | 16 | interface Calculator 17 | { 18 | /** 19 | * Add numbers. 20 | * 21 | * @param mixed $value1 a number that will be added to $value2 22 | * @param mixed $value2 a number that will be added to $value1 23 | * 24 | * @return mixed the addition result 25 | */ 26 | public function add(mixed $value1, mixed $value2); 27 | 28 | /** 29 | * Subtract one number from another. 30 | * 31 | * @param mixed $value1 a number that will be subtracted of $value2 32 | * @param mixed $value2 a number that will be subtracted to $value1 33 | * 34 | * @return mixed the subtraction result 35 | */ 36 | public function sub(mixed $value1, mixed $value2); 37 | 38 | /** 39 | * Multiply numbers. 40 | * 41 | * @param mixed $value1 a number that will be multiplied by $value2 42 | * @param mixed $value2 a number that will be multiplied by $value1 43 | * 44 | * @return mixed the multiplication result 45 | */ 46 | public function multiply(mixed $value1, mixed $value2); 47 | 48 | /** 49 | * Divide numbers. 50 | * 51 | * @param mixed $value The number being divided. 52 | * @param mixed $base The number that $value is being divided by. 53 | * 54 | * @return mixed the result of the division 55 | */ 56 | public function div(mixed $value, mixed $base); 57 | 58 | /** 59 | * Raise an number to the power of exponent. 60 | * 61 | * @param mixed $value scalar, the base to use 62 | * 63 | * @return mixed the value raised to the power of exp. 64 | */ 65 | public function pow(mixed $value, int $exponent); 66 | 67 | /** 68 | * Returns the int point remainder (modulo) of the division of the arguments. 69 | * 70 | * @param mixed $value The dividend 71 | * @param mixed $base The divisor 72 | * 73 | * @return mixed the remainder 74 | */ 75 | public function mod(mixed $value, mixed $base); 76 | 77 | /** 78 | * Number comparison. 79 | * 80 | * @param mixed $value1 the first value 81 | * @param mixed $value2 the second value 82 | * 83 | * @return int Returns < 0 if value1 is less than value2; > 0 if value1 is greater than value2, and 0 if they are equal. 84 | */ 85 | public function compare(mixed $value1, mixed $value2): int; 86 | 87 | /** 88 | * Get the decimal integer value of a variable. 89 | * 90 | * @param mixed $value The scalar value being converted to an integer 91 | * 92 | * @return mixed the integer value 93 | */ 94 | public function baseConvert(mixed $value, int $base); 95 | } 96 | -------------------------------------------------------------------------------- /interfaces/IPv4/GMPCalculator.php: -------------------------------------------------------------------------------- 1 | 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 | declare(strict_types=1); 13 | 14 | namespace League\Uri\IPv4; 15 | 16 | use GMP; 17 | 18 | use function gmp_add; 19 | use function gmp_cmp; 20 | use function gmp_div_q; 21 | use function gmp_init; 22 | use function gmp_mod; 23 | use function gmp_mul; 24 | use function gmp_pow; 25 | use function gmp_sub; 26 | 27 | use const GMP_ROUND_MINUSINF; 28 | 29 | final class GMPCalculator implements Calculator 30 | { 31 | public function baseConvert(mixed $value, int $base): GMP 32 | { 33 | return gmp_init($value, $base); 34 | } 35 | 36 | public function pow(mixed $value, int $exponent): GMP 37 | { 38 | return gmp_pow($value, $exponent); 39 | } 40 | 41 | public function compare(mixed $value1, mixed $value2): int 42 | { 43 | return gmp_cmp($value1, $value2); 44 | } 45 | 46 | public function multiply(mixed $value1, mixed $value2): GMP 47 | { 48 | return gmp_mul($value1, $value2); 49 | } 50 | 51 | public function div(mixed $value, mixed $base): GMP 52 | { 53 | return gmp_div_q($value, $base, GMP_ROUND_MINUSINF); 54 | } 55 | 56 | public function mod(mixed $value, mixed $base): GMP 57 | { 58 | return gmp_mod($value, $base); 59 | } 60 | 61 | public function add(mixed $value1, mixed $value2): GMP 62 | { 63 | return gmp_add($value1, $value2); 64 | } 65 | 66 | public function sub(mixed $value1, mixed $value2): GMP 67 | { 68 | return gmp_sub($value1, $value2); 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /interfaces/IPv4/NativeCalculator.php: -------------------------------------------------------------------------------- 1 | 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 | declare(strict_types=1); 13 | 14 | namespace League\Uri\IPv4; 15 | 16 | use function floor; 17 | use function intval; 18 | 19 | final class NativeCalculator implements Calculator 20 | { 21 | public function baseConvert(mixed $value, int $base): int 22 | { 23 | return intval((string) $value, $base); 24 | } 25 | 26 | public function pow(mixed $value, int $exponent) 27 | { 28 | return $value ** $exponent; 29 | } 30 | 31 | public function compare(mixed $value1, mixed $value2): int 32 | { 33 | return $value1 <=> $value2; 34 | } 35 | 36 | public function multiply(mixed $value1, mixed $value2): int 37 | { 38 | return $value1 * $value2; 39 | } 40 | 41 | public function div(mixed $value, mixed $base): int 42 | { 43 | return (int) floor($value / $base); 44 | } 45 | 46 | public function mod(mixed $value, mixed $base): int 47 | { 48 | return $value % $base; 49 | } 50 | 51 | public function add(mixed $value1, mixed $value2): int 52 | { 53 | return $value1 + $value2; 54 | } 55 | 56 | public function sub(mixed $value1, mixed $value2): int 57 | { 58 | return $value1 - $value2; 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /interfaces/Idna/Error.php: -------------------------------------------------------------------------------- 1 | 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 League\Uri\Idna; 13 | 14 | enum Error: int 15 | { 16 | case NONE = 0; 17 | case EMPTY_LABEL = 1; 18 | case LABEL_TOO_LONG = 2; 19 | case DOMAIN_NAME_TOO_LONG = 4; 20 | case LEADING_HYPHEN = 8; 21 | case TRAILING_HYPHEN = 0x10; 22 | case HYPHEN_3_4 = 0x20; 23 | case LEADING_COMBINING_MARK = 0x40; 24 | case DISALLOWED = 0x80; 25 | case PUNYCODE = 0x100; 26 | case LABEL_HAS_DOT = 0x200; 27 | case INVALID_ACE_LABEL = 0x400; 28 | case BIDI = 0x800; 29 | case CONTEXTJ = 0x1000; 30 | case CONTEXTO_PUNCTUATION = 0x2000; 31 | case CONTEXTO_DIGITS = 0x4000; 32 | 33 | public function description(): string 34 | { 35 | return match ($this) { 36 | self::NONE => 'No error has occurred', 37 | self::EMPTY_LABEL => 'a non-final domain name label (or the whole domain name) is empty', 38 | self::LABEL_TOO_LONG => 'a domain name label is longer than 63 bytes', 39 | self::DOMAIN_NAME_TOO_LONG => 'a domain name is longer than 255 bytes in its storage form', 40 | self::LEADING_HYPHEN => 'a label starts with a hyphen-minus ("-")', 41 | self::TRAILING_HYPHEN => 'a label ends with a hyphen-minus ("-")', 42 | self::HYPHEN_3_4 => 'a label contains hyphen-minus ("-") in the third and fourth positions', 43 | self::LEADING_COMBINING_MARK => 'a label starts with a combining mark', 44 | self::DISALLOWED => 'a label or domain name contains disallowed characters', 45 | self::PUNYCODE => 'a label starts with "xn--" but does not contain valid Punycode', 46 | self::LABEL_HAS_DOT => 'a label contains a dot=full stop', 47 | self::INVALID_ACE_LABEL => 'An ACE label does not contain a valid label string', 48 | self::BIDI => 'a label does not meet the IDNA BiDi requirements (for right-to-left characters)', 49 | self::CONTEXTJ => 'a label does not meet the IDNA CONTEXTJ requirements', 50 | self::CONTEXTO_DIGITS => 'a label does not meet the IDNA CONTEXTO requirements for digits', 51 | self::CONTEXTO_PUNCTUATION => 'a label does not meet the IDNA CONTEXTO requirements for punctuation characters. Some punctuation characters "Would otherwise have been DISALLOWED" but are allowed in certain contexts', 52 | }; 53 | } 54 | 55 | public static function filterByErrorBytes(int $errors): array 56 | { 57 | return array_values( 58 | array_filter( 59 | self::cases(), 60 | fn (self $error): bool => 0 !== ($error->value & $errors) 61 | ) 62 | ); 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /interfaces/Idna/Result.php: -------------------------------------------------------------------------------- 1 | 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 | declare(strict_types=1); 13 | 14 | namespace League\Uri\Idna; 15 | 16 | /** 17 | * @see https://unicode-org.github.io/icu-docs/apidoc/released/icu4c/uidna_8h.html 18 | */ 19 | final class Result 20 | { 21 | private function __construct( 22 | private readonly string $domain, 23 | private readonly bool $isTransitionalDifferent, 24 | /** @var array */ 25 | private readonly array $errors 26 | ) { 27 | } 28 | 29 | /** 30 | * @param array{result:string, isTransitionalDifferent:bool, errors:int} $infos 31 | */ 32 | public static function fromIntl(array $infos): self 33 | { 34 | return new self($infos['result'], $infos['isTransitionalDifferent'], Error::filterByErrorBytes($infos['errors'])); 35 | } 36 | 37 | public function domain(): string 38 | { 39 | return $this->domain; 40 | } 41 | 42 | public function isTransitionalDifferent(): bool 43 | { 44 | return $this->isTransitionalDifferent; 45 | } 46 | 47 | /** 48 | * @return array 49 | */ 50 | public function errors(): array 51 | { 52 | return $this->errors; 53 | } 54 | 55 | public function hasErrors(): bool 56 | { 57 | return [] !== $this->errors; 58 | } 59 | 60 | public function hasError(Error $error): bool 61 | { 62 | return in_array($error, $this->errors, true); 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /interfaces/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 ignace nyamagana butera 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of 6 | this software and associated documentation files (the "Software"), to deal in 7 | the Software without restriction, including without limitation the rights to 8 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 9 | the Software, and to permit persons to whom the Software is furnished to do so, 10 | subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 17 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 18 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 19 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | -------------------------------------------------------------------------------- /interfaces/composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "league/uri-interfaces", 3 | "type": "library", 4 | "description" : "Common tools for parsing and resolving RFC3987/RFC3986 URI", 5 | "keywords": [ 6 | "url", 7 | "uri", 8 | "rfc3986", 9 | "rfc3987", 10 | "rfc6570", 11 | "psr-7", 12 | "parse_url", 13 | "http", 14 | "https", 15 | "ws", 16 | "ftp", 17 | "data-uri", 18 | "file-uri", 19 | "parse_str", 20 | "query-string", 21 | "querystring", 22 | "hostname" 23 | ], 24 | "license": "MIT", 25 | "homepage": "https://uri.thephpleague.com", 26 | "authors": [ 27 | { 28 | "name" : "Ignace Nyamagana Butera", 29 | "email" : "nyamsprod@gmail.com", 30 | "homepage" : "https://nyamsprod.com" 31 | } 32 | ], 33 | "funding": [ 34 | { 35 | "type": "github", 36 | "url": "https://github.com/sponsors/nyamsprod" 37 | } 38 | ], 39 | "require": { 40 | "php" : "^8.1", 41 | "ext-filter": "*", 42 | "psr/http-message": "^1.1 || ^2.0" 43 | }, 44 | "autoload": { 45 | "psr-4": { 46 | "League\\Uri\\": "" 47 | } 48 | }, 49 | "suggest": { 50 | "ext-bcmath": "to improve IPV4 host parsing", 51 | "ext-gmp": "to improve IPV4 host parsing", 52 | "ext-intl": "to handle IDN host with the best performance", 53 | "php-64bit": "to improve IPV4 host parsing", 54 | "symfony/polyfill-intl-idn": "to handle IDN host via the Symfony polyfill if ext-intl is not present", 55 | "rowbot/url": "to handle WHATWG URL" 56 | }, 57 | "extra": { 58 | "branch-alias": { 59 | "dev-master": "7.x-dev" 60 | } 61 | }, 62 | "support": { 63 | "forum": "https://thephpleague.slack.com", 64 | "docs": "https://uri.thephpleague.com", 65 | "issues": "https://github.com/thephpleague/uri-src/issues" 66 | }, 67 | "config": { 68 | "sort-packages": true 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /test_files/hello-world.txt: -------------------------------------------------------------------------------- 1 | Bonjour le monde! -------------------------------------------------------------------------------- /test_files/john-doe.vcf: -------------------------------------------------------------------------------- 1 | BEGIN:VCARD 2 | VERSION:3.0 3 | N:Doe;John;;; 4 | FN:John Doe 5 | ORG:Example.com Inc.; 6 | TITLE:Imaginary test person 7 | EMAIL;type=INTERNET;type=WORK;type=pref:johnDoe@example.org 8 | TEL;type=WORK;type=pref:+1 617 555 1212 9 | TEL;type=WORK:+1 (617) 555-1234 10 | TEL;type=CELL:+1 781 555 1212 11 | TEL;type=HOME:+1 202 555 1212 12 | item1.ADR;type=WORK:;;2 Enterprise Avenue;Worktown;NY;01111;USA 13 | item1.X-ABADR:us 14 | item2.ADR;type=HOME;type=pref:;;3 Acacia Avenue;Hoemtown;MA;02222;USA 15 | item2.X-ABADR:us 16 | NOTE:John Doe has a long and varied history\, being documented on more police files that anyone else. Reports of his death are alas numerous. 17 | item3.URL;type=pref:http\://www.example/com/doe 18 | item3.X-ABLabel:_$!!$_ 19 | item4.URL:http\://www.example.com/Joe/foaf.df 20 | item4.X-ABLabel:FOAF 21 | item5.X-ABRELATEDNAMES;type=pref:Jane Doe 22 | item5.X-ABLabel:_$!!$_ 23 | CATEGORIES:Work,Test group 24 | X-ABUID:5AD380FD-B2DE-4261-BA99-DE1D1DB52FBE\:ABPerson 25 | END:VCARD 26 | -------------------------------------------------------------------------------- /test_files/red-nose.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thephpleague/uri-src/7081f6d332026d9ffdd453e9acb44342e331c0b1/test_files/red-nose.gif -------------------------------------------------------------------------------- /uri/HttpFactory.php: -------------------------------------------------------------------------------- 1 | 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 | declare(strict_types=1); 13 | 14 | namespace League\Uri; 15 | 16 | use Psr\Http\Message\UriFactoryInterface; 17 | use Psr\Http\Message\UriInterface; 18 | 19 | final class HttpFactory implements UriFactoryInterface 20 | { 21 | public function createUri(string $uri = ''): UriInterface 22 | { 23 | return Http::new($uri); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /uri/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 ignace nyamagana butera 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of 6 | this software and associated documentation files (the "Software"), to deal in 7 | the Software without restriction, including without limitation the rights to 8 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 9 | the Software, and to permit persons to whom the Software is furnished to do so, 10 | subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 17 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 18 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 19 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | -------------------------------------------------------------------------------- /uri/UriResolver.php: -------------------------------------------------------------------------------- 1 | 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 | declare(strict_types=1); 13 | 14 | namespace League\Uri; 15 | 16 | use Deprecated; 17 | use League\Uri\Contracts\UriInterface; 18 | use Psr\Http\Message\UriInterface as Psr7UriInterface; 19 | 20 | /** 21 | * @deprecated since version 7.0.0 22 | * @codeCoverageIgnore 23 | * @see BaseUri 24 | */ 25 | final class UriResolver 26 | { 27 | /** 28 | * Resolves a URI against a base URI using RFC3986 rules. 29 | * 30 | * This method MUST retain the state of the submitted URI instance, and return 31 | * a URI instance of the same type that contains the applied modifications. 32 | * 33 | * This method MUST be transparent when dealing with error and exceptions. 34 | * It MUST not alter or silence them apart from validating its own parameters. 35 | */ 36 | #[Deprecated(message:'use League\Uri\BaseUri::resolve() instead', since:'league/uri:7.0.0')] 37 | public static function resolve(Psr7UriInterface|UriInterface $uri, Psr7UriInterface|UriInterface $baseUri): Psr7UriInterface|UriInterface 38 | { 39 | return BaseUri::from($baseUri)->resolve($uri)->getUri(); 40 | } 41 | 42 | /** 43 | * Relativizes a URI according to a base URI. 44 | * 45 | * This method MUST retain the state of the submitted URI instance, and return 46 | * a URI instance of the same type that contains the applied modifications. 47 | * 48 | * This method MUST be transparent when dealing with error and exceptions. 49 | * It MUST not alter or silence them apart from validating its own parameters. 50 | */ 51 | #[Deprecated(message:'use League\Uri\BaseUri::relativize() instead', since:'league/uri:7.0.0')] 52 | public static function relativize(Psr7UriInterface|UriInterface $uri, Psr7UriInterface|UriInterface $baseUri): Psr7UriInterface|UriInterface 53 | { 54 | return BaseUri::from($baseUri)->relativize($uri)->getUri(); 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /uri/UriTemplate/Expression.php: -------------------------------------------------------------------------------- 1 | 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 | declare(strict_types=1); 13 | 14 | namespace League\Uri\UriTemplate; 15 | 16 | use Deprecated; 17 | use League\Uri\Exceptions\SyntaxError; 18 | use Stringable; 19 | 20 | use function array_filter; 21 | use function array_map; 22 | use function array_unique; 23 | use function explode; 24 | use function implode; 25 | 26 | /** 27 | * @internal The class exposes the internal representation of an Expression and its usage 28 | * @link https://www.rfc-editor.org/rfc/rfc6570#section-2.2 29 | */ 30 | final class Expression 31 | { 32 | /** @var array */ 33 | private readonly array $varSpecifiers; 34 | /** @var array */ 35 | public readonly array $variableNames; 36 | public readonly string $value; 37 | 38 | private function __construct(public readonly Operator $operator, VarSpecifier ...$varSpecifiers) 39 | { 40 | $this->varSpecifiers = $varSpecifiers; 41 | $this->variableNames = array_unique( 42 | array_map( 43 | static fn (VarSpecifier $varSpecifier): string => $varSpecifier->name, 44 | $varSpecifiers 45 | ) 46 | ); 47 | $this->value = '{'.$operator->value.implode(',', array_map( 48 | static fn (VarSpecifier $varSpecifier): string => $varSpecifier->toString(), 49 | $varSpecifiers 50 | )).'}'; 51 | } 52 | 53 | /** 54 | * @throws SyntaxError if the expression is invalid 55 | */ 56 | public static function new(Stringable|string $expression): self 57 | { 58 | $parts = Operator::parseExpression($expression); 59 | 60 | return new Expression($parts['operator'], ...array_map( 61 | static fn (string $varSpec): VarSpecifier => VarSpecifier::new($varSpec), 62 | explode(',', $parts['variables']) 63 | )); 64 | } 65 | 66 | /** 67 | * DEPRECATION WARNING! This method will be removed in the next major point release. 68 | * 69 | * @throws SyntaxError if the expression is invalid 70 | * @see Expression::new() 71 | * 72 | * @deprecated Since version 7.0.0 73 | * @codeCoverageIgnore 74 | */ 75 | #[Deprecated(message:'use League\Uri\UriTemplate\Exppression::new() instead', since:'league/uri:7.0.0')] 76 | public static function createFromString(Stringable|string $expression): self 77 | { 78 | return self::new($expression); 79 | } 80 | 81 | public function expand(VariableBag $variables): string 82 | { 83 | $expanded = implode( 84 | $this->operator->separator(), 85 | array_filter( 86 | array_map( 87 | fn (VarSpecifier $varSpecifier): string => $this->operator->expand($varSpecifier, $variables), 88 | $this->varSpecifiers 89 | ), 90 | static fn ($value): bool => '' !== $value 91 | ) 92 | ); 93 | 94 | return match ('') { 95 | $expanded => '', 96 | default => $this->operator->first().$expanded, 97 | }; 98 | } 99 | } 100 | -------------------------------------------------------------------------------- /uri/UriTemplate/TemplateCanNotBeExpanded.php: -------------------------------------------------------------------------------- 1 | 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 | declare(strict_types=1); 13 | 14 | namespace League\Uri\UriTemplate; 15 | 16 | use InvalidArgumentException; 17 | use League\Uri\Contracts\UriException; 18 | 19 | class TemplateCanNotBeExpanded extends InvalidArgumentException implements UriException 20 | { 21 | public readonly array $variablesNames; 22 | 23 | public function __construct(string $message = '', string ...$variableNames) 24 | { 25 | parent::__construct($message, 0, null); 26 | 27 | $this->variablesNames = $variableNames; 28 | } 29 | 30 | public static function dueToUnableToProcessValueListWithPrefix(string $variableName): self 31 | { 32 | return new self('The ":" modifier cannot be applied on "'.$variableName.'" since it is a list of values.', $variableName); 33 | } 34 | 35 | public static function dueToNestedListOfValue(string $variableName): self 36 | { 37 | return new self('The "'.$variableName.'" cannot be a nested list.', $variableName); 38 | } 39 | 40 | public static function dueToMissingVariables(string ...$variableNames): self 41 | { 42 | return new self('The following required variables are missing: `'.implode('`, `', $variableNames).'`.', ...$variableNames); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /uri/UriTemplate/VarSpecifier.php: -------------------------------------------------------------------------------- 1 | 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 | declare(strict_types=1); 13 | 14 | namespace League\Uri\UriTemplate; 15 | 16 | use League\Uri\Exceptions\SyntaxError; 17 | 18 | use function preg_match; 19 | 20 | /** 21 | * @internal The class exposes the internal representation of a Var Specifier 22 | * @link https://www.rfc-editor.org/rfc/rfc6570#section-2.3 23 | */ 24 | final class VarSpecifier 25 | { 26 | /** 27 | * Variables specification regular expression pattern. 28 | * 29 | * @link https://tools.ietf.org/html/rfc6570#section-2.3 30 | */ 31 | private const REGEXP_VARSPEC = '/^(?(?:[A-z0-9_\.]|%[0-9a-fA-F]{2})+)(?\:(?\d+)|\*)?$/'; 32 | 33 | private const MODIFIER_POSITION_MAX_POSITION = 10_000; 34 | 35 | private function __construct( 36 | public readonly string $name, 37 | public readonly string $modifier, 38 | public readonly int $position 39 | ) { 40 | } 41 | 42 | public static function new(string $specification): self 43 | { 44 | if (1 !== preg_match(self::REGEXP_VARSPEC, $specification, $parsed)) { 45 | throw new SyntaxError('The variable specification "'.$specification.'" is invalid.'); 46 | } 47 | 48 | $properties = ['name' => $parsed['name'], 'modifier' => $parsed['modifier'] ?? '', 'position' => $parsed['position'] ?? '']; 49 | 50 | if ('' !== $properties['position']) { 51 | $properties['position'] = (int) $properties['position']; 52 | $properties['modifier'] = ':'; 53 | } 54 | 55 | if ('' === $properties['position']) { 56 | $properties['position'] = 0; 57 | } 58 | 59 | if (self::MODIFIER_POSITION_MAX_POSITION <= $properties['position']) { 60 | throw new SyntaxError('The variable specification "'.$specification.'" is invalid the position modifier must be lower than 10000.'); 61 | } 62 | 63 | return new self($properties['name'], $properties['modifier'], $properties['position']); 64 | } 65 | 66 | public function toString(): string 67 | { 68 | return $this->name.$this->modifier.match (true) { 69 | 0 < $this->position => $this->position, 70 | default => '', 71 | }; 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /uri/composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "league/uri", 3 | "type": "library", 4 | "description" : "URI manipulation library", 5 | "keywords": [ 6 | "url", 7 | "uri", 8 | "rfc3986", 9 | "rfc3987", 10 | "rfc6570", 11 | "psr-7", 12 | "parse_url", 13 | "http", 14 | "https", 15 | "ws", 16 | "ftp", 17 | "data-uri", 18 | "file-uri", 19 | "middleware", 20 | "parse_str", 21 | "query-string", 22 | "querystring", 23 | "hostname", 24 | "uri-template" 25 | ], 26 | "license": "MIT", 27 | "homepage": "https://uri.thephpleague.com", 28 | "authors": [ 29 | { 30 | "name" : "Ignace Nyamagana Butera", 31 | "email" : "nyamsprod@gmail.com", 32 | "homepage" : "https://nyamsprod.com" 33 | } 34 | ], 35 | "support": { 36 | "forum": "https://thephpleague.slack.com", 37 | "docs": "https://uri.thephpleague.com", 38 | "issues": "https://github.com/thephpleague/uri-src/issues" 39 | }, 40 | "funding": [ 41 | { 42 | "type": "github", 43 | "url": "https://github.com/sponsors/nyamsprod" 44 | } 45 | ], 46 | "require": { 47 | "php": "^8.1", 48 | "league/uri-interfaces": "^7.6", 49 | "psr/http-factory": "^1" 50 | }, 51 | "autoload": { 52 | "psr-4": { 53 | "League\\Uri\\": "" 54 | } 55 | }, 56 | "conflict": { 57 | "league/uri-schemes": "^1.0" 58 | }, 59 | "suggest": { 60 | "ext-dom": "to convert the URI into an HTML anchor tag", 61 | "ext-bcmath": "to improve IPV4 host parsing", 62 | "ext-fileinfo": "to create Data URI from file contennts", 63 | "ext-gmp": "to improve IPV4 host parsing", 64 | "ext-intl": "to handle IDN host with the best performance", 65 | "jeremykendall/php-domain-parser": "to resolve Public Suffix and Top Level Domain", 66 | "league/uri-components" : "Needed to easily manipulate URI objects components", 67 | "php-64bit": "to improve IPV4 host parsing", 68 | "symfony/polyfill-intl-idn": "to handle IDN host via the Symfony polyfill if ext-intl is not present", 69 | "rowbot/url": "to handle WHATWG URL", 70 | "bakame/aide-uri": "A polyfill for PHP8.1 until PHP8.4 to add support to PHP Native URI parser" 71 | }, 72 | "extra": { 73 | "branch-alias": { 74 | "dev-master": "7.x-dev" 75 | } 76 | }, 77 | "config": { 78 | "sort-packages": true 79 | } 80 | } 81 | --------------------------------------------------------------------------------