Skip to main content

Examples

Practical examples demonstrating common use cases.

Building URIs from Scratch​

use ByJG\Util\Uri;

$uri = Uri::getInstance()
->withScheme("https")
->withHost("api.example.com")
->withPort(443)
->withPath("/v1/users")
->withQueryKeyValue("page", "1")
->withQueryKeyValue("limit", "20");

echo (string)$uri;
// "https://api.example.com:443/v1/users?page=1&limit=20"

Database Connection Strings​

MySQL​

$uri = Uri::getInstance("mysql://root:password@localhost:3306/mydb");

echo $uri->getScheme(); // "mysql"
echo $uri->getUsername(); // "root"
echo $uri->getPassword(); // "password"
echo $uri->getHost(); // "localhost"
echo $uri->getPort(); // 3306
echo $uri->getPath(); // "/mydb"

PostgreSQL with Query Parameters​

$uri = Uri::getInstance("postgresql://user:pass@host/database")
->withQueryKeyValue("sslmode", "require")
->withQueryKeyValue("connect_timeout", "10");

echo (string)$uri;
// "postgresql://user:pass@host/database?sslmode=require&connect_timeout=10"

SQLite​

// Windows path
$uri = Uri::getInstance("sqlite://C:\\data\\mydb.sqlite");

// Unix path
$uri = Uri::getInstance("sqlite:///var/lib/data/mydb.sqlite");

Modifying Existing URIs​

$uri = Uri::getInstance("http://example.com/old-path?old=param");

// Change to HTTPS
$uri = $uri->withScheme("https");

// Change path
$uri = $uri->withPath("/new-path");

// Replace query string entirely
$uri = $uri->withQuery("new=param&another=value");

echo (string)$uri;
// "https://example.com/new-path?new=param&another=value"

Working with Query Parameters​

Adding Parameters​

$uri = Uri::getInstance("https://api.example.com/search");

$uri = $uri
->withQueryKeyValue("q", "search term")
->withQueryKeyValue("category", "books")
->withQueryKeyValue("sort", "price");

echo (string)$uri;
// "https://api.example.com/search?q=search%20term&category=books&sort=price"

Reading Parameters​

$uri = Uri::getInstance("https://example.com?name=John&age=30&active");

echo $uri->getQueryPart("name"); // "John"
echo $uri->getQueryPart("age"); // "30"
var_dump($uri->hasQueryKey("active")); // true
var_dump($uri->getQueryPart("active")); // "" (empty string, key exists)
var_dump($uri->getQueryPart("missing")); // NULL

Updating Parameters​

$uri = Uri::getInstance("https://example.com?page=1&limit=10");

// Update existing parameter
$uri = $uri->withQueryKeyValue("page", "2");

echo $uri->getQuery(); // "page=2&limit=10"

Handling Special Characters​

Email as Username​

$uri = Uri::getInstance("ftp://[email protected]:[email protected]/path");

echo $uri->getUsername(); // "[email protected]"
echo $uri->getPassword(); // "password"
echo $uri->getHost(); // "ftp.server.com"

// The "@" in the user is percent-encoded on output
echo (string)$uri; // "ftp://user%40example.com:[email protected]/path"

Special Characters in Password​

// Automatically encoded during parsing
$uri = Uri::getInstance("https://user:p@[email protected]");

echo $uri->getUserInfo(); // "user:p%40ss%26word%21"
echo $uri->getPassword(); // "p@ss&word!" (decoded internally)

File URIs​

Local File Path​

// Unix
$uri = Uri::getInstance("file:///home/user/documents/file.txt");
echo $uri->getPath(); // "/home/user/documents/file.txt"

// Windows
$uri = Uri::getInstance("file://C:\\Users\\John\\file.txt");
echo $uri->getPath(); // "C:\\Users\\John\\file.txt"

IPv6 hosts​

An IPv6 literal is written in brackets, as RFC 3986 requires, so that the colons inside are not read as the port separator. getHost() returns the literal with its brackets, which is what getAuthority() and __toString() need to reassemble it:

$uri = Uri::getInstance("kafka://[::1]:9092");

echo $uri->getHost(); // "[::1]"
echo $uri->getPort(); // 9092
echo $uri->getAuthority(); // "[::1]:9092"

// with userinfo, and a zone identifier (RFC 6874)
Uri::getInstance("https://user:pw@[2001:db8::1]:443/p")->getHost(); // "[2001:db8::1]"
Uri::getInstance("kafka://[fe80::1%25eth0]:9092")->getHost(); // "[fe80::1%25eth0]"
info

The brackets are matched for their shape, not validated as an address -- just as a registered name is not validated as a hostname. Checking that an address is well formed belongs to whatever consumes the host. IPvFuture ([v7.foo]) is not supported.

Drive letters and one-character hosts​

A Windows drive letter and a one-character host with a port look alike: C: and h:. They are told apart by what follows the colon -- digits mean a port, anything else means a drive letter:

Uri::getInstance("C:\\Windows\\file.db")->getPath(); // "C:\\Windows\\file.db" -- a path
Uri::getInstance("C:foo")->getPath(); // "C:foo" -- a path
Uri::getInstance("kafka://h:9092")->getHost(); // "h", port 9092 -- a host
warning

C:1 is genuinely ambiguous -- it is both a drive-relative path and a one-character host on port 1, and nothing in the string separates them. It is read as host C on port 1. Write C:\\1 or C:/1 if a path is meant.

API URL Building​

$baseUri = Uri::getInstance("https://api.github.com");

// Build endpoint URL
$uri = $baseUri
->withPath("/repos/byjg/php-uri/issues")
->withQueryKeyValue("state", "open")
->withQueryKeyValue("labels", "bug")
->withQueryKeyValue("per_page", "50");

echo (string)$uri;
// "https://api.github.com/repos/byjg/php-uri/issues?state=open&labels=bug&per_page=50"

Parsing and Extracting Information​

$url = "https://john:[email protected]:8080/path/to/resource?search=test&filter=active#section";
$uri = Uri::getInstance($url);

// Extract all components
$components = [
'scheme' => $uri->getScheme(), // "https"
'user' => $uri->getUsername(), // "john"
'pass' => $uri->getPassword(), // "secret"
'host' => $uri->getHost(), // "example.com"
'port' => $uri->getPort(), // 8080
'path' => $uri->getPath(), // "/path/to/resource"
'query' => $uri->getQuery(), // "search=test&filter=active"
'fragment' => $uri->getFragment(), // "section"
'authority' => $uri->getAuthority(), // "john:[email protected]:8080"
];

print_r($components);

Immutability Example​

$original = Uri::getInstance("https://example.com/path");

// Each modification returns a new instance
$modified1 = $original->withPath("/new-path");
$modified2 = $original->withScheme("http");

echo $original->getPath(); // "/path" (unchanged)
echo $original->getScheme(); // "https" (unchanged)

echo $modified1->getPath(); // "/new-path"
echo $modified2->getScheme(); // "http"

Type Conversion​

// From another PSR-7 implementation
$psr7Uri = new \GuzzleHttp\Psr7\Uri("https://example.com");
$uri = Uri::getInstance($psr7Uri);

// Back to string
$uriString = (string)$uri;

// Re-parse
$newUri = Uri::getInstance($uriString);