The Url class is a URL utility for inspecting the current request, building and manipulating URL strings, validating URLs, and resolving domain information. It has no dependencies and can be used standalone or through the application container.
- Class:
JiFramework\Core\Utilities\Url - Access:
$app->url
Features at a glance:
- Current request inspection —
current(),host(),path(),referrer() - Query parameter reading —
queryParam(),queryParams() - URL construction and manipulation —
build(),removeParam() - URL validation —
isValid() - Domain and IP resolution —
domainInfo() - Consistent HTTPS detection — handles direct SSL, port 443, and reverse-proxy
X-Forwarded-Proto
$app = new App();
// Inspect the current request
echo $app->url->current(); // https://example.com/products?sort=asc
echo $app->url->host(); // https://example.com
echo $app->url->path(); // /products?sort=asc
// Build a URL
$link = $app->url->build('https://example.com/search', ['q' => 'php', 'page' => 2]);
// https://example.com/search?q=php&page=2
// Validate
$app->url->isValid('https://example.com'); // true
$app->url->isValid('not-a-url'); // false
current(): string
Returns the full URL of the current request — scheme, host, path, and query string. HTTPS is detected consistently across direct SSL, port 443, and reverse-proxy environments (X-Forwarded-Proto).
echo $app->url->current();
// https://example.com/products?sort=asc&page=2
The value is assembled from $_SERVER['HTTP_HOST'] and $_SERVER['REQUEST_URI']. Both keys are safely defaulted — an empty host or / path is returned if the server does not provide them (e.g. CLI context).
// Typical use: canonical link tag
echo '';
host(): string
Returns the scheme and host only — no path or query string. Useful for constructing absolute URLs from relative paths.
echo $app->url->host();
// https://example.com
// Build an absolute URL from a relative path
$absolute = $app->url->host() . '/assets/logo.png';
// https://example.com/assets/logo.png
The relationship between the three current-request methods is always:
$app->url->host() . $app->url->path() === $app->url->current(); // true
path(): string
Returns REQUEST_URI — the path and query string without the scheme or host. Useful for comparisons and redirect logic.
echo $app->url->path();
// /products?sort=asc&page=2
// Check if the current path starts with /admin
if (str_starts_with($app->url->path(), '/admin')) {
// restrict access
}
referrer(): string|null
Returns the HTTP referrer URL, or null when the browser did not send a Referer header (direct access, privacy settings, HTTPS→HTTP navigation).
$ref = $app->url->referrer();
if ($ref !== null) {
// User came from somewhere — log it or redirect back
$app->logger->info('Referrer: {ref}', ['ref' => $ref]);
} else {
// Direct access or referrer suppressed
}
Never trust the referrer for security decisions — it is a user-controlled header and can be spoofed or omitted.
queryParam(string $key, mixed $default = null): mixed
Returns a single query parameter from the current request ($_GET). Returns $default when the key is absent.
$key— (string) The query parameter name.$default— (mixed, optional) Value to return when the key is not present. Defaults tonull.
// URL: /products?sort=price&page=3
$sort = $app->url->queryParam('sort'); // "price"
$page = $app->url->queryParam('page'); // "3"
$view = $app->url->queryParam('view', 'grid'); // "grid" (default — key absent)
// Typical pagination usage
$page = (int) $app->url->queryParam('page', 1);
$rows = $app->db->table('products')->paginate($page, 20);
All values from $_GET are strings. Cast to the expected type (int, float, bool) after reading.
queryParams(string $url): array
Parses all query parameters from a URL string into an associative array. Returns an empty array when the URL has no query string.
$url— (string) Any absolute or relative URL string.
$params = $app->url->queryParams('https://example.com/search?q=php&page=2&sort=asc');
// ['q' => 'php', 'page' => '2', 'sort' => 'asc']
// URL with no query string
$params = $app->url->queryParams('https://example.com/about');
// []
// Parse the current page URL
$params = $app->url->queryParams($app->url->current());
Use queryParam() to read a single key from the live request. Use queryParams() when you need to inspect all parameters of an arbitrary URL string.
build(string $baseUrl, array $params = []): string
Appends query parameters to a base URL, correctly using ? or & depending on whether a query string already exists. Returns the base URL unchanged when $params is empty.
$baseUrl— (string) The base URL, with or without an existing query string.$params— (array, optional) Associative array of parameters to append.
// Clean base URL — appends with ?
$link = $app->url->build('https://example.com/search', ['q' => 'hello world', 'page' => 2]);
// https://example.com/search?q=hello+world&page=2
// Base URL already has a query string — appends with &
$link = $app->url->build('https://example.com/search?q=hello', ['page' => 3]);
// https://example.com/search?q=hello&page=3
// Empty params — base URL returned unchanged
$link = $app->url->build('https://example.com/page', []);
// https://example.com/page
// Pagination links
for ($p = 1; $p <= $totalPages; $p++) {
$href = $app->url->build($app->url->host() . '/products', [
'page' => $p,
'sort' => $app->url->queryParam('sort', 'name'),
]);
echo ''. $p .'';
}
removeParam(string $url, string $key): string
Removes a single query parameter from a URL and returns the cleaned URL. All other components — scheme, host, port, path, remaining parameters, and fragment — are preserved exactly.
$url— (string) The source URL.$key— (string) The query parameter key to remove.
// Remove one parameter, preserve the rest
$clean = $app->url->removeParam('https://example.com/page?a=1&b=2&c=3', 'b');
// https://example.com/page?a=1&c=3
// Remove the only parameter — no trailing ? left
$clean = $app->url->removeParam('https://example.com/page?token=abc123', 'token');
// https://example.com/page
// Key not present — URL returned unchanged
$clean = $app->url->removeParam('https://example.com/page?a=1', 'z');
// https://example.com/page?a=1
// Fragment is preserved
$clean = $app->url->removeParam('https://example.com/page?debug=1&view=list#results', 'debug');
// https://example.com/page?view=list#results
Combine with build() and current() to add or strip parameters from the live URL without string manipulation:
// Strip the "token" param then add "confirmed=1"
$next = $app->url->build(
$app->url->removeParam($app->url->current(), 'token'),
['confirmed' => 1]
);
isValid(string $url): bool
Returns true when the string is a well-formed HTTP or HTTPS URL. Only http:// and https:// schemes are accepted. Localhost and IP addresses (v4 and v6) are valid hosts.
$url— (string) The URL string to validate.
$app->url->isValid('https://example.com'); // true
$app->url->isValid('http://example.com/path?q=1'); // true
$app->url->isValid('https://sub.domain.co.uk'); // true
$app->url->isValid('http://localhost'); // true
$app->url->isValid('http://127.0.0.1/api'); // true
$app->url->isValid('http://192.168.1.1/admin'); // true
$app->url->isValid('ftp://files.example.com'); // false — ftp not allowed
$app->url->isValid('javascript:alert(1)'); // false — dangerous scheme
$app->url->isValid('https://example'); // false — no TLD
$app->url->isValid('not-a-url'); // false
$app->url->isValid(''); // false
Use this before storing or following a user-supplied URL to prevent open-redirect and scheme-injection attacks.
$redirect = $app->url->queryParam('next');
if ($redirect !== null && $app->url->isValid($redirect)) {
$app->redirect($redirect);
} else {
$app->redirect('/dashboard');
}
domainInfo(string $url): array|null
Extracts the domain name from a URL and resolves it to an IPv4 address via DNS. Returns null when the URL is malformed and has no host component.
$url— (string) Any URL string to inspect.
Return value — associative array with two keys:
domain_name— (string) The extracted hostname.domain_ip— (string|null) Resolved IPv4 address, ornullwhen DNS resolution fails.
$info = $app->url->domainInfo('https://example.com/some/path?q=1');
// [
// 'domain_name' => 'example.com',
// 'domain_ip' => '93.184.216.34',
// ]
// Malformed URL — no host
$info = $app->url->domainInfo('not-a-url');
// null
// Non-existent domain — DNS fails
$info = $app->url->domainInfo('https://this.host.does.not.exist.invalid/');
// [
// 'domain_name' => 'this.host.does.not.exist.invalid',
// 'domain_ip' => null,
// ]
Always check the return value before accessing the array keys, and check domain_ip for null before treating it as a resolved address.
$info = $app->url->domainInfo($userSuppliedUrl);
if ($info === null) {
// URL was malformed
} elseif ($info['domain_ip'] === null) {
// Domain parsed but DNS resolution failed
} else {
echo $info['domain_name'] . ' resolves to ' . $info['domain_ip'];
}
This method makes a live DNS lookup on every call. Cache the result if you are resolving the same domain repeatedly.