Práce s URL
***********
.[perex]
Třídy [#Url], [#UrlImmutable] a [#UrlScript] umožňují snadné generování, parsování a manipulaci s URL.
→ [Instalace a požadavky |@home#Instalace]
Url
===
Třída [api:Nette\Http\Url] umožňuje snadno pracovat s URL a jejími jednotlivými komponentami, které zachycuje tento nákres:
/--pre
scheme user password host port path query fragment
| | | | | | | |
/--\ /--\ /------\ /-------\ /--\/----------\ /--------\ /----\
<b>http://john:xyz%2A12@nette.org:8080/en/download?name=param#footer</b>
\______\__________________________/
| |
hostUrl authority
\--
Generování URL je intuitivní:
```php
use Nette\Http\Url;
$url = new Url;
$url->setScheme('https')
->setHost('localhost')
->setPath('/edit')
->setQueryParameter('foo', 'bar');
echo $url; // 'https://localhost/edit?foo=bar'
```
Lze také URL naparsovat a dále s ní manipulovat:
```php
$url = new Url(
'http://john:xyz%2A12@nette.org:8080/en/download?name=param#footer',
);
```
Třída `Url` implementuje rozhraní `JsonSerializable` a má metodu `__toString()`, takže objekt lze vypsat nebo použít v datech předávaných do `json_encode()`.
```php
echo $url;
echo json_encode([$url]);
```
Komponenty URL
--------------
Pro vrácení nebo změnu jednotlivých komponent URL jsou vám k dispozici tyto metody:
.[language-php]
| Setter | Getter | Vrácená hodnota
|--------------------------------------------------------------------------------------------
| `setScheme(string $scheme)` | `getScheme(): string` | `'http'`
| `setUser(string $user)` | `getUser(): string` | `'john'`
| `setPassword(string $password)` | `getPassword(): string` | `'xyz*12'`
| `setHost(string $host)` | `getHost(): string` | `'nette.org'`
| `setPort(int $port)` | `getPort(): ?int` | `8080`
| | `getDefaultPort(): ?int` | `80`
| `setPath(string $path)` | `getPath(): string` | `'/en/download'`
| `setQuery(string\|array $query)` | `getQuery(): string` | `'name=param'`
| `setFragment(string $fragment)` | `getFragment(): string` | `'footer'`
| | `getAuthority(): string` | `'john:xyz%2A12@nette.org:8080'`
| | `getHostUrl(): string` | `'http://john:xyz%2A12@nette.org:8080'`
| | `getAbsoluteUrl(): string` | celá URL
Metody `getUser()`, `getPassword()`, `setUser()` a `setPassword()` jsou zastaralé, protože vkládání přihlašovacích údajů přímo do URL se nedoporučuje.
Upozornění: Když pracujete s URL, které je získáno z [HTTP requestu|request], mějte na paměti, že nebude obsahovat fragment, protože prohlížeč jej neodesílá na server.
Můžeme pracovat i s jednotlivými query parametry pomocí:
.[language-php]
| Setter | Getter
|---------------------------------------------------
| `setQuery(string\|array $query)` | `getQueryParameters(): array`
| `setQueryParameter(string $name, $val)` | `getQueryParameter(string $name)`
| `appendQuery(string|array $query)` |
getDomain(int $level = 2): string .[method]
-------------------------------------------
Vrací pravou či levou část hostitele. Takto funguje, pokud je host `www.nette.org`:
.[language-php]
| `getDomain(1)` | `'org'`
| `getDomain(2)` | `'nette.org'`
| `getDomain(3)` | `'www.nette.org'`
| `getDomain(0)` | `'www.nette.org'`
| `getDomain(-1)` | `'www.nette'`
| `getDomain(-2)` | `'www'`
| `getDomain(-3)` | `''`
isEqual(string|Url $url): bool .[method]
----------------------------------------
Ověří, zda jsou dvě URL shodné.
```php
$url->isEqual('https://nette.org');
```
canonicalize() .[method]
------------------------
Převede URL do kanonického tvaru. Převede hostname na malá písmena a normalizuje cestu (percent-encoding a odstranění nadbytečných znaků). Query string zůstává beze změny.
Url::isAbsolute(string $url): bool .[method]{data-version:3.3.2}
----------------------------------------------------------------
Ověřuje, zda je URL absolutní. URL je považována za absolutní, pokud začíná schématem (např. http, https, ftp) následovaným dvojtečkou.
```php
Url::isAbsolute('https://nette.org'); // true
Url::isAbsolute('//nette.org'); // false
```
Url::removeDotSegments(string $path): string .[method]{data-version:3.3.2}
--------------------------------------------------------------------------
Normalizuje cestu v URL odstraněním speciálních segmentů `.` a `..`. Metoda odstraňuje nadbytečné prvky cesty stejným způsobem, jako to dělají webové prohlížeče.
```php
Url::removeDotSegments('/path/../subtree/./file.txt'); // '/subtree/file.txt'
Url::removeDotSegments('/../foo/./bar'); // '/foo/bar'
Url::removeDotSegments('./today/../file.txt'); // 'file.txt'
```
UrlImmutable
============
Třída [api:Nette\Http\UrlImmutable] je immutable (neměnnou) alternativou třídy [#Url] (podobně jako je v PHP `DateTimeImmutable` neměnnou alternativou `DateTime`). Místo setterů má tzv. withery, které objekt nemění, ale vracejí nové instance s upravenou hodnotou:
```php
use Nette\Http\UrlImmutable;
$url = new UrlImmutable(
'https://nette.org:8080/cs/download?name=param#footer',
);
$newUrl = $url
->withHost('example.com')
->withPath('/cs/')
->withQueryParameter('name', 'value');
echo $newUrl; // 'https://example.com:8080/cs/?name=value#footer'
```
Třída `UrlImmutable` implementuje rozhraní `JsonSerializable` a má metodu `__toString()`, takže objekt lze vypsat nebo použít v datech předávaných do `json_encode()`.
```php
echo $url;
echo json_encode([$url]);
```
Komponenty URL
--------------
Pro vrácení nebo změnu jednotlivých komponent URL slouží metody:
.[language-php]
| Wither | Getter | Vrácená hodnota
|--------------------------------------------------------------------------------------------
| `withScheme(string $scheme)` | `getScheme(): string` | `'http'`
| `withUser(string $user)` | `getUser(): string` | `'john'`
| `withPassword(string $password)` | `getPassword(): string` | `'xyz*12'`
| `withHost(string $host)` | `getHost(): string` | `'nette.org'`
| `withPort(int $port)` | `getPort(): ?int` | `8080`
| | `getDefaultPort(): ?int` | `80`
| `withPath(string $path)` | `getPath(): string` | `'/en/download'`
| `withQuery(string\|array $query)` | `getQuery(): string` | `'name=param'`
| `withFragment(string $fragment)` | `getFragment(): string` | `'footer'`
| | `getAuthority(): string` | `'john:xyz%2A12@nette.org:8080'`
| | `getHostUrl(): string` | `'http://john:xyz%2A12@nette.org:8080'`
| | `getAbsoluteUrl(): string` | celá URL
Metody `getUser()`, `getPassword()`, `withUser()`, `withPassword()` a `withoutUserInfo()` jsou zastaralé, protože vkládání přihlašovacích údajů přímo do URL se nedoporučuje.
Můžeme pracovat i s jednotlivými query parametry pomocí:
.[language-php]
| Wither | Getter
|-----------------------------------------------
| `withQuery(string\|array $query)` | `getQueryParameters(): array`
| `withQueryParameter(string $name, $val)` | `getQueryParameter(string $name)`
getDomain(int $level = 2): string .[method]
-------------------------------------------
Vrací pravou či levou část hostitele. Takto funguje, pokud je host `www.nette.org`:
.[language-php]
| `getDomain(1)` | `'org'`
| `getDomain(2)` | `'nette.org'`
| `getDomain(3)` | `'www.nette.org'`
| `getDomain(0)` | `'www.nette.org'`
| `getDomain(-1)` | `'www.nette'`
| `getDomain(-2)` | `'www'`
| `getDomain(-3)` | `''`
resolve(string $reference): UrlImmutable .[method]{data-version:3.3.2}
----------------------------------------------------------------------
Odvozuje absolutní URL stejným způsobem, jakým prohlížeč zpracovává odkazy na HTML stránce:
- pokud je odkaz absolutní URL (obsahuje schéma), použije se beze změny
- pokud odkaz začíná `//`, převezme se pouze schéma z aktuální URL
- pokud odkaz začíná `/`, vytvoří se absolutní cesta od kořene domény
- v ostatních případech se URL sestaví relativně vůči aktuální cestě
```php
$url = new UrlImmutable('https://example.com/path/page');
echo $url->resolve('../foo'); // 'https://example.com/foo'
echo $url->resolve('/bar'); // 'https://example.com/bar'
echo $url->resolve('sub/page.html'); // 'https://example.com/path/sub/page.html'
```
isEqual(string|Url $url): bool .[method]
----------------------------------------
Ověří, zda jsou dvě URL shodné.
```php
$url->isEqual('https://nette.org');
```
UrlScript
=========
Třída [api:Nette\Http\UrlScript] je potomkem [#UrlImmutable] a rozšiřuje ji o další virtuální komponenty URL, jako je kořenový adresář projektu apod. Stejně jako rodičovská třída je immutable (neměnným) objektem.
Následující diagram zobrazuje komponenty, které UrlScript rozpoznává:
/--pre
baseUrl basePath relativePath relativeUrl
| | | |
/---------------/-----\/--------\---------------------------\
<b>http://nette.org/admin/script.php/pathinfo/?name=param#footer</b>
\_______________/\________/
| |
scriptPath pathInfo
\--
- `baseUrl` je základní URL adresa aplikace včetně domény a části cesty ke kořenovému adresáři aplikace
- `basePath` je část cesty ke kořenovému adresáři aplikace
- `scriptPath` je cesta k aktuálnímu skriptu
- `relativePath` je název skriptu (případně další segmenty cesty) relativní k basePath
- `relativeUrl` je celá část URL za baseUrl, včetně query string a fragmentu
- `pathInfo` je dnes už málo využívaná část URL za názvem skriptu
Pro vrácení částí URL jsou k dispozici metody:
.[language-php]
| Getter | Vrácená hodnota
|------------------------------------------------
| `getScriptPath(): string` | `'/admin/script.php'`
| `getBasePath(): string` | `'/admin/'`
| `getBaseUrl(): string` | `'http://nette.org/admin/'`
| `getRelativePath(): string` | `'script.php/pathinfo/'`
| `getRelativeUrl(): string` | `'script.php/pathinfo/?name=param#footer'`
| `getPathInfo(): string` | `'/pathinfo/'`
Objekty `UrlScript` obvykle přímo nevytváříme, ale vrací je metoda [Nette\Http\Request::getUrl()|request] s již správně nastavenými komponentami pro aktuální HTTP požadavek.
{{maintitle: Práce s URL v PHP s Nette: parsování a sestavení adres}}
{{description: Parsujte, sestavujte a upravujte URL v PHP pomocí tříd Url, UrlImmutable a UrlScript: parametry v query, porovnávání adres a cesta ke skriptu.}}
Práce s URL
Třídy Url, UrlImmutable a UrlScript umožňují snadné generování, parsování a manipulaci s URL.
→ Instalace a požadavky
Url
Třída Nette\Http\Url umožňuje snadno pracovat s URL a
jejími jednotlivými komponentami, které zachycuje tento nákres:
scheme user password host port path query fragment
| | | | | | | |
/--\ /--\ /------\ /-------\ /--\/----------\ /--------\ /----\
http://john:xyz%2A12@nette.org:8080/en/download?name=param#footer
\______\__________________________/
| |
hostUrl authority
Generování URL je intuitivní:
use Nette\Http\Url;
$url = new Url;
$url->setScheme('https')
->setHost('localhost')
->setPath('/edit')
->setQueryParameter('foo', 'bar');
echo $url; // 'https://localhost/edit?foo=bar'
Lze také URL naparsovat a dále s ní manipulovat:
$url = new Url(
'http://john:xyz%2A12@nette.org:8080/en/download?name=param#footer',
);
Třída Url implementuje rozhraní JsonSerializable a má metodu __toString(), takže
objekt lze vypsat nebo použít v datech předávaných do json_encode().
echo $url;
echo json_encode([$url]);
Komponenty URL
Pro vrácení nebo změnu jednotlivých komponent URL jsou vám k dispozici tyto metody:
| Setter |
Getter |
Vrácená hodnota |
setScheme(string $scheme) |
getScheme(): string |
'http' |
setUser(string $user) |
getUser(): string |
'john' |
setPassword(string $password) |
getPassword(): string |
'xyz*12' |
setHost(string $host) |
getHost(): string |
'nette.org' |
setPort(int $port) |
getPort(): ?int |
8080 |
| |
getDefaultPort(): ?int |
80 |
setPath(string $path) |
getPath(): string |
'/en/download' |
setQuery(string|array $query) |
getQuery(): string |
'name=param' |
setFragment(string $fragment) |
getFragment(): string |
'footer' |
| |
getAuthority(): string |
'john:xyz%2A12@nette.org:8080' |
| |
getHostUrl(): string |
'http://john:xyz%2A12@nette.org:8080' |
| |
getAbsoluteUrl(): string |
celá URL |
Metody getUser(), getPassword(), setUser() a setPassword() jsou zastaralé,
protože vkládání přihlašovacích údajů přímo do URL se nedoporučuje.
Upozornění: Když pracujete s URL, které je získáno z HTTP requestu,
mějte na paměti, že nebude obsahovat fragment, protože prohlížeč jej neodesílá na server.
Můžeme pracovat i s jednotlivými query parametry pomocí:
| Setter |
Getter |
setQuery(string|array $query) |
getQueryParameters(): array |
setQueryParameter(string $name, $val) |
getQueryParameter(string $name) |
| `appendQuery(string |
array $query)` |
getDomain (int $level = 2): string
Vrací pravou či levou část hostitele. Takto funguje, pokud je host www.nette.org:
getDomain(1) |
'org' |
getDomain(2) |
'nette.org' |
getDomain(3) |
'www.nette.org' |
getDomain(0) |
'www.nette.org' |
getDomain(-1) |
'www.nette' |
getDomain(-2) |
'www' |
getDomain(-3) |
'' |
isEqual (string|Url $url): bool
Ověří, zda jsou dvě URL shodné.
$url->isEqual('https://nette.org');
canonicalize()
Převede URL do kanonického tvaru. Převede hostname na malá písmena a normalizuje cestu (percent-encoding a odstranění
nadbytečných znaků). Query string zůstává beze změny.
Url::isAbsolute (string
$url): bool
Ověřuje, zda je URL absolutní. URL je považována za absolutní, pokud začíná schématem (např. http, https, ftp)
následovaným dvojtečkou.
Url::isAbsolute('https://nette.org'); // true
Url::isAbsolute('//nette.org'); // false
Url::removeDotSegments (string $path): string
Normalizuje cestu v URL odstraněním speciálních segmentů . a ... Metoda odstraňuje
nadbytečné prvky cesty stejným způsobem, jako to dělají webové prohlížeče.
Url::removeDotSegments('/path/../subtree/./file.txt'); // '/subtree/file.txt'
Url::removeDotSegments('/../foo/./bar'); // '/foo/bar'
Url::removeDotSegments('./today/../file.txt'); // 'file.txt'
UrlImmutable
Třída Nette\Http\UrlImmutable je immutable
(neměnnou) alternativou třídy Url (podobně jako je v PHP DateTimeImmutable neměnnou
alternativou DateTime). Místo setterů má tzv. withery, které objekt nemění, ale vracejí nové instance
s upravenou hodnotou:
use Nette\Http\UrlImmutable;
$url = new UrlImmutable(
'https://nette.org:8080/cs/download?name=param#footer',
);
$newUrl = $url
->withHost('example.com')
->withPath('/cs/')
->withQueryParameter('name', 'value');
echo $newUrl; // 'https://example.com:8080/cs/?name=value#footer'
Třída UrlImmutable implementuje rozhraní JsonSerializable a má metodu __toString(),
takže objekt lze vypsat nebo použít v datech předávaných do json_encode().
echo $url;
echo json_encode([$url]);
Komponenty URL
Pro vrácení nebo změnu jednotlivých komponent URL slouží metody:
| Wither |
Getter |
Vrácená hodnota |
withScheme(string $scheme) |
getScheme(): string |
'http' |
withUser(string $user) |
getUser(): string |
'john' |
withPassword(string $password) |
getPassword(): string |
'xyz*12' |
withHost(string $host) |
getHost(): string |
'nette.org' |
withPort(int $port) |
getPort(): ?int |
8080 |
| |
getDefaultPort(): ?int |
80 |
withPath(string $path) |
getPath(): string |
'/en/download' |
withQuery(string|array $query) |
getQuery(): string |
'name=param' |
withFragment(string $fragment) |
getFragment(): string |
'footer' |
| |
getAuthority(): string |
'john:xyz%2A12@nette.org:8080' |
| |
getHostUrl(): string |
'http://john:xyz%2A12@nette.org:8080' |
| |
getAbsoluteUrl(): string |
celá URL |
Metody getUser(), getPassword(), withUser(), withPassword() a
withoutUserInfo() jsou zastaralé, protože vkládání přihlašovacích údajů přímo do URL se
nedoporučuje.
Můžeme pracovat i s jednotlivými query parametry pomocí:
| Wither |
Getter |
withQuery(string|array $query) |
getQueryParameters(): array |
withQueryParameter(string $name, $val) |
getQueryParameter(string $name) |
getDomain (int $level = 2): string
Vrací pravou či levou část hostitele. Takto funguje, pokud je host www.nette.org:
getDomain(1) |
'org' |
getDomain(2) |
'nette.org' |
getDomain(3) |
'www.nette.org' |
getDomain(0) |
'www.nette.org' |
getDomain(-1) |
'www.nette' |
getDomain(-2) |
'www' |
getDomain(-3) |
'' |
resolve (string
$reference): UrlImmutable
Odvozuje absolutní URL stejným způsobem, jakým prohlížeč zpracovává odkazy na HTML stránce:
- pokud je odkaz absolutní URL (obsahuje schéma), použije se beze změny
- pokud odkaz začíná
//, převezme se pouze schéma z aktuální URL
- pokud odkaz začíná
/, vytvoří se absolutní cesta od kořene domény
- v ostatních případech se URL sestaví relativně vůči aktuální cestě
$url = new UrlImmutable('https://example.com/path/page');
echo $url->resolve('../foo'); // 'https://example.com/foo'
echo $url->resolve('/bar'); // 'https://example.com/bar'
echo $url->resolve('sub/page.html'); // 'https://example.com/path/sub/page.html'
isEqual (string|Url $url): bool
Ověří, zda jsou dvě URL shodné.
$url->isEqual('https://nette.org');
UrlScript
Třída Nette\Http\UrlScript je potomkem UrlImmutable a rozšiřuje ji o další virtuální komponenty URL, jako je kořenový adresář
projektu apod. Stejně jako rodičovská třída je immutable (neměnným) objektem.
Následující diagram zobrazuje komponenty, které UrlScript rozpoznává:
baseUrl basePath relativePath relativeUrl
| | | |
/---------------/-----\/--------\---------------------------\
http://nette.org/admin/script.php/pathinfo/?name=param#footer
\_______________/\________/
| |
scriptPath pathInfo
baseUrl je základní URL adresa aplikace včetně domény a části cesty ke kořenovému adresáři
aplikace
basePath je část cesty ke kořenovému adresáři aplikace
scriptPath je cesta k aktuálnímu skriptu
relativePath je název skriptu (případně další segmenty cesty) relativní k basePath
relativeUrl je celá část URL za baseUrl, včetně query string a fragmentu
pathInfo je dnes už málo využívaná část URL za názvem skriptu
Pro vrácení částí URL jsou k dispozici metody:
| Getter |
Vrácená hodnota |
getScriptPath(): string |
'/admin/script.php' |
getBasePath(): string |
'/admin/' |
getBaseUrl(): string |
'http://nette.org/admin/' |
getRelativePath(): string |
'script.php/pathinfo/' |
getRelativeUrl(): string |
'script.php/pathinfo/?name=param#footer' |
getPathInfo(): string |
'/pathinfo/' |
Objekty UrlScript obvykle přímo nevytváříme, ale vrací je metoda Nette\Http\Request::getUrl() s již správně nastavenými komponentami pro
aktuální HTTP požadavek.