如何在PHP中进行重定向?


1261

是否可以通过使用PHP将用户重定向到其他页面?

假设用户转到www.example.com/page.php并且我想将其重定向到www.example.com/index.php,那么在不使用元刷新的情况下该怎么做?可能吗?

这甚至可以保护我的页面免受未经授权的用户的侵害。


您可以在PHP中更新标头:标头
Zack Marrapese

11
@Sam:就像副节点一样,不要实现任何类型的protection from unauthorized usersvia重定向;这不是应该做的事情;)
Strae 2011年

7
@Strae用重定向保护页面怎么了?那最好的方法是什么?

6
@PravindaAmarathunga重定向是元素之一,但不是唯一的元素。只要确保未授权用户根本不会输出受保护的元素即可;可以在客户端禁用浏览器的重定向,例如:如果浏览器不执行重定向并且原始页面正常输出,那么用户会看到什么?CMS通常会进行重定向,并且不会打印出受保护的项目,而是用礼貌性的消息代替常规输出。
Strae

@PravindaAmarathunga检查来自马库斯答案的链接:thedailywtf.com/Articles/WellIntented-Destruction.aspx
Strae

Answers:


1696

现有答案的摘要加上我自己的两分钱:

1.基本答案

您可以使用该header()函数发送新的HTTP标头,但是必须在发送任何HTML或文本之前(<!DOCTYPE ...>例如,在声明之前)将其发送到浏览器。

header('Location: '.$newURL);

2.重要细节

die()exit()

header("Location: http://example.com/myOtherPage.php");
die();

为什么要使用die()exit()每日WTF

绝对或相对URL

自2014年6月起,绝对URL和相对URL均可使用。请参阅RFC 7231,该文件已替换了旧的RFC 2616,其中仅允许绝对URL。

状态码

PHP的“位置”标头仍使用HTTP 302重定向代码,但这不是您应该使用的代码。您应该考虑301(永久重定向)或303(其他)。

注意:W3C提到 303标头与“许多HTTP / 1.1之前的用户代理不兼容。当前使用的浏览器都是HTTP / 1.1用户代理。对于许多其他用户代理(例如蜘蛛网和漫游器)而言,情况并非如此。

3.文件

HTTP标头和header()PHP中的函数

4.替代方案

您可以使用http_redirect($url);需要安装PECL软件包pecl的替代方法。

5.助手功能

此功能未包含303状态代码:

function Redirect($url, $permanent = false)
{
    header('Location: ' . $url, true, $permanent ? 301 : 302);

    exit();
}

Redirect('http://example.com/', false);

这更加灵活:

function redirect($url, $statusCode = 303)
{
   header('Location: ' . $url, true, $statusCode);
   die();
}

6.解决方法

如前所述,header()重定向仅在任何内容写出之前起作用。如果在HTML输出中调用它们,通常会失败。然后,您可以使用HTML标头解决方法(不是很专业!),例如:

 <meta http-equiv="refresh" content="0;url=finalpage.html">

甚至JavaScript重定向。

window.location.replace("http://example.com/");

5
此答案有一些问题:303可能不是“正确”的状态代码。例如,对于Google可能需要301。其次,header('Location: '.$newURL);必须在将任何HTML(或文本)传递到浏览器之前,否则不能正常工作。
Chuck Le Butt

6
不幸的是,每天的WTF故事都是一个普通的故事。无论如何,导致问题的原因不是缺少模具,而是不良的设计。在99.9%的情况下,强行关闭该过程是错误的。一个常见的,更简洁的解决方案(无论如何不是我的最爱)是抛出RedirectionException并将其捕获到应用程序入口点。之后,您可以进行所有“ after *”呼叫(日志/关闭连接/进行任何操作)
robertodecurnex

4
http-equiv="Location"并非所有浏览器都支持。您应该refresh改用!<meta http-equiv="refresh" content="0;url=http://example.com/">
Timo002 2014年

71
除非您是故意的,否则请勿发出301 。301表示永久,permanent表示永久,这意味着它将被用户代理缓存,这意味着漫长而充满咖啡因的夜晚盯着应用程序日志,怀疑您是否发疯了,因为您发誓某些页面应该被调用或更新并且发誓对上帝而言,它在您的计算机上起作用,但在客户的计算机上不起作用。如果您绝对必须调用301,请在资源上放置一个缓存控制最大容量。你没有无限的智慧,你不应该表现得像你一样。
madumlao 2014年

2
但是,有理由在退出时使用die吗?出口似乎更干净更合适。
2015年

122

使用该header()函数发送HTTP Location标头

header('Location: '.$newURL);

与某些人认为的相反,die()它与重定向无关。当您要重定向而不是正常执行时才使用它。

文件example.php

<?php
    header('Location: static.html');
    $fh = fopen('/tmp/track.txt', 'a');
    fwrite($fh, $_SERVER['REMOTE_ADDR'] . ' ' . date('c') . "\n");
    fclose($fh);
?>

三个执行的结果:

bart@hal9k:~> cat /tmp/track.txt
127.0.0.1 2009-04-21T09:50:02+02:00
127.0.0.1 2009-04-21T09:50:05+02:00
127.0.0.1 2009-04-21T09:50:08+02:00

恢复-强制性die()/ exit()是一些城市传说,与实际的PHP无关。它与客户端“尊重” Location:报头无关。无论使用哪种客户端,发送标头都不会停止PHP执行。


8
die()或exit()适用于不遵守“ Location:...”标头的客户
clawr

12
@clawr:否,exit()是为了防止页面显示剩余内容(请考虑限制页面)。vartec是正确的,它与HTTP Location标头无关,您也不需要exit。我选择将其包含在我的答案中,因为对于一个不知道如何进行简单重定向的人,最好还是起着安全的作用,而不是不执行简单但关键的步骤,以使他能够利用高级流程控制。
Alix Axel

1
但是,尊重标题的浏览器将在脚本仍在执行的同时离开页面并关闭连接。这太糟糕了。PHP将在脚本上运行一段时间(这就是代码执行的原因),但是在执行过程中可能会随机中止该脚本,从而使工作中断。调用ignore_user_abort()可以防止这种情况,但是我诚恳地,这是不值得的。只是继续用HTML编写东西(尽管可能没用),但是不要做在标头('Location:')之后在磁盘或数据库上写的东西。如果可能,在重定向之前写入磁盘。[也:URL应该是绝对的。]
FrancescoMM

在浏览器检测到HTTP协议之前,有什么方法可以重定向?我需要重定向的原因是因为我无法为所有域都获得足够的SSL证书。我会使用.htaccess重定向,但我需要一种方法以某种方式将哪个域重定向到最终域?
oldboy

109
function Redirect($url, $permanent = false)
{
    if (headers_sent() === false)
    {
        header('Location: ' . $url, true, ($permanent === true) ? 301 : 302);
    }

    exit();
}

Redirect('http://www.google.com/', false);

不要忘记die()/ exit()!


6
并且不要忘了输出缓冲,否则您将得到“ Headers has sent”。
黑木风2009年

8
...并且不要忘记打印出类似“像这样的消息:您将在$ n秒内被重定向到$ nepage,如果不发生重定向,请单击$ link在这里”某些浏览器和某些浏览器的设置可能会导致重定向失败。
Strae

3
@DaNieL:这种重定向不会花费“ $ n秒”。如果完全发生,它将是即时的,任何兼容的浏览器都应处理。我认为您正在思考的是人们不了解的“元刷新”重定向。
rmeador

1
@rmeador ...对于较旧的浏览器和专用浏览器。您应该首先执行您的Location标头,如果失败,请进行元重定向,并带有“您将在x秒内将您重定向到页面”链接,以防元重定向失败。这是进行重定向的正确且故障保护的方法。
Andrew Moore

3
安德鲁:HTTP浏览器如何不尊重位置:?
vartec

102

使用echo从PHP输出JavaScript,即可完成工作。

echo '<script type="text/javascript">
           window.location = "http://www.google.com/"
      </script>';

除非缓冲页面输出然后在以后检查重定向条件,否则您实际上无法在PHP中执行此操作。那可能太麻烦了。请记住,标题是从页面发送的第一件事。大多数重定向通常在页面的稍后部分是必需的。为此,您必须缓冲页面的所有输出,并在以后检查重定向条件。那时,您可以重定向页面用户header()或仅回显缓冲的输出。

有关缓冲的更多信息(优势)

什么是输出缓冲?


2
简单而切题的答案!非常适合简单的页面重定向!
Stathis Andronikos

这样,您就不会遇到常见Cannot modify header information - headers already sent by错误。
Kai Noack

1
@hmd,如果禁用了javascript怎么办?
Istiaque Ahmed

这些天,@ IstiaqueAhmed javascript几乎总是被启用,但是如果被禁用,则可以使用PHP缓冲区。这样的问题可以回答。如果您使用的是PHP缓冲,那么我猜您不需要此方法。
Hammad Khan

错误的是,即使没有缓冲,您也可以(并且应该)在PHP中进行处理:在设计合理的页面中,所有相关的PHP处理都应在将任何HTML内容发送给用户之前进行。这样,PHP重定向将可以正常工作。
MestreLion

91

1.使用标头功能 exit()

<?php 
     header('Location: target-page.php');
     exit();
?>

但是,如果您使用标头函数,那么有时您会收到“警告,就像标头已经发送”这样的警告,以解决在发送标头之前不回显或打印的问题,或者您可以简单地使用标头函数die()exit()在标头函数之后使用。

2.无标题

<?php 
    echo "<script>location.href='target-page.php';</script>";
?>

在这里你不会遇到任何问题

3.通过ob_start()和使用标题功能ob_end_flush()

<?php
ob_start(); //this should be first line of your page
header('Location: target-page.php');
ob_end_flush(); //this should be last line of your page
?>

像魅力一样工作。我使用<?php echo“ <script> location.href =' google.fr/ '; </script >”; ?>要测试它,它做了我想要的
DoctorDroid Haiti

1
第二种解决方案在禁用JS的情况下不起作用。
塔吉尼

55

这些答案大多数都忘记了非常重要的一步!

header("Location: myOtherPage.php");
die();

撇开第二条至关重要的电话,您可能最终会进入《每日WTF》。问题是,浏览器不具备尊重,你的页面返回,所以用被忽略标题,页面的其余部分将不重定向执行的头。


1
在终止脚本之前向用户提供一些输出是什么?你知道,人们喜欢知道发生了什么...
Strae

3
您假设脚本除了重定向外没有其他事情。这可能根本不正确。
vartec

13
@DaNieL:将其更改为die(“停止忽略我的标题!”)
nickf

3
我喜欢die();您提供的简单说明-如果您不这样做,那么如果您确实使用它,用户可能会看到一整页的内容;用户将被重定向,并且不会显示临时内容故障+ 1
TheBlackBenzKid 2015年

发送标头后,可能发生有用的活动,该活动不向浏览器发送任何内容,但记录该活动或完成记录交易。因此,是否需要死/退出取决于脚本。
DanAllen '17

28

采用:

<?php header('Location: another-php-file.php'); exit(); ?>

或者,如果您已经打开了PHP标签,请使用以下命令:

header('Location: another-php-file.php'); exit();

您还可以重定向到外部页面,例如:

header('Location: https://www.google.com'); exit();

确保包含exit()或包含die()


25

您可以使用会话变量来控制对页面的访问并授权有效用户:

<?php
    session_start();

    if (!isset( $_SESSION["valid_user"]))
    {
        header("location:../");
        exit();
    }

    // Page goes here
?>

http://php.net/manual/en/reserved.variables.session.php

最近,我受到了网络攻击,并决定要了解试图访问管理面板或Web应用程序保留部分的用户。

因此,我在文本文件中添加了IP地址和用户会话的日志访问权限,因为我不想打扰数据库。


19

这些答案中有许多是正确的,但它们假定您拥有一个绝对URL,而事实并非如此。如果要使用相对URL并生成其余URL,则可以执行以下操作...

$url = 'http://' . $_SERVER['HTTP_HOST'];            // Get the server
$url .= rtrim(dirname($_SERVER['PHP_SELF']), '/\\'); // Get the current directory
$url .= '/your-relative/path-goes/here/';            // <-- Your relative path
header('Location: ' . $url, true, 302);              // Use either 301 or 302

16

header( 'Location: http://www.yoursite.com/new_page.html' );


在浏览器检测到HTTP协议之前,有什么方法可以重定向?我需要重定向的原因是因为我无法为所有域都获得足够的SSL证书。我会使用.htaccess重定向,但我需要一种方法以某种方式将哪个域重定向到最终域?
oldboy

16

使用以下代码:

header("Location: /index.php");
exit(0);   

14

我已经回答了这个问题,但是由于我同时了解到了某些特殊情况,如果您在CLI中运行(重定向无法发生,因此应该不会发生exit()),或者您的网络服务器处于将PHP作为(F)CGI运行(它需要预先设置的Status标头才能正确重定向)。

function Redirect($url, $code = 302)
{
    if (strncmp('cli', PHP_SAPI, 3) !== 0)
    {
        if (headers_sent() !== true)
        {
            if (strlen(session_id()) > 0) // If using sessions
            {
                session_regenerate_id(true); // Avoids session fixation attacks
                session_write_close(); // Avoids having sessions lock other requests
            }

            if (strncmp('cgi', PHP_SAPI, 3) === 0)
            {
                header(sprintf('Status: %03u', $code), true, $code);
            }

            header('Location: ' . $url, true, (preg_match('~^30[1237]$~', $code) > 0) ? $code : 302);
        }

        exit();
    }
}

我也处理的支持不同的HTTP重定向代码的问题(301302303307),因为它是在我以前的答复的意见中提到。以下是说明:

  • 301 -永久移动
  • 302-找到
  • 303-查看其他
  • 307-临时重定向(HTTP / 1.1)

11

要将访问者重定向到另一个页面(在条件循环中特别有用),只需使用以下代码:

<?php
    header('Location: mypage.php');
?>

在这种情况下,mypage.php是您要将访问者重定向到的页面的地址。该地址可以是绝对地址,也可以包含以下格式的参数:mypage.php?param1=val1&m2=val2)

相对/绝对路径

处理相对路径或绝对路径时,理想的是从服务器的根目录(DOCUMENT_ROOT)中选择一个绝对路径。使用以下格式:

<?php
    header('Location: /directory/mypage.php');
?>

如果目标页面位于另一台服务器上,则包括完整的URL:

<?php
    header('Location: http://www.ccm.net/forum/');
?>

HTTP头

根据HTTP协议,HTTP标头必须发送before任何类型的内容。这就是说,在标题之前绝对不能发送任何字符-甚至不能有空格!

临时/永久重定向

默认情况下,上面介绍的重定向类型是临时的。这意味着在建立索引时,搜索引擎(例如Google搜索)将不会考虑重定向。

如果您想通知搜索引擎某个页面已被永久移动到另一个位置,请使用以下代码:

<?
    header('Status: 301 Moved Permanently', false, 301);
    header('Location: new_address');
?>

例如,此页面具有以下代码:

<?
    header('Status: 301 Moved Permanently', false, 301);
    header('Location: /pc/imprimante.php3');
    exit();
?>

当您单击上面的链接时,您将自动重定向到此页面。此外,它是永久重定向(状态:301,已永久移动)。因此,如果您在Google中输入第一个URL,则会自动将您重定向到第二个重定向的链接。

PHP代码解读

即使访问者移动到重定向中指定的地址,服务器也会解释header()之后的PHP代码。在大多数情况下,这意味着您需要一种方法来遵循该header()函数的exit()功能,以减轻服务器的负载:

<?
    header('Status: 301 Moved Permanently', false, 301);
    header('Location: address');
    exit();
?>

为什么(在第二段末尾附近)?您是&para不是要说(所以整个读为mypage.php?param1=val1&param2=val2))?(HTML实体para)为“¶”-也许某些外部程序进行了转换?)。
彼得·莫滕森

9

采用:

<?php
    header('Location: redirectpage.php');
    header('Location: redirectpage.php');
    exit();
    echo "<script>location.href='redirectpage.php';</script>";
?>

这是常规的和正常的PHP重定向,但是您可以通过以下代码创建一个重定向页面,等待几秒钟:

<?php
    header('refresh:5;url=redirectpage.php '); // Note: here 5 means 5 seconds wait for redirect.
?>

7

在语义网的前夕,要考虑正确性。不幸的是,PHP的“ Location”标头仍然使用HTTP 302重定向代码,严格来说,它不是用于重定向的最佳代码。它应该使用的是303号

W3C很友好地提到 303标头与“许多HTTP / 1.1之前的用户代理”不兼容,这在当前使用中没有浏览器。因此,302是一个遗物,不应使用。

...或者您可以像其他所有人一样忽略它...


7

您可以使用如下所示的一些JavaScript方法

  1. self.location="http://www.example.com/index.php";

  2. window.location.href="http://www.example.com/index.php";

  3. document.location.href = 'http://www.example.com/index.php';

  4. window.location.replace("http://www.example.com/index.php");


JavaScript可以在客户端上运行,也可以不是您想要的。
chharvey

7

是的,您可以使用header()函数,

header("Location: http://www.yourwebsite.com/user.php"); /* Redirect browser */
exit();

最佳实践也是在函数之后立即调用exit()函数,header()以避免执行以下代码。

根据文档,header()必须在发送任何实际输出之前调用它。


6

就像这里所说的其他人一样,发送带有以下内容的位置标头:

header( "Location: http://www.mywebsite.com/otherpage.php" );

但是您需要先执行此操作,然后再将其他任何输出发送到浏览器。

另外,如果您要使用它来阻止某些页面上未经身份验证的用户(如您提到的那样),请记住,某些用户代理将忽略此内容并继续在当前页面上继续,因此您需要死亡( )发送后。


but you need to do it before you've sent any other output to the browser. 太棒了!! 我一直在寻找关于为什么我不断收到标头已发送错误的记录。+1!
2014年

更笼统地说,您已经/完全停止了脚本/。die()只是做到这一点的一种方法。
MauganRa

6

这是我的想法:

恕我直言,重定向传入请求的最佳方法是使用位置标头,

<?php
    header("Location: /index.php");
?>

一旦执行了该语句并发送了输出,浏览器将开始重新定向用户。但是,请确保在发送标头之前没有任何输出(任何echo / var_dump),否则会导致错误。

尽管这是实现最初要求的快捷方法,但最终最终将是SEO灾难,因为这种重定向始终被解释为301/302重定向,因此搜索引擎将始终看到您的索引页作为重定向页面,而不是目标网页/主页。

因此,它将影响网站的SEO设置。


1
应该在header()之后立即使用exit()
EKanadily

@docesam ..同意的.. exit()应该在header()调用之后立即调用。但是我觉得,如果没有更多的输出到浏览器这个头后()语句,退出()可能不是必要的-只是我的意见
巴斯卡尔·普拉马尼克

是的,但是您必须解释一下,因为有人可以将您的代码行复制到他的脚本中,并且可能导致长时间盘旋在自己周围,以找出问题所在。
EKanadily

1
@BhaskarPramanik想象您必须快速锁上一扇门,但是随后您必须再次拉/推/砸它们,以确保它是否已经锁好
。–

5

使用PHP重定向的最佳方法是以下代码...

 header("Location: /index.php");

确保之后没有代码可以工作

header("Location: /index.php");

所有代码必须在上一行之前执行。

假设,

情况1:

echo "I am a web developer";
header("Location: /index.php");

它将正确重定向到位置(index.php)。

情况2:

return $something;
header("Location: /index.php");

上面的代码不会重定向到位置(index.php)。


已经有一个包含1085的答案,其中包含您提供的信息以及更多信息。
帕特里克·洪德

5

是的,可以使用PHP。我们将重定向到另一个页面。

尝试以下代码:

<?php
    header("Location:./"); // Redirect to index file
    header("Location:index.php"); // Redirect to index file
    header("Location:example.php");
?>

4

1.使用header,内置的PHP函数

a)没有参数的简单重定向

<?php
   header('Location: index.php');
?>

b)使用GET参数重定向

<?php
      $id = 2;
      header("Location: index.php?id=$id&msg=succesfully redirect");
  ?>

2.在PHP中使用JavaScript进行重定向

a)没有参数的简单重定向

<?php
     echo "<script>location.href='index.php';</script>";
 ?>

b)使用GET参数重定向

<?php
     $id = 2;
     echo "<script>location.href='index.php?id=$id&msg=succesfully redirect';</script>";
   ?>

某种程度上,javascript是唯一可以在网站的最终托管中工作的东西。我相信这是一个缓存问题,但是有了这个,我马上解决了。
cdsaenz

3

我们可以通过两种方式做到这一点:

  1. 当用户进入https://bskud.com/PINCODE/BIHAR/index.php时,然后重定向到https://bskud.com/PINCODE/BIHAR.php

    通过下面的PHP代码

    <?php
        header("Location: https://bskud.com/PINCODE/BIHAR.php");
        exit;
    ?>

    将以上代码保存在https://bskud.com/PINCODE/BIHAR/index.php中

  2. 如果满足任何条件,则重定向到另一页:

    <?php
        $myVar = "bskud";
        if ($myVar == "bskud") {
    ?>
    
    <script> window.location.href="https://bskud.com";  </script>
    
    <?php
        }
        else {
            echo "<b>Check the website name again</b>";
        }
    ?>

这是什么?请不要使用指向您自己网站的链接。第二个示例使用javascript重定向,而不使用PHP header()函数。
Scriptman '18

2

采用:

<?php
    $url = "targetpage"
    function redirect$url(){
        if (headers_sent()) == false{
            echo '<script>window.location.href="' . $url . '";</script>';
        }
    }
?>

1
您能解释一下代码的功能吗?您的答案由于篇幅和内容而被标记。
www139

2

有多种方法可以执行此操作,但是如果您愿意php,我建议使用该header()功能。

基本上

$your_target_url = www.example.com/index.php”;
header(“Location : $your_target_url”);
exit();

如果您想提高它的档次,最好在函数中使用它。这样,您便可以在其中添加身份验证和其他检查元素。

让我们通过检查用户级别来进行尝试。

因此,假设您已经在名为的会话中存储了用户的权限级别u_auth

在里面 function.php

<?php
    function authRedirect($get_auth_level,
                          $required_level,
                          $if_fail_link = www.example.com/index.php”){
        if ($get_auth_level != $required_level){
            header(location : $if_fail_link);
            return false;
            exit();
        }
        else{
            return true;
        }
     }

     . . .

然后,您将为要验证的每个页面调用该函数。

点赞page.php或其他任何页面。

<?php

    // page.php

    require function.php

    // Redirects to www.example.com/index.php if the
    // user isn’t authentication level 5
    authRedirect($_SESSION[‘u_auth’], 5);

    // Redirects to www.example.com/index.php if the
    // user isn’t authentication level 4
    authRedirect($_SESSION[‘u_auth’], 4);

    // Redirects to www.someotherplace.com/somepage.php if the
    // user isn’t authentication level 2
    authRedirect($_SESSION[‘u_auth’], 2, www.someotherplace.com/somepage.php”);

    . . .

参考文献;



2

使用标题功能进行路由

<?php
     header('Location: B.php');
     exit();
?>

假设我们要从A.php文件路由到B.php而不需要借助<button><a>。让我们看一个例子

<?php
if(isset($_GET['go_to_page_b'])) {
    header('Location: B.php');
    exit();

}
?>

<p>I am page A</p>
<button name='go_to_page_b'>Page B</button>

B.php

<p> I am Page B</p>

您能提供准确的解决方案还是好的解决方案?
Mehedi Abdullah

已经有很多解决方案。您的解决方案混合了HTML和PHP,没有PHP标签。其次,您在打印html代码后发送标头,因此它将不起作用。并且示例文件的名称不正确。您不应该将它们命名为A.php和B.php。我知道这只是示例,但您仍然应该注意命名约定。
塔吉尼(Tajni)

1

如果您在Apache上运行,则还可以使用.htaccess进行重定向。

Redirect 301 / http://new-site.com/

1

您可以尝试使用PHP header函数进行重定向。您将需要设置输出缓冲区,以便您的浏览器不会向屏幕发出重定向警告。

ob_start();
header("Location: " . $website);
ob_end_flush();

1
exit()应该在header()之后立即使用。另外,默认情况下,一段时间以来,默认情况下自动启用了外缓冲。
EKanadily

0

试试这个

 $url = $_SERVER['HTTP_REFERER'];
 redirect($url);
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.