ChatGPT解决这个技术问题 Extra ChatGPT

如何在 PHP 中进行重定向?

是否可以通过使用 PHP 将用户重定向到不同的页面?

假设用户转到 www.example.com/page.php,我想将他们重定向到 www.example.com/index.php,如果不使用元刷新,我该怎么做?可能吗?

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

您可以在 PHP 中更新标头:header
@Sam:就像侧节点一样,不要通过重定向实现任何类型的 protection from unauthorized users;这不是应该做的事情;)
@Strae 使用重定向保护页面有什么问题?那么最好的方法是什么?
@PravindaAmarathunga 重定向是元素之一,但不是唯一的元素。只要确保受保护的元素根本不会为未经授权的用户输出;浏览器的重定向可以在客户端禁用,例如:如果浏览器不做重定向并且原始页面正常输出,用户会看到什么? CMS 通常会进行重定向并且不会打印出受保护的项目,而是用礼貌的消息替换正常输出。
@PravindaAmarathunga 检查来自 markus 答案的链接:thedailywtf.com/Articles/WellIntentioned-Destruction.aspx

2
24 revs, 15 users 65%

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

1. 基本答案

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

header('Location: '.$newURL);

2. 重要细节

死()或退出()

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

为什么应该使用 die()exit()The Daily WTF

绝对或相对 URL

自 2014 年 6 月起,可以使用绝对 URL 和相对 URL。请参阅已替换旧 RFC 2616RFC 7231,其中只允许使用绝对 URL。

状态码

PHP 的“Location”-header 仍然使用 HTTP 302-redirect 代码,这是一种“临时”重定向,可能不是您应该使用的。您应该考虑 301(永久重定向)或 303(其他)。

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

3. 文档

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

PHP手册说什么

维基百科说什么

W3C 怎么说

4. 替代品

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

5. 辅助函数

此函数不包含 303 状态代码:

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

    exit();
}

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

这更灵活:

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

6. 解决方法

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

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

甚至是 JavaScript 重定向。

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

这个答案的一些问题:303 可能不是“正确”的状态码。例如,Google 可能需要 301。其次,header('Location: '.$newURL); 必须在任何 HTML(或文本)被传递到浏览器之前,否则它将无法正常工作。
可悲的是,每天的 WTF 故事很常见。无论如何,导致问题的不是丢失的模具,而是糟糕的设计。在 99.9% 的情况下,猛烈地关闭进程是错误的。一个常见的、更干净的解决方案(不是我最喜欢的)是抛出一个 RedirectionException 并在您的应用程序入口点捕获它。之后,您可以进行所有“after *”调用(记录/关闭连接/什么)
并非所有浏览器都支持 http-equiv="Location"。您应该改用 refresh<meta http-equiv="refresh" content="0;url=http://example.com/">
除非你是认真的,否则永远不要发出 301。 301 意味着永久,永久意味着永久,这意味着它将被用户代理缓存,这意味着长时间的、充满咖啡因的夜晚盯着应用程序日志想知道你是否发疯了,因为你发誓应该调用或更新某些页面并且你发誓对上帝来说,它可以在您的机器上运行,但不能在客户端的机器上运行。如果您绝对必须调用 301,请在资源上放置缓存控制 max-age。你没有无限的智慧,你不应该像你那样行事。
但是有理由使用 die 而不是 exit 吗?出口似乎更干净,更合适。
P
Peter Mortensen

使用 header() function 发送 HTTP Location header

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 执行。


die() 或 exit() 适用于不尊重“Location: ...”标头的客户
@clawr:不,exit() 是为了防止页面显示剩余的内容(认为受限页面)。 vartec 是对的,它与 HTTP Location 标头无关,您不需要exit。我选择将其包含在我的答案中,因为对于不知道如何进行 simple 重定向的人来说,与其不执行一个简单但关键的步骤,不如安全行事能够利用高级过程控制。
但是尊重标头的浏览器会在您的脚本仍在执行时离开页面并关闭连接。这太糟糕了。 PHP 将继续执行脚本一段时间(这就是您的代码执行的原因),但可能会在执行过程中随机中止它,从而使内容损坏。调用 ignore_user_abort() 可以防止这种情况发生,但老实说我不值得。继续编写 HTML 内容(尽管可能没用),但不要在 header('Location:'); 之后写在磁盘或数据库上的内容。如果可能,在重定向之前写入磁盘。 [另外:url 应该是绝对的。]
在浏览器检测到 HTTP 协议之前有什么方法可以重定向吗?我需要重定向的原因是因为我无法为我的所有域获得足够的 SSL 证书。我会使用 .htaccess 来重定向,但我需要一种方法来以某种方式将哪个域传递到最终域?
R
Rifky Niyas
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()


并且不要忘记输出缓冲,否则您最终会得到“标头已发送”。
...并且不要忘记打印出类似“您将在 $n 秒内被重定向到 $nepage,如果重定向没有发生,请单击此处的 $link”之类的打印输出某些 broser 和某些浏览器的设置可能会导致重定向失败。
@DaNieL:这种类型的重定向不会花费“$n 秒”。如果它真的发生,它将是即时的,任何符合要求的浏览器都应该处理它。我认为您正在考虑人们在不了解时使用的“元刷新”重定向。
@rmeador ... 适用于较旧的浏览器和专业浏览器。你应该首先做你的 Location 标头,如果失败有一个带有“你将在 x 秒内被重定向到页面”的元重定向,并带有一个链接,以防元重定向失败。这是进行重定向的正确且安全的方式。
安德鲁:HTTP浏览器怎么能不尊重位置:?
C
Community

使用 echo 从 PHP 输出 JavaScript,这将完成这项工作。

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

除非您缓冲页面输出然后稍后检查重定向条件,否则您无法在 PHP 中真正做到这一点。那可能太麻烦了。请记住,标题是从页面发送的第一件事。大多数重定向通常在页面后面需要。为此,您必须缓冲页面的所有输出并稍后检查重定向条件。此时,您可以重定向页面用户 header() 或简单地回显缓冲的输出。

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

What is output buffering?


简单而中肯的答案!非常适合简单的页面重定向!
@hmd,如果禁用了 javascript 怎么办?
错,即使没有缓冲,您也可以(并且应该)在 PHP 中执行此操作:在设计良好的页面中,所有相关的 PHP 处理都应该在任何 HTML 内容发送给用户之前进行。这样 PHP 重定向就可以正常工作。
javascript 不会自动激活,实际上这只适用于现代浏览器。另外,问题是关于 php,而不是 JS
是的,这是对一个完全不同的问题的答案。您无法控制客户端,假设您这样做很危险。
J
Juned Ansari

1.没有标题

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

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

2. 使用带有exit()的头函数

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

但是如果你使用 header 函数,那么有时你会得到 "warning like header already send" 来解决在发送 headers 之前不回显或打印的问题,或者你可以在发送 headers 之后简单地使用 die()exit()头功能。

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>"; ?>测试它,它做了我想要的
n
nickf

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

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

离开那条重要的第二条线可能会让您最终进入The Daily WTF。问题是浏览器没有 尊重页面返回的标题,因此在忽略标题的情况下,页面的其余部分将在没有重定向的情况下执行。


在杀死脚本之前给用户一些输出是什么?你知道,人们喜欢知道发生了什么...
您假设脚本除了重定向之外没有任何关系。这可能根本不是真的。
@DaNieL:将其更改为死(“停止忽略我的标题!”)
我喜欢您对 die(); 的简单解释 - 如果您不这样做,如果您使用它,用户可能会暂时看到完整的页面;用户将被重定向并且不会显示临时内容故障 + 1
发送标头后可能会发生有用的活动,即不向浏览器发送任何内容但记录活动或完成记录事务的活动。出于这个原因,死亡/退出的需要取决于脚本。
D
Dirk Diggler

利用:

<?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()


它仅用作代码中的第一条语句。如果您有逻辑并且重定向基于此。使用 meta http-equiv refresh 或 window.open javascript 比。 (复制)
它不必是代码中的第一条语句。它只需要在任何输出之前。在开始打印输出之前组织您的代码以执行所有逻辑 - 然后它可能应该一次性打印准备好的输出。
A
Asuquo12

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

<?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 地址和用户会话的日志访问权限,因为我不想打扰我的数据库。


L
Luke

其中许多答案是正确的,但他们假设您有一个绝对 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

A
Abdur Rehman

使用以下代码:

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

D
Daniel A. White

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


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

我已经回答了这个问题,但我会再回答一次,因为与此同时我了解到,如果您在 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)


A
Abdur Rehman

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

<?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 代码将由服务器解释,即使访问者移动到重定向中指定的地址也是如此。在大多数情况下,这意味着您需要一个方法来遵循 exit() 函数的 header() 函数,以减少服务器的负载:

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

为什么是 (接近第二段的末尾)?你的意思是&para(所以整个读作mypage.php?param1=val1&param2=val2))? (HTML 实体 para)是“¶” - 也许某些外部程序进行了转换?)。
P
Peter Mortensen

利用:

<?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.
?>

J
Jsowa

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

试试下面的代码:

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

M
Mr. Coderx
header("Location: https://www.example.com/redirect.php");

直接重定向到此链接 https://www.example.com/redirect.php

$redirect = "https://www.example.com/redirect.php";
header("Location: $redirect");

首先获取 $redirect 值,然后重定向到 [value],例如:https://www.example.com/redirect.php


H
Henrik Paul

在语义网的前夜,正确性是需要考虑的事情。遗憾的是,PHP 的“Location”-header 仍然使用 HTTP 302-redirect 代码,严格来说,它并不是最好的重定向代码。它应该使用的那个是 303 那个。

W3C 对 mention 表示友好,认为 303 标头与“许多 HTTP/1.1 之前的用户代理”不兼容,这相当于没有当前使用的浏览器。所以,302 是一个遗物,不应该被使用。

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


P
Peter Mortensen

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

self.location="http://www.example.com/index.php"; window.location.href="http://www.example.com/index.php"; document.location.href = 'http://www.example.com/index.php'; window.location.replace("http://www.example.com/index.php");


Javascript 在客户端上运行,这可能是也可能不是您要查找的内容。
P
Peter Mortensen

是的,您可以使用 header() 功能,

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

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

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


B
B001ᛦ

要在 php 中重定向,请使用:

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


B
Brent

就像这里的其他人所说,发送位置标头:

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

但是您需要在将任何其他输出发送到浏览器之前执行此操作。

另外,如果您要使用它来阻止未经身份验证的用户访问某些页面,就像您提到的那样,请记住某些用户代理 will ignore this 并继续在当前页面上,所以您需要死( ) 发送后。


but you need to do it before you've sent any other output to the browser. 太棒了!!一直在寻找关于为什么我一直收到标头已发送错误的几分钟。 +1!!
更一般地说,你有/完全停止你的脚本/。 die() 只是其中一种方法。
P
Peter Mortensen

以下是我的想法:

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

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

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

尽管这是实现最初要求的快速而肮脏的方式,但最终会成为 SEO 灾难,因为这种重定向始终被解释为 301 / 302 重定向,因此搜索引擎将始终看到您的索引页面作为重定向页面,而不是登录页面/主页。

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


exit() 应该在 header() 之后立即使用
@docesam .. 同意 .. exit() 应该在 header() 调用之后立即调用。但是我觉得,如果在这个 header() 语句之后没有更多的输出到浏览器,exit() 可能没有必要 - 只是我的意见
是的,但您必须解释这一点,因为有人可以将您的代码行复制到他的脚本中,这可能会导致他长时间在自己周围盘旋以找出问题所在。
@BhaskarPramanik 想象你必须快速锁上一扇门,但是你必须再次拉/推/砸它们以确保它是否已经锁定......
P
Peter Mortensen

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

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

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

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

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

认为,

情况1:

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

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

案例二:

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

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


已经有一个包含 1085 的答案,其中包含您提供的信息以及更多信息。
R
Roman

您可以尝试使用

header('Location:'.$your_url)

有关更多信息,您可以参考 php official documentation


P
Peter Mortensen

<强> 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 位是网站最终托管中唯一起作用的东西;我相信这是一个缓存的问题,但我马上就解决了。
J
Jsowa

使用标头功能进行路由

<?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>

已经有很多解决方案了。您的解决方案混合了没有 PHP 标记的 HTML 和 PHP。其次,您在打印 html 代码后发送标头,因此它将不起作用。示例文件的名称不好。您不应该将它们命名为 A.php 和 B.php。我知道这只是一个例子,但你仍然应该关心命名约定。
P
Peter Mortensen

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

当用户访问 https://bskud.com/PINCODE/BIHAR/index.php 然后重定向到 https://bskud.com/PINCODE/BIHAR.php 通过下面的 PHP 代码 将上述代码保存在 https://bskud.com/PINCODE/BIHAR/index.php 当任何条件为真时重定向到另一个页面: 再次检查网站名称"; } ?>


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

利用:

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

你能解释一下你的代码的功能吗?您的答案因其长度和内容而被标记。
P
Peter Mortensen

有多种方法可以做到这一点,但如果您更喜欢 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”);

    . . .

参考;

http://php.net/manual/en/function.header.php


P
Paulo Boaventura

我喜欢数秒后的那种重定向

<?php

header("Refresh: 3;url=https://theweek.com.br/índex.php");