Формирование URL-адресов в PHP: практическое руководство

Раздел: Веб-разработка -> URL

Основные методы построения URL в PHP

Наиболее эффективным решением для генерации ссылок в PHP является создание собственной функции, учитывающей базовый URL, путь и параметры запроса. Это обеспечивает единообразие, безопасность и лёгкость поддержки.

define('BASE_URL', 'https://example.com');

function buildUrl(string $path, array $params = []): string {
    $url = rtrim(BASE_URL, '/') . '/' . ltrim($path, '/');
    if (!empty($params)) {
        $url .= '?' . http_build_query($params, '', '&', PHP_QUERY_RFC3986);
    }
    return $url;
}

// Пример использования
echo buildUrl('/catalog', ['category' => 'books', 'page' => 2]);
// Результат: https://example.com/catalog?category=books&page=2

код ссылки php (код ссылки php)

Функция http_build_query корректно кодирует параметры, предотвращая XSS-атаки. Константа BASE_URL позволяет легко менять домен или протокол.

Как избежать двойных слешей в URL?

Если путь уже начинается со слеша, функция ltrim удалит его, а rtrim удалит слеш из BASE_URL. Однако при изменении константы может возникнуть дублирование. Решение: всегда задавать BASE_URL без завершающего слеша, а путь с ведущим слешем или без – функция сама нормализует.

Когда достаточно относительной ссылки?

Если документ и целевая страница находятся на одном домене, можно использовать относительный путь. Это упрощает перенос сайта между средами.

$relative = '/about/team';
echo 'О команде';

Почему обязательно использовать htmlspecialchars?

При выводе в HTML любые данные, включая URL, должны быть экранированы, чтобы избежать XSS. Использование htmlspecialchars с флагом ENT_QUOTES гарантирует безопасность.

Как добавить якорь (anchor) к ссылке?

Якорь добавляется после URL через символ #. Важно включать якорь после всех параметров запроса.

$url = 'https://example.com/page?section=faq#answer3';
// Сборка:
$base = 'https://example.com/page';
$params = ['section' => 'faq'];
$anchor = 'answer3';
$full = $base . '?' . http_build_query($params) . '#' . $anchor;
echo $full;
https://example.com/page?section=faq#answer3

Что если якорь содержит специальные символы?

Якорь не проходит URL-кодирование; он должен быть простым идентификатором. Если якорь формируется динамически, следует ограничить допустимые символы.

Как передать API-ключ в URL без утечки?

Для API-запросов часто требуется токен в query-параметре. Не рекомендуется включать его в URL для GET-запросов, лучше использовать заголовки. Если же необходимо, параметр следует передавать через http_build_query и хранить ключ в переменной окружения.

$apiKey = getenv('API_KEY');
$url = 'https://api.example.com/data?' . http_build_query(['key' => $apiKey, 'format' => 'json']);
echo $url;

Почему не стоит жестко прописывать ключ в коде?

Ключи доступа должны храниться вне репозитория (в .env). При выводе URL с ключом в логах или HTML он может быть скомпрометирован. Для внутренних запросов используйте curl с заголовком Authorization.

Как организовать дружественные URL для CMS?

Современные CMS используют роутинг, где URL собирается из маршрута и параметров. Пример с использованием простого роутера:

$routes = [
    'product' => '/catalog/{id}/{slug}',
    'page'    => '/{slug}',
];
function route(string $name, array $params = []): string {
    global $routes;
    if (!isset($routes[$name])) return '#';
    $url = $routes[$name];
    foreach ($params as $key => $value) {
        $url = str_replace('{'.$key.'}', rawurlencode($value), $url);
    }
    return $url;
}
// Генерация ссылки на товар с id=42 и slug='phone'
echo route('product', ['id' => 42, 'slug' => 'phone-mobile']);
/catalog/42/phone-mobile

Как избежать неопределенных параметров?

Если в шаблоне маршрута остались не замененные плейсхолдеры, URL будет содержать {param}. Следует проверять наличие всех ключей до замены.

Расширенные примеры генерации URL

Использование PSR-7 UriInterface

Компонент HTTP Foundation или Guzzle предоставляет объект Uri для работы с URL.

Пример
use GuzzleHttp\Psr7\Uri;
use GuzzleHttp\Psr7\Query;

$uri = new Uri('https://example.com/path');
$uri = $uri->withQuery(Query::build(['page' => 3, 'sort' => 'desc']));
echo $uri; // https://example.com/path?page=3&sort=desc
https://example.com/path?page=3&sort=desc

Метод withQuery заменяет строку запроса, обеспечивая корректное кодирование.

Генерация URL с поддоменом

Для мультисайтовых приложений динамически меняется поддомен.

Пример
$subdomain = 'shop';
$base = 'example.com';
$scheme = 'https';
$url = $scheme . '://' . $subdomain . '.' . $base . '/products';
echo $url; // https://shop.example.com/products
https://shop.example.com/products

Следует экранировать поддомен, если он берется из пользовательского ввода.

Создание ссылок с сохранением состояния пагинации

На странице результатов часто нужно сохранить все параметры кроме page.

Пример
$base = '/search';
$params = $_GET; // или массив
unset($params['page']); // удаляем текущий номер страницы
$url = $base . '?' . http_build_query($params);
// Для каждой страницы:
for ($i = 1; $i <= 5; $i++) {
    $paginatedUrl = $url . '&page=' . $i;
    echo 'Страница ' . $i . ' ';
}
/search?q=php&category=books&page=1

Использование http_build_query гарантирует, что спецсимволы будут закодированы.

Работа с URL-rewriting через .htaccess

При использовании mod_rewrite внутренние URL преобразуются. Генерация ссылок должна соответствовать внешнему виду.

Пример
// Внешний URL: /article/123/hello-world
// Внутренний: index.php?page=article&id=123
function articleUrl(int $id, string $slug): string {
    return '/article/' . $id . '/' . rawurlencode($slug);
}
echo articleUrl(123, 'hello world'); // /article/123/hello%20world
/article/123/hello%20world

При выводе в HTML ссылку следует экранировать htmlspecialchars.

Сравнение urlencode и rawurlencode

urlencode кодирует пробел как '+', rawurlencode как '%20'. Для query-строки обычно используют rawurlencode для совместимости с RFC 3986, но PHP функции http_build_query по умолчанию использует '+'. Флаг PHP_QUERY_RFC3986 переключает на '%20'.

Пример
echo urlencode('hello world'); // hello+world
echo rawurlencode('hello world'); // hello%20world
hello+world
hello%20world

При ручной сборке строки запроса рекомендуется использовать rawurlencode.

Код ссылки PHP - comments

En
код ссылки php (php)