Вопрос или проблема
Я пытаюсь получить текущий URL страницы, для чего требуется использовать $_SERVER[“REQUEST_URI”].
Вопрос в том, как мне нужно очистить возвращаемый URL?
Я пытался использовать sanitize_url( string $url, string[] $protocols = null ) с переменной $pageURL, но это вернуло только “https” в качестве результата.
Использование sanitize_url напрямую на $_SERVER[“REQUEST_URI”] вызвало критическую ошибку на сайте.
Что я делаю не так?
Вот мой текущий код, который работает, но не очищен:
$pageURL = 'http';
if( isset($_SERVER["HTTPS"]) ) {
if ($_SERVER["HTTPS"] == "on") {$pageURL .= "s";}
}
$pageURL .= "://";
if ($_SERVER["SERVER_PORT"] != "80") {
$pageURL .= esc_html($_SERVER["SERVER_NAME"].":".$_SERVER["SERVER_PORT"].htmlspecialchars
($_SERVER["REQUEST_URI"]));
} else {
$pageURL .= esc_html($_SERVER["SERVER_NAME"].htmlspecialchars($_SERVER["REQUEST_URI"]));
}
$parse = parse_url($pageURL);
if($parse !== false)
{
return esc_url($pageURL);
}
else{ __return_false(); }
Контекст: Эта функция будет вызвана на фронтенде с использованием короткого кода для получения URL страницы
Молодец, что пытаешься сделать это правильно – но… как насчет этого?
global $wp;
echo esc_url( home_url( $wp->request ) );
ИЗМЕНЕНИЕ:
Версии твоего кода выше были написаны повсюду в интернете – см. этот вопрос на SO с тысячами голосов. Выводит, что это не суперпростая задача, так как клиент может устанавливать некоторые из этих значений сам, так что ты прав, что хочешь их очистить.
Очистка – это просто удаление всего, чего ты не ожидаешь в своей строке… Ты ожидаешь URL – так что позволяй проходить только допустимым символам URL. Если тебе не нужно выводить строку запроса – ну, тогда ты также можешь удалить все, что не входит в названия страниц или структуру сайта. Главное – это ты решаешь – нет функции, которая просто делает sanitize_this()
, твоя задача заключается в том, чтобы выяснить, что именно нужно позволить. Возможно, одна из этих функций подойдет? Посмотри, что разрешено, и реши, что правильно в этом случае.
В общем, тебе нужно очищать только один раз и экранировать один раз, чтобы избежать излишней сложности, и если ты кодируешь, ты не хочешь кодировать дважды – на самом деле ты можешь сделать свой код менее безопасным, поскольку другие функции могут искать строки, такие как '<script>'
в “декодированных” строках и видеть только %3Cscript%3E
, в то время как твой JavaScript декодирует и выводит позже. Ты понимаешь, о чем я?
Мой вышеупомянутый пункт о использовании wp заключается в том, что это уже существует для тебя. Переписывание этих функций – это повод для ошибок, проблем с безопасностью и странных условий ошибок, а решение общих проблем PHP с помощью собственных пользовательских функций – это наивно в лучшем случае и самонадеянно в худшем – профессионалы уже сделали это для тебя – зачем тебе делать это снова?
Что касается критической проблемы, о которой ты упоминаешь – sanitize_url( $_SERVER['REQUEST_URI'] );
является допустимой разметкой – sanitize_url()
является функцией WordPress и требует, чтобы WordPress был загружен для работы. Проверь свои логи для точной причины.
Я добавил код с некоторыми деталями. Ты должен разбить URL на части, затем проверить и очистить его.
// Разбор URL
$parse = parse_url($pageURL);
// Если разбор был успешным, очисти и верни URL
if ($parse !== false) {
// Раздели URL на основную и запросные части. scheme=https/http, host=домен, path=/путь/к/странице
// Например, если $pageURL равен "https://example.com/path/to/page", после разбора $parse['scheme'] будет "https", $parse['host'] будет "example.com", а $parse['path'] будет "/path/to/page". Таким образом, $base_url будет "https://example.com/path/to/page".
// Если у URL есть строка запроса (например, "https://example.com/page?query=value"), она будет добавлена к основной части URL также:
$base_url = $parse['scheme'] . '://' . $parse['host'] . $parse['path'];
// Этот код проверяет, есть ли компонент строки запроса в разобранном URL ($parse['query']). Если он существует, он добавляет его с ведущим ? к переменной $query_string. В противном случае он остается пустой строкой.
// Таким образом, после построения $base_url и $query_string ты можешь объединить их, чтобы получить полный очищенный URL.
// Если URL имеет строку запроса, например "https://example.com/page?query=value", тогда $parse['query'] будет "query=value", а $query_string будет "?query=value". Если у URL нет строки запроса, $query_string останется пустой строкой "".
$query_string = isset($parse['query']) ? '?' . $parse['query'] : '';
// Очисти основной URL и объедините его со строкой запроса
$sanitized_url = esc_url($base_url) . $query_string;
return $sanitized_url;
} else {
return __return_false();
}
Ответ или решение
Для решения вашей проблемы с получением и санитацией текущего URL в плагине WordPress, давайте рассмотрим несколько подходов и рекомендации, чтобы сделать это правильно и безопасно.
Шаг 1: Получение URL страницы
Для начала, мы можем использовать глобальные переменные WordPress для более простого и безопасного получения текущего URL. Вместо использования $_SERVER["REQUEST_URI"]
, можно использовать встроенные функции WordPress, такие как home_url()
или site_url()
.
Шаг 2: Санитация URL
Санитация URL – это важный момент, так как нужно удостовериться, что в URL нет опасных символов или вредоносного кода. WordPress предоставляет функции, такие как esc_url()
, которые помогут в этом.
Полный пример кода
Вот как можно реализовать это в вашем плагине:
function get_sanitized_current_url() {
global $wp;
// Получаем текущий URL
$current_url = home_url($wp->request);
// Санитируем URL
$sanitized_url = esc_url($current_url);
// Возвращаем санированный URL
return $sanitized_url;
}
Объяснение кода
-
Получение текущего URL: Используя
home_url($wp->request)
, мы получаем полное URL текущей страницы.$wp->request
возвращает путь запроса, который был осуществлён. -
Санитация URL: Функция
esc_url()
обрабатывает URL, чтобы убедиться, что он безопасен для использования. Это включает в себя удаление нежелательных символов. -
Возврат результата: После санитации мы возвращаем безопасный URL.
Примечания
-
Если вам не нужно учитывать параметры запроса, то использование
home_url($wp->request)
обеспечит получение базового URL без них. Если параметры вам нужны, убедитесь, что вы их добавляете позже, если это необходимо. -
Никогда не используйте
htmlspecialchars()
для обработки URL, так как эта функция предназначена для HTML-контента, а не для URL. -
Если вводимые данные могут приходить от пользователей (например, через запросы), необходимо соблюдать дополнительные меры предосторожности.
Заключение
Использование встроенных функций WordPress, таких как home_url()
и esc_url()
, обеспечивает необходимую безопасность и простоту. Это уменьшает вероятность ошибок и уязвимостей, которые могут возникнуть при ручной обработке HTTP-заголовков. Ваш метод обработки URL станет более простым и эффективным, если вы будете следовать этим рекомендациям.