WordPress как на ладони
Недорогой хостинг для сайтов на WordPress: wordpress.jino.ru

wp_redirect() WP 1.5.1

Перенаправляет (редиректит) на указанный УРЛ, можно указать статус редиректа (301, 302...).

Для правильной работы функции нужно указывать полный УРЛ:

http://www.example.com/blog/post_name
ftp://ftp.example.com/users/h/harriet/www/

После функции нужно обрывать работу скрипта функцией exit() или die().

В WordPress есть аналогичная функция для редиректа: wp_safe_redirect(). Отличается тем, что проверяет переданный адрес и сравнивает его со списком разрешенных хостов, если хост не найден, то перенаправления не происходит. «Белым» списком можно управлять с помощью фильтра allowed_redirect_hosts.

Другими словами, wp_safe_redirect() рекомендуется использовать всегда, особенно когда $url передается пользователем, а wp_redirect() нужно использовать когда мы намеренно хотим перенаправить пользователя на любой другой сайт, как правило тут $url жестко прописывается в коде, а не передается от пользователя.

// мы точно не знаем указан URL на наш сайт или нет и нам нужно избежать неожиданных редиректов.
wp_safe_redirect( $url );

// мы намеренно перенаправляем на другой сайт, URL прописываем жестко.
wp_redirect( 'https://example.com/some/page' );

wp_redirect() вызовет PHP ошибку (Output already started. Headers not sent.), если использовать функцию после того, как заголовки (header) были отправлены. Т.е. если мы вызовем функцию в файле темы, отвечающем за вывод контента, то функция работать не будет. В таких случаях, в виде некой альтернативы, можно использовать редирект на javascript: document.location.href = 'http://example.com';

Это pluggable функция — т.е. её можно заменить из плагина. Это значит, что она будет работать (подключается) только после подключения всех плагинов, а до этого момента функция еще не определена... Поэтому нельзя вызывать эту и зависящие от неё функции прямо из кода плагина. Их нужно вызывать через хук plugins_loaded или позднее, например хук init.

Замена функции (переопределение) — в плагине можно создать функцию с таким же названием, тогда она заменит текущую функцию.

Является основой для: wp_safe_redirect()
Хуки из функции

Использование

wp_redirect( $location, $status );
exit;
$location(строка) (обязательный)
УРЛ страницы на которую нужно перенаправить.
По умолчанию: нет
$status(число)

Статус код перенаправления (код состояния HTTP):

  • 300 — Multiple Choices (Множество выборов);
  • 301 — Moved Permanently (Перемещено окончательно);
  • 302 — Found (Найдено);
  • 303 — See Other (Смотреть другое);
  • 304 — Not Modified (Не изменялось);
  • 305 — Use Proxy (Использовать прокси);
  • 306 — (зарезервировано);
  • 307 — Temporary Redirect (Временное перенаправление).

Статус 302 означает временное изменение адреса. Если роботу нужно указать, что страница перемещена навсегда, используйте статус — 301. Полный список статусов смотрите здесь.

По умолчанию: 302

Примеры

#1. Внутренний редирект

Пример перенаправления на главную страницу блога:

wp_redirect( home_url() ); 
exit;

#2. Внешний редирект

Редирект может быть и внешним. В примере, мы установили статус код редиректа в 301, что означает что данная страница (страница с которой мы перенаправляем) перемещена навсегда:

wp_redirect( 'http://www.example.com', 301 ); 
exit;

#3. Редирект через хук template_redirect

Этот пример показывает как в WordPress перенаправить пользователя на другую страницу, с возможностью проверить на какой странице сайта он находится сейчас. Т.е. в момент редиректа WP уже определил отображаемую страницу.

Для примера, допустим, нам нужно перенаправить пользователя, если он посетил страницу с ID 10:

add_action( 'template_redirect', function() {
	if( is_page(10) ){
		wp_redirect( 'http://example.org/path/to/subscribe', 301 );
		exit;
	}
} );

Заметки

  • Global. true/false. $is_IIS

Список изменений

С версии 1.5.1 Введена.
С версии 5.1.0 The $x_redirect_by parameter was added.
С версии 5.4.0 On invalid status codes, wp_die() is called.

Код wp redirect: wp-includes/pluggable.php WP 5.4.2

<?php
function wp_redirect( $location, $status = 302, $x_redirect_by = 'WordPress' ) {
	global $is_IIS;

	/**
	 * Filters the redirect location.
	 *
	 * @since 2.1.0
	 *
	 * @param string $location The path or URL to redirect to.
	 * @param int    $status   The HTTP response status code to use.
	 */
	$location = apply_filters( 'wp_redirect', $location, $status );

	/**
	 * Filters the redirect HTTP response status code to use.
	 *
	 * @since 2.3.0
	 *
	 * @param int    $status   The HTTP response status code to use.
	 * @param string $location The path or URL to redirect to.
	 */
	$status = apply_filters( 'wp_redirect_status', $status, $location );

	if ( ! $location ) {
		return false;
	}

	if ( $status < 300 || 399 < $status ) {
		wp_die( __( 'HTTP redirect status code must be a redirection code, 3xx.' ) );
	}

	$location = wp_sanitize_redirect( $location );

	if ( ! $is_IIS && PHP_SAPI != 'cgi-fcgi' ) {
		status_header( $status ); // This causes problems on IIS and some FastCGI setups.
	}

	/**
	 * Filters the X-Redirect-By header.
	 *
	 * Allows applications to identify themselves when they're doing a redirect.
	 *
	 * @since 5.1.0
	 *
	 * @param string $x_redirect_by The application doing the redirect.
	 * @param int    $status        Status code to use.
	 * @param string $location      The path to redirect to.
	 */
	$x_redirect_by = apply_filters( 'x_redirect_by', $x_redirect_by, $status, $location );
	if ( is_string( $x_redirect_by ) ) {
		header( "X-Redirect-By: $x_redirect_by" );
	}

	header( "Location: $location", true, $status );

	return true;
}

Cвязанные функции

Из метки: redirect (редиректы)

Еще из метки: Вспомогательные

Еще из раздела: Без рубрики

30 комментов
Полезные 7 Все
  • Александр Аликин jurnalizd.ru

    Подскажите, пожалуйста, как сделать переадресацию короткой ссылки вида .../?p=123 на каноническую страницу с адресом .../%year%/%monthnum%/%day%/%postname%/

    Перерыл весь интернет, ничего не нашел sad

    Ответить13.Май.2012 17:45 #
  • Артур imvest.biz

    1.Создайте папку с кодом самого редиректа
    2.С необходимого анкора ссылайтесь на папку редиректа, код в которой будет вас перенаправлять. smile

    Ответить15.Июн.2012 17:10 #
    • Александр Аликин jurnalizd.ru

      Благодарю вас.

      Проблему решил еще месяц назад. Как выяснилось, автоматический редирект с http на www и с "коротких ссылок" на канонические был отменен в одной из прежних версий "Вордпресса", и с тех пор эта функция не возобновлялась. Я просто заменил часть кода в одном из файлов на прежний. Теперь все работает smile

      Ответить15.Июн.2012 19:58 #
  • cjcat

    Было бы еще неплохо добавить, что данную функцию нет смысла вызывать, если заголовки уже посланы/установлены, потому что она работать не будет. Работает только до того, как пошлются заголовки.

    Ответить20.Авг.2013 18:30 #
    • Kama7752

      Хорошее замечание, спасибо!

      Ответить21.Авг.2013 03:41 #
    • @ Dima

      можно об этом поподробней? я пытаюсь сделать редирект из обработчика который находится на одной странице с формой , но ничего не происходит, редирект не работает. каким образом мне сделать перенаправление после успешного выполнения функции

      $insertion = wp_insert_post( $my_post );
      if ($insertion) {
      
      $permalink = get_permalink( $insertion );
       wp_redirect( $permalink );
      
      exit;
      			}
      Ответить17.Сен.2013 22:29 #
      • Kama7752

        Вам нужно выполнять эту операцию до того, как страница начнет генерироваться, до того как на экран будет выведена любая информация, это может быть даже любой невидимый символ. Т.е. вставлять ваш код в тело поста, когда, например, шапка сайта уже выведена - вернет ошибку: headers already send.

        Чтобы этого избежать, вы можете повесить вашу операцию на хук, до генерации шаблона: init, template_redirect и т.д. Примерно так:

        add_action('init', 'my_insert_post_hook');
        function my_insert_post_hook($my_post){
        	$insertion = wp_insert_post( $my_post );
        	if( $insertion ){             
        	   $permalink = get_permalink( $insertion );
        	   wp_redirect( $permalink );
        
        	   exit;
        	}
        }
        Ответить18.Сен.2013 11:00 #
  • vovasik

    а ещё эта функция к сожалению не может отдать 404 статус

    1
    Ответить28.Авг.2013 16:03 #
  • Pavel

    302-й статус часто упоминается как Moved Temporarily, и, возможно, не каждый будет искать его по словам "Found":

    wikipedia.org

    Возможно имеет смысл написать "302 - Moved Temporarily (или Found)" или что-то похожее.

    Ответить6.Сен.2015 07:48 #
  • Как перенаправить пользователя с site.ru/statja/ на site.ru/kategoria/statja.html или site.ru/statja.html

    На сайте около 15 000 статей, тому вручную не как не выйдет.

    Ответить19.Май.2016 23:31 #
    • Kama7752

      В .htaccess такое правило добавь:

      # 301 редирект с site.ru/statja/ на site.ru/kategoria/statja.html
      RewriteRule ^statja/?$ kategoria/statja.html [R=301,L]

      Или так в functions.php темы

      add_action( 'template_redirect', function() {
      	if ( preg_match( '~^/statja/?$~i', $_SERVER['REQUEST_URI'] ) ) {
      		wp_redirect('http://site.ru/kategoria/statja.html', 301);
      		exit;
      	}
      } );
      Ответить19.Май.2016 23:57 #
      • Добрый день. Спасибо за ответ. НО редирект не работает.
        Нужно с:
        http://site.com/31259-orange-rose-among-the-stones-in-the-water/
        на:
        http://site.com/31259-orange-rose-among-the-stones-in-the-water.html

        И при этом работали категории в виде:
        http://site.com/category/flowers/
        И главная страница:
        http://site.com

        При установке 301 редирект, главная и категория не работает, перенаправляет на:
        http://site.com/.html
        http://site.com/category/flowers/.html

        На сайте около 15 000 статей, нужен редирект что бы все статьи перенаправляло на .html

        Спасибо. Жду ответа.

        Ответить20.Май.2016 14:05 #
        • Kama7752

          http://site.com/31259-orange-rose-among-the-stones-in-the-water/ - тут 31259 это ID статьи ил и что? Нужен какой нибудь шаблон ссылки...

          Ответить21.Май.2016 00:34 #
          • Да это пост ID
            В чпу прописано так: /%post_id%-%postname%/
            И віходит ссылка http://site.com/31259-orange-rose-among-the-stones-in-the-water/

            Ответить22.Май.2016 12:51 #
            • campusboy3542 www.youtube.com/c/wpplus

              Если в ЧПУ прописать /%post_id%-%postname%.html прописать, поможет?

              1
              Ответить25.Май.2016 02:03 #
              • Kama7752

                Дельное предложение. WP сам 301 редирект поставит...

                Правда нагрузка при этом будет... Но в любом случае это правило нужно установить, чтобы новые ссылки создавались правильно. А чтобы не было лишней нагрузки при редиректах в htaccess до правил wordpress, можно добавить такое правило:

                # 301 редирект с http://site.com/31259-orange-rose-among-the-stones-in-the-water/
                # на http://site.com/31259-orange-rose-among-the-stones-in-the-water.html
                RewriteRule ^([0-9]+-[^/]+)/?$ $1.html [R=301,L]
                Ответить25.Май.2016 04:57 #
              • Конечно, НО вы не помяли, сайт уже проиндексирован, и при переходе с поиска (если сменить на /%post_id%-%postname%.html) выдает ошибку, что страницы такой нету. Тому и нужно сделать перенаправления с / на .html

                Ответить26.Май.2016 10:53 #
                • И команда RewriteRule ^([0-9]+-[^/]+)/?$ $1.html [R=301,L] не работает, пустая страница. Что я сделал:

                  1. Сменил ЧПУ с /%post_id%-%postname%/ на /%post_id%-%postname%.html
                  2. Прописал команду RewriteRule ^([0-9]+-[^/]+)/?$ $1.html [R=301,L]
                    Результат - пустая страница
                  Ответить26.Май.2016 10:58 #
                  • Kama7752

                    при переходе с поиска (если сменить на /%post_id%-%postname%.html) выдает ошибку, что страницы такой нету.

                    Что это значит я не понял...

                    Вы когда ЧПУ поменяли у вас старница типа работает вообще?

                    http://site.com/31259-orange-rose-among-the-stones-in-the-water.html

                    П.С. Еще раз напишите что есть, что не так и что нужно.

                    Ответить1.Июн.2016 15:58 #
                    • да работает, но не работает когда переходишь из поиска, нету редиректа с / на html

                    • Kama7752

                      Вот сервис, показывает что редирект работает, обычно он правильно показывает: http://htaccess.mwl.be/

                      Проверить мне негде...

                      Ты правила до правил WP вставил?

  • campusboy3542 www.youtube.com/c/wpplus

    Бывает приходится переводить самописные сайты на WordPress. В таких сайтах часто все урлы заказчиваются на '.php'. Предлагаю решение проблемы 2 способами.

    1 способ на основе описываемой функции (оформлен как плагин):

    /*
    Plugin Name: Редиректы
    Description: Редиректы, чтобы избавиться от .php в урлах
    */
    
    add_action( 'init', 'moto_disable_php_in_url');
    function moto_disable_php_in_url(){
    	$url = $_SERVER['REQUEST_URI'];
    
    	// Проверка на наличие .php в урле
    	if( strpos($url, '.php') !== false ){
    		// Проверка обращения к файлам движка (разрешаем доступ)
    		if( strpos($url, 'wp-admin') !== false || strpos($url, 'wp-includes') !== false || strpos($url, 'wp-login.php') !== false ){
    
    		}
    		else{
    			$url = home_url() . str_replace('.php', '', $url);
    			wp_redirect( $url, 301 );
    			exit;
    		}
    	}
    }

    2 способ - это набор плагин для htaccess:

    # BEGIN WordPress
    <IfModule mod_rewrite.c>
    RewriteEngine On
    RewriteBase /
    RewriteCond %{THE_REQUEST} ^[A-Z]{3,}\s([^.]+)\.php [NC]
    RewriteCond %{REQUEST_URI} !^/wp-admin
    RewriteCond %{REQUEST_URI} !^/wp-includes
    RewriteCond %{REQUEST_URI} !^/wp-login.php
    RewriteRule ^ %1 [R=301,L]
    RewriteRule ^index\.php$ - [L]
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteRule . /index.php [L]
    </IfModule>
    # END WordPress
    1
    Ответить19.Янв.2017 15:28 #
  • campusboy3542 www.youtube.com/c/wpplus

    Я вот такой код использую, когда надо сделать лендинг со страницей настроек и редактирования:

    /**
    * Перенаправление с главной страницы админки на страницу настроек лендингом
    * 
    * @param object $current_screen объект с данными о текущей страницы админки
    */
    function redirect_dashboard_to_page_options( $current_screen ) {
    
      // Проверяем страницу админки
      if( $current_screen->base != 'dashboard' )
    	return;
    
      // Перенаправляем на кастомную страницу настроек
      wp_redirect( home_url() . '/wp-admin/admin.php?page=pult' );
      exit;
    
    }
    add_action( 'current_screen', 'redirect_dashboard_to_page_options' );
    
    // Переадресация при авторизации на страницу настроек лендингом
    function admin_default_page() {
      return '/wp-admin/admin.php?page=pult';
    }
    add_filter('login_redirect', 'admin_default_page');
    1
    Ответить9.Апр.2017 17:18 #
  • Здравствуйте, не до конца понятно как сделать редирект например с страницы http://example.org/old/ на страницу http://example.org/new/ - можете показать пример?

    Ответить14.Ноя.2017 02:35 #
    • Kama7752

      В файле, который отвечает за вывод страницы http://example.org/old/ используешь такой код:

      wp_redirect( 'http://example.org/new', 301 ); 
      exit;
      Ответить17.Ноя.2017 23:01 #
  • Максим

    Интересный случай, делал обработку формы через admin-post.php и уже в обработчике в зависимости от условий делал редирект или назад на страничку формы в админке с уведомлением о проблеме или перебрасывал на нужную страничку, так вот, редирект сразу при выполнении не сработал, код продолжил выполняться далее, то есть у меня была проверка

    if (ошибка){
    wp_redirect(урл)
    }
    //если ошибки нету то выполняем дальше

    и у меня при истином значении ошибки wp_redirect отрабатывал (но не отправлял данные в браузер) и шло выполнение кода после условия, что как бы не правильно. Нужного поведения добился поставив после wp_redirect exit, теперь в случае ошибки код дальше не выполнялся. Мне интересно это разве правильное поведение? По идее я сразу должен был отправить браузеру редирект, а не тянуть до завершения скрипта, это я к тому что разве такое поведение wp_redirect нормальное?

    1
    Ответить31.Янв.2018 19:13 #
    • Kama7752

      В описании же везде указано что нужно обрывать скрипт - юзать exit. Правильное поведение, почему нет... Правда не очень понятно почему exit в саму функцию не сунули под соответствующий параметр. В 99% случаев нужно использовать exit. О-очень редко бывает нужно, еще что-то делать после установки заголовков, которые ставит wp_redirect()...

      1
      Ответить3.Фев.2018 23:29 #