PHP class for handling and manipulating URLs. It's a pragmatic one-class lib that is completely framework independent.
-
Parse URL strings to objects
-
add and modify query parameters
-
set and modify any part of the url
-
test for equality of URLs with query parameters in a PHP-fashioned way
-
supports protocol-relative urls
-
convert absolute, host-relative and protocol-relative urls to relative and vice versa
-
New in version 0.7 (2018/07/25): optional compatibility with
Psr\Http\Message\UriInterface
(PSR-7), see below
This package is listed on Packagist.
composer require wa72/url
use \Wa72\Url\Url;
$url = new Url('http://my-server.com/index.php?p1=foo&p2=bar');
// or alternatively use the static factory function `parse`:
$url = Url::parse('http://my-server.com/index.php?p1=foo&p2=bar');
// set another host
$url->setHost('another-server.org');
// return the URL as string again
echo $url->write();
// or simply:
echo $url;
$url->setQueryParameter('p1', 'newvalue');
$url->setQueryParameter('param3', 'another value');
echo $url;
// will output:
// http://another-server.org/index.php?p1=newvalue&p2=bar¶m3=another%20value
// You can even add arrays a query parameter:
$url->setQueryParameter('param3', array(5, 6));
echo $url;
// will output:
// http://another-server.org/index.php?p1=newvalue&p2=bar¶m3[]=5¶m3[]=6
While in general a URL may have multiple query parameters with the same name
(e.g. ?a=value1&a=value2&a=value3
) and there are web applications that convert
those parameters into an array, this is not the PHP way of dealing with query parameters:
In PHP, the last parameter with the same name always wins, so the
above query string is equal to only ?a=value3
.
Similarly, while in general the order of query parameters in the query string may
be significant to a web application, it is not in PHP: ?a=1&b=2
is equivalent
to ?b=2&a=1
for a PHP application.
Url
deals with query strings in URLs like PHP does, so the URLs in the following
example are to be considered equal:
$url1 = Url::parse('index.php?a=0&a=1&b=2');
$url2 = Url::parse('index.php?b=2&a=1');
return $url1.equals($url2);
// will return TRUE
A given URL that has
- no scheme (protocol-relative URL)
- no scheme and no host (host-relative URL)
- no scheme, no host, and a relative path (relative URL)
can be turned into an absolute URL by a given base URL:
$url = Url::parse('page.php');
$baseurl = Url::parse('http://www.test.test/index.html');
$url->makeAbsolute($baseurl);
echo $url; // will print: http://www.test.test/page.php
$url = Url::parse('../de/seite.html');
$baseurl = Url::parse('http://www.test.test/en/page.html');
$url->makeAbsolute($baseurl);
echo $url; // will print: http://www.test.test/de/seite.html
$url = Url::parse('/index.html');
$baseurl = Url::parse('http://www.test.test/en/page.html');
$url->makeAbsolute($baseurl);
echo $url; // will print: http://www.test.test/index.html
$url = Url::parse('/index.html');
$baseurl = Url::parse('http://www.test.test/en/page.html');
$url->makeAbsolute($baseurl);
echo $url; // will print: http://www.test.test/index.html
$url = Url::parse('//www.test.test/index.html');
$baseurl = Url::parse('https://www.test.test/en/page.html');
$url->makeAbsolute($baseurl);
echo $url; // will print: https://www.test.test/index.html
If you want to omit the scheme, or scheme and host, when outputting the URL
you can pass Url::WRITE_FLAG_OMIT_SCHEME
and with Url::WRITE_FLAG_OMIT_HOST
to the write()
-method:
$url = Url::parse('https://www.test.test/index.php?id=5#c1');
// protocol-relative output
echo $url->write(Url::WRITE_FLAG_OMIT_SCHEME); // will print: //www.test.test/index.php?id=5#c1
// host-relative output
echo $url->write(Url::WRITE_FLAG_OMIT_SCHEME | Url::WRITE_FLAG_OMIT_HOST)); // will print: /index.php?id=5#c1
- class
Url
now has all methods defined in this interface but does not officially implement it. - new wrapper class
Psr7Uri
that implementsUriInterface
- methods for converting between
Url
andPsr7Uri
Class Url
does not implement the PSR Interface by itself for two reasons:
- To not introduce a new dependency on the PSR interface. The dependency is only "suggested" in composer json.
- Because the PSR interface is designed to be immutable,
while
Url
is not.
To use this feature, you need to composer require psr/http-message
.
<?php
use Wa72\Url\Psr7Uri;
use Wa72\Url\Url;
# Get a Psr7Uri from a Url object
$url = Url::parse('https://www.foo.bar/test.php?a=b');
$psr7uri = Psr7Uri::fromUrl($url);
// or alternatively:
$psr7uri = $url->toPsr7();
# Get a Url object from UriInterface
$url = Url::fromPsr7($psr7uri); // this works for every UriInterface object, not only Wa72\Url\Psr7Uri
// or alternatively:
$url = $psr7uri->toUrl();
# You can also create a Psr7Uri directly
$psr7uri = Psr7Uri::parse('https://www.foo.bar/test.php?a=b');
Meanwhile, have a look at the source code, there are lots of comments in it.
(c) Christoph Singer 2018. Licensed under the MIT license.