PHP · TUTORIAL

How to Extract a Directory Name from a URL in PHP

Separate URL paths from query strings, identify category and article segments, and handle missing or unexpected values.

A directory-based website often stores useful information in its addresses. In /action-games/gravity-guy/, the first segment identifies a category and the second identifies an individual page. A shared PHP component can use that structure to choose related content, highlight navigation, or build a breadcrumb. The important part is deciding what each segment means before writing the extraction code.

Consider a website with hundreds of pages arranged in category folders. Passing the category manually to every include creates repeated configuration. Extracting it from a known URL pattern can reduce that repetition, but only if the pattern is consistent. This tutorial uses simple ASCII slugs and root-relative paths. It is designed for familiar directory-based PHP hosting, rather than as a general parser for every possible internet address.

Start with the path, not the full address

A URL can contain a scheme, hostname, path, query string and fragment. If you split the complete address on slashes, the hostname becomes part of your segment list. If you inspect the last slash-separated value without separating the query, you may accidentally include tracking parameters. Keep the example input explicit so you can see which part is being processed.

$url = 'https://www.example.com/action-games/gravity-guy/?ref=home';
$path = parse_url($url, PHP_URL_PATH);
if (!is_string($path)) {
    $path = '';
}
$segments = $path === '' ? [] : explode('/', trim($path, '/'));
$category = $segments[0] ?? '';
$slug = $segments[1] ?? '';

For this example, the category becomes action-games and the slug becomes gravity-guy. The query string does not participate in that result. The type check also gives us a deliberate response when the input has no path or cannot be parsed. Returning an empty category may suit optional navigation; a required routing component should reject the input instead.

Give your URL structure a clear contract

The first segment is not always a category. On this site, /programming/php/read-text-file/ contains a section, language and article slug. Calling every first segment a category would hide that distinction. Name variables after the role they actually play: section, language, article, or whatever your site structure specifies. That makes future changes much easier to review.

Trailing slashes are another source of confusion. Trimming them before splitting gives the same segments for a directory address with or without its final slash. However, trimming does not resolve repeated interior slashes, dot segments or encoded separators. Rather than quietly guessing what a malformed path means, define the shapes you accept and let your redirects establish the public canonical address.

function categoryFromPath(string $path): ?string
{
    if (!preg_match('~^/([a-z0-9-]+)(?:/[a-z0-9-]+)?/?$~D', $path, $match)) {
        return null;
    }
    return $match[1];
}

This function accepts one or two slug segments and rejects everything else. It deliberately does not accept filenames or deeper article hierarchies. Adapt the contract to your own routes instead of loosening it until every string passes. For a three-level programming route, a separate function with clearly named return values would be more useful.

Use explicit page metadata when you already have it

URL extraction is helpful when an include must operate across many existing pages. New pages with a configuration array often have a better source: an explicit section or category field. If a page already declares its canonical path, use that trusted value for breadcrumbs rather than reconstructing it from a request hostname. The request describes what the visitor asked for; page configuration describes the content you intend to serve.

For a root-relative request target supplied by your server, a query can also be removed with explode('?', $requestTarget, 2)[0]. This avoids treating a request path as a complete external URL. Do not decode it repeatedly. Encoded characters and slashes need a single site-wide policy, otherwise two helpers can disagree about which page a visitor requested.

Keep URL values separate from filesystem paths

An address such as /action-games/ is not automatically a safe directory on disk. If the extracted value chooses a folder, compare it with a fixed allowlist first. A valid-looking slug could still name an unpublished area or a folder that has nothing to do with recommendations. The code should know which categories it is permitted to inspect.

$folders = [
    'action-games' => __DIR__ . '/content/action-games',
    'puzzle-games' => __DIR__ . '/content/puzzle-games',
];
$folder = $folders[$category] ?? null;

These paths are examples relative to the script containing the code; adjust them to the actual deployment. Keep the public URL prefix in a separate variable. When you display a category name or link in HTML, escape it for the HTML context, even if the underlying identifier has already passed a slug check. Validation and output escaping solve different problems.

Test the boundaries before sharing the helper

Write down the expected outcomes for the homepage, a category page, an article, a tracking query, a trailing slash and an unexpected deep path. Also try an empty string and a path containing repeated separators. A small table of inputs and outputs is often enough to reveal that the helper is answering a different question from the one you intended.

The PHP manual cautions that parse_url() is not URL validation and recommends standards-based URI classes for new general URL processing. The compatibility example above uses it only to extract a component from a familiar address, not to authorize a redirect or fetch a remote resource. For links themselves, continue with relative versus absolute URLs. See the PHP parsing reference for limitations and alternatives.