Как получить URL текущей отображаемой страницы?
Я хочу добавить пользовательский PHP-код, чтобы при загрузке любой страницы на моем сайте в браузере выводился URL этой страницы. Я могу использовать echo get_permalink()
, но это работает не на всех страницах. Некоторые страницы (например, моя главная страница) отображают несколько постов, и если я использую get_permalink()
на этих страницах, URL отображаемой страницы не возвращается (я полагаю, что возвращается URL последнего поста в цикле). Как для этих страниц можно получить правильный URL?
Могу ли я привязать get_permalink()
к определенному хуку, который срабатывает до выполнения цикла? Или как-то прервать цикл, или сбросить его после завершения?
Спасибо.

get_permalink()
действительно полезен только для отдельных страниц и записей, и работает только внутри цикла.
Самый простой способ, который я видел, выглядит так:
global $wp;
echo home_url( $wp->request )
$wp->request
включает часть пути URL, например /path/to/page
, а home_url()
выводит URL, указанный в Настройки > Общие, но вы можете добавить к нему путь, поэтому в этом коде мы добавляем путь запроса к домашнему URL.
Обратите внимание, что это, вероятно, не будет работать, если в настройках постоянных ссылок выбран "Обычный" тип, и будут опущены строки запроса (часть URL вида ?foo=bar
).
Чтобы получить URL, когда постоянные ссылки установлены как обычные, вы можете использовать $wp->query_vars
, передав его в add_query_arg()
:
global $wp;
echo add_query_arg( $wp->query_vars, home_url() );
И вы можете объединить эти два метода, чтобы получить текущий URL, включая строку запроса, независимо от настроек постоянных ссылок:
global $wp;
echo add_query_arg( $wp->query_vars, home_url( $wp->request ) );

Если постоянные ссылки установлены как обычные: echo '//' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'];
.

@Jacob Я попробовал это, но похоже, что возвращается URL только моей главной страницы. Как вы можете видеть в верхнем левом углу на этой странице (https://dev.horizonhomes-samui.com/properties/hs0540/), где я вставил код echo home_url( $wp->request )
. Я также убедился, что включил global $wp
. Постоянные ссылки установлены не как 'Обычные', а как 'Название записи'. Я также не вижу никаких соответствующих ошибок PHP в логах. Эта конкретная страница является частью моего сайта разработки, который в остальном заблокирован для посетителей. Не уверен, имеет ли это значение или нет. редактирование: Подождите, возможно, это ошибка пользователя. Минутку...

@Jacob редактирование 2: OK, ваш код действительно работает. Моя проблема была в том, что я включил код в functions.php 'голым', т.е. не в функции, привязанной к хуку. Поэтому ваш код возвращал URL главной страницы, независимо от страницы, отображаемой в моем браузере. Как только я переместил код внутрь функции -- функции, привязанной к хуку WordPress (wp_enqueue_scripts), он действительно стал возвращать URL отображаемой страницы. Вы знаете причину такого поведения? Возможно, мне нужно создать новый вопрос для этого.

@cag8f Если код находится "голым" в functions.php, значит вы запускаете его до того, как все свойства объекта $wp были настроены. Когда вы оборачиваете его в функцию, привязанную к соответствующему хуку, вы откладываете его выполнение до подходящего момента в процессе выполнения кода WordPress.

Все эти методы отличные и являются прекрасными идеями для работы с WordPress. Вы можете добавить к ним trailingslashit()
, в зависимости от ваших потребностей.

Это работает нормально, но не учитывает слеш в конце URL. Рассмотрите вариант $post_permalink = home_url( $_SERVER['REQUEST_URI'] );

Также стоит иметь в виду, что это может быть CSS или JS файл (или вообще любой запрос к серверу)

@MaxYudin пожалуйста, не используйте $_SERVER, так как он отключен на некоторых хостингах.

Будьте осторожны при использовании $wp->query_vars
со страницей, имеющей пользовательский URL, созданный с помощью add_rewrite_rule()
, обычный WP-запрос с пользовательским запросом будет виден. Пример: /mycustompage/subscribe?pagename=mycustompage&mycustom_subpage=subscribe. При этом URL, который отображается в браузере, будет просто /mycustompage/subscribe.

Вы можете использовать приведенный ниже код, чтобы получить полный текущий URL в WordPress:
global $wp;
// Получаем текущий URL, включая все параметры запроса
$current_url = home_url(add_query_arg(array(), $wp->request));
Это покажет полный путь, включая параметры запроса.

Привет - если вы посмотрите на https://developer.wordpress.org/reference/functions/add_query_arg/, вы увидите, что ваш код фактически не сохраняет существующие параметры запроса.

Чтобы сохранить параметры запроса, вам нужно заменить пустой array()
на $_GET
. То есть:
home_url(add_query_arg($_GET,$wp->request));

Это не будет работать, если WordPress установлен в поддиректории

@BradAdams ответ не работал для меня, пока я не увидел ваш комментарий о пустом массиве. Спасибо!

Почему бы просто не использовать?
get_permalink( get_the_ID() );
Это для отдельных страниц.
Для страниц категорий используйте следующее:
get_category_link( get_query_var( 'cat' ) );
Простой скрипт для получения текущего URL любой страницы:
// получить текущий URL
$current_url = get_permalink( get_the_ID() );
if( is_category() ) $current_url = get_category_link( get_query_var( 'cat' ) );
echo $current_url;

Следующий код предоставит текущий URL:
global $wp;
echo home_url($wp->request)
Вы можете использовать приведенный ниже код, чтобы получить полный URL вместе с параметрами запроса.
global $wp;
$current_url = home_url(add_query_arg(array($_GET), $wp->request));
Это покажет полный путь, включая параметры запроса. Данный метод сохранит параметры запроса, если они уже присутствуют в URL.

Этот фрагмент пропускает wp-admin/plugins.php
в текущем URL, оставляя только корневой путь и строки запроса.

Почти! Отсутствовал завершающий слеш, что вызывает быстрый редирект для его добавления, когда WP его обрабатывает, что немного ухудшает SEO, поэтому я добавил его ниже. Пока что это создает точный URL
global $wp;
$current_url = home_url(add_query_arg(array($_GET), $wp->request . '/'));

@ShaneMcCurdy Вы также можете использовать trailingslashit()
(смотрите комментарий Jake выше)

Все представленные здесь решения хороши, но не были последовательными как для локальной, так и для удаленной серверной среды. Поэтому я разработал более простое и элегантное решение, которое работает лучше независимо от настроек постоянных ссылок WordPress.
// Функция получения текущего URL
function getCurrentUrl() {
$protocol = is_ssl() ? 'https://' : 'http://'; // Определяем протокол (http/https)
return ($protocol) . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'];
}
$currentUrl = getCurrentUrl();
echo $currentUrl;
Вывод будет включать параметры запроса URL и ЧПУ-ссылки.

// Функция для получения текущего URL сайта
function current_location()
{
// Проверяем используется ли HTTPS
if (isset($_SERVER['HTTPS']) &&
($_SERVER['HTTPS'] == 'on' || $_SERVER['HTTPS'] == 1) ||
isset($_SERVER['HTTP_X_FORWARDED_PROTO']) &&
$_SERVER['HTTP_X_FORWARDED_PROTO'] == 'https') {
$protocol = 'https://';
} else {
$protocol = 'http://';
}
// Возвращаем полный URL, включая протокол, хост и путь
return $protocol . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'];
}
// Выводим текущий URL
echo current_location();

Всегда старайтесь включать небольшое объяснение к вашему ответу, чтобы автор вопроса лучше понял, что происходит. Таким образом мы все учимся, и сообщество растет. :-)

Да, спустя восемь лет я все еще озадачен тем, как это работает, и где это следует использовать (в чистом виде? внутри хука? фильтра? цикла?... мы понятия не имеем).

Вот что сработало для меня (короткое и чистое решение, которое также включает строки запроса в URL):
$current_url = add_query_arg( $_SERVER['QUERY_STRING'], '', home_url( $wp->request ) );
URL будет выглядеть следующим образом:
http://sometesturl.test/slug1/slug2?queryParam1=testing&queryParam2=123
Решение было взято отсюда

Это улучшенный способ примера, упомянутого ранее. Он работает, когда включены красивые URL-адреса, однако не учитывает наличие каких-либо параметров запроса, таких как /page-slug/?param=1 или если URL вообще не является красивым.
Следующий пример будет работать в обоих случаях.
$query_args = array();
// Разбираем URL на составные части
$query = wp_parse_url( $YOUR_URL );
// Получаем структуру постоянных ссылок
$permalink = get_option( 'permalink_structure' );
// Если структура постоянных ссылок пуста
if ( empty( $permalink ) ) {
$query_args = $query['query'];
}
// Выводим URL с добавленными параметрами запроса
echo home_url( add_query_arg( $query_args , $wp->request ) )

Возможно, wp_guess_url()
- это то, что вам нужно. Доступно начиная с версии 2.6.0.

После долгих исследований простой задачи, для нас работает комбинация всех приведенных выше ответов:
function get_wp_current_url(){
global $wp;
if('' === get_option('permalink_structure')) return home_url(add_query_arg(array($_GET), $wp->request));
else return home_url(trailingslashit(add_query_arg(array($_GET), $wp->request)));
}
Нет отсутствующего слеша в конце и так далее. Поскольку вопрос касается вывода текущего URL, здесь не рассматриваются вопросы безопасности и прочее. Однако, хеш вроде #comment в конце не может быть обнаружен в PHP.

Я понимаю, что это старый вопрос, однако я заметил, что никто не упомянул использование get_queried_object()
.
Это глобальная функция WordPress, которая получает всё, что относится к текущему URL, на котором вы находитесь. Например, если вы находитесь на странице или записи, она вернет объект записи. Если вы находитесь в архиве, она вернет объект типа записи.
WordPress также имеет множество вспомогательных функций, таких как get_post_type_archive_link
, которой вы можете передать поле типа записи объекта и получить обратно его ссылку, например так:
get_post_type_archive_link(get_queried_object()->name);
Суть в том, что вам не нужно полагаться на некоторые из приведенных выше хаковых решений, а вместо этого использовать queried object, чтобы всегда получать правильный URL.
Это также будет работать для мультисайтовых установок без дополнительной работы, так как используя функции WordPress, вы всегда получаете правильный URL.

Хм. Возможно, проблема заключается в отсутствии универсального способа указания всех возможных типов объектов. Другими словами, такие функции как get_post_type_archive_link()
отлично работают, если вы заранее знаете, что у вас есть ссылка на архив. Таким образом, вам всё равно нужно определить, какой тип объекта у вас есть, прежде чем использовать конкретную вспомогательную функцию для него. По мере того как WordPress получает всё больше и больше типов объектов, вам нужно писать больше кода для обработки каждого отдельного случая...

get_queried_object ВСЕГДА содержит информацию, которую можно использовать для определения типа объекта WordPress. Это включает архивы записей. Это достаточно легко проверить. Просто попробуйте просмотреть результаты вызова метода в каждом типе шаблона, и вы лучше поймете, что я имею в виду.

WP обновил что-то и теперь свойство request глобальной переменной $wp по умолчанию пустое. Вы должны вызвать специальный метод parse_request перед тем, как получить данные этого свойства.
Раньше это работало так:
global $wp;
echo home_url( $wp->request );
Теперь это должно быть так:
global $wp;
$wp->parse_request();
echo home_url( $wp->request );
P.S. Я хотел бы оставить это в комментариях под самым популярным ответом, но у меня нет прав оставлять комментарии.

Но parse_request уже должен быть вызван через $wp->main() в конце этого файла.
