Praca z adresami URL
Klasy Url, UrlImmutable i UrlScript ułatwiają generowanie, parsowanie i manipulowanie adresami URL.
Url
Klasa Nette\Http\Url pozwala łatwo manipulować adresami URL i ich poszczególnymi składowymi, jak pokazuje ten diagram:
scheme user password host port path query fragment
| | | | | | | |
/--\ /--\ /------\ /-------\ /--\/----------\ /--------\ /----\
http://john:xyz%2A12@nette.org:8080/en/download?name=param#footer
\______\__________________________/
| |
hostUrl authority
Generowanie URL-i jest intuicyjne:
use Nette\Http\Url;
$url = new Url;
$url->setScheme('https')
->setHost('localhost')
->setPath('/edit')
->setQueryParameter('foo', 'bar');
echo $url; // 'https://localhost/edit?foo=bar'
URL możesz też sparsować, a następnie nim manipulować:
$url = new Url(
'http://john:xyz%2A12@nette.org:8080/en/download?name=param#footer',
);
Klasa Url implementuje interfejs JsonSerializable i ma metodę __toString(), więc
obiekt można wypisać albo użyć w danych przekazywanych do json_encode().
echo $url;
echo json_encode([$url]);
Składowe URL
Do odczytu albo zmiany poszczególnych składowych URL służą poniższe metody:
| Setter | Getter | Zwracana wartość |
|---|---|---|
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 |
cały URL |
Metody getUser(), getPassword(), setUser() i setPassword() są
przestarzałe, bo osadzanie danych uwierzytelniających bezpośrednio w URL jest odradzane.
Uwaga: przy pracy z URL uzyskanym z żądania HTTP pamiętaj, że nie będzie zawierał fragmentu, bo przeglądarka nie wysyła go na serwer.
Z poszczególnymi parametrami query możemy pracować za 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
Zwraca prawą albo lewą część hosta. Oto jak to działa, jeśli hostem jest 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
Sprawdza, czy dwa URL-e są identyczne.
$url->isEqual('https://nette.org');
canonicalize()
Konwertuje URL do postaci kanonicznej. Zamienia nazwę hosta na małe litery i normalizuje ścieżkę (percent-encoding i usunięcie zbędnych znaków). Query string pozostaje niezmieniony.
Url::isAbsolute (string $url): bool
Sprawdza, czy URL jest absolutny. URL uznaje się za absolutny, jeśli zaczyna się schematem (np. http, https, ftp), po którym następuje dwukropek.
Url::isAbsolute('https://nette.org'); // true
Url::isAbsolute('//nette.org'); // false
Url::removeDotSegments (string $path): string
Normalizuje ścieżkę URL, usuwając specjalne segmenty . i ... Metoda usuwa zbędne elementy
ścieżki tak samo, jak robią to przeglądarki.
Url::removeDotSegments('/path/../subtree/./file.txt'); // '/subtree/file.txt'
Url::removeDotSegments('/../foo/./bar'); // '/foo/bar'
Url::removeDotSegments('./today/../file.txt'); // 'file.txt'
UrlImmutable
Klasa Nette\Http\UrlImmutable to niezmienna
alternatywa dla klasy Url (podobnie jak DateTimeImmutable jest w PHP niezmienną alternatywą
dla DateTime). Zamiast setterów ma “withery”, które nie zmieniają obiektu, tylko zwracają nowe instancje ze
zmienioną wartością:
use Nette\Http\UrlImmutable;
$url = new UrlImmutable(
'https://nette.org:8080/en/download?name=param#footer',
);
$newUrl = $url
->withHost('example.com')
->withPath('/en/')
->withQueryParameter('name', 'value');
echo $newUrl; // 'https://example.com:8080/en/?name=value#footer'
Klasa UrlImmutable implementuje interfejs JsonSerializable i ma metodę __toString(),
więc obiekt można wypisać albo użyć w danych przekazywanych do json_encode().
echo $url;
echo json_encode([$url]);
Składowe URL
Do odczytu albo zmiany poszczególnych składowych URL służą poniższe metody:
| Wither | Getter | Zwracana wartość |
|---|---|---|
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 |
cały URL |
Metody getUser(), getPassword(), withUser(), withPassword() i
withoutUserInfo() są przestarzałe, bo osadzanie danych uwierzytelniających bezpośrednio w URL jest odradzane.
Z poszczególnymi parametrami query możemy pracować za pomocą:
| Wither | Getter |
|---|---|
withQuery(string|array $query) |
getQueryParameters(): array |
withQueryParameter(string $name, $val) |
getQueryParameter(string $name) |
getDomain (int $level = 2): string
Zwraca prawą albo lewą część hosta. Oto jak to działa, jeśli hostem jest 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
Rozwiązuje absolutny URL tak samo, jak przeglądarka przetwarza odnośniki na stronie HTML:
- jeśli odnośnik jest absolutnym URL (zawiera schemat), używany jest bez zmian
- jeśli odnośnik zaczyna się od
//, przejmowany jest tylko schemat z bieżącego URL - jeśli odnośnik zaczyna się od
/, tworzona jest absolutna ścieżka od korzenia domeny - w pozostałych przypadkach URL składany jest względem bieżącej ścieżki
$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
Sprawdza, czy dwa URL-e są identyczne.
$url->isEqual('https://nette.org');
UrlScript
Klasa Nette\Http\UrlScript to potomek UrlImmutable rozszerzający ją o kolejne wirtualne składowe URL, jak katalog główny projektu itd. Podobnie jak klasa nadrzędna jest obiektem niezmiennym.
Poniższy diagram pokazuje składowe, które UrlScript rozpoznaje:
baseUrl basePath relativePath relativeUrl
| | | |
/---------------/-----\/--------\---------------------------\
http://nette.org/admin/script.php/pathinfo/?name=param#footer
\_______________/\________/
| |
scriptPath pathInfo
baseUrlto bazowy URL aplikacji wraz z domeną i częścią ścieżki do katalogu głównego aplikacjibasePathto część ścieżki do katalogu głównego aplikacjiscriptPathto ścieżka do bieżącego skrypturelativePathto nazwa skryptu (i ewentualnie kolejne segmenty ścieżki) względembasePathrelativeUrlto cała część URL zabaseUrlwraz z query stringiem i fragmentempathInfoto dziś rzadko używana część URL za nazwą skryptu
Do odczytu tych części URL służą poniższe metody:
| Getter | Zwracana wartość |
|---|---|
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/' |
Obiektów UrlScript zwykle nie tworzymy bezpośrednio; zamiast tego zwraca go metoda Nette\Http\Request::getUrl() z już poprawnie ustawionymi składowymi dla
bieżącego żądania HTTP.