PHP:在header("Location: ")之后使用exit();或die();

20

我有一个用户登录/注册系统,它只是使用

// execute queries, set cookies, etc. here
header("Location: " . getenv("HTTP_REFERER"));

最近我读了一篇关于exit();die();的帖子,但我不知道我应该使用它们。据我所知,它们会终止PHP程序?这是正确的吗?我应该怎么做才能达到这个效果?是否只需要在每个header()执行之后直接添加其中一个函数即可?

我有AJAX和jQuery在login.php/register.php中进行读取,这会受到影响吗?

编辑:除了在header()之后,我还应该在哪些地方使用exit();die();函数?exit();在PHP中更常用,而die();在Perl中更常用吗?


“AJAX通过register.php读取”是什么意思?你能贴一些代码吗? - konsolenfreddy
我的register.php检查是否提交了一个表单,然后读取输入内容,并使用AJAX $.post()返回在register.php中发现的任何错误到HTML页面上供用户查看。 - Aaron
只要使用其中一个,使用 die 还是 exit 都没有太大关系。 - Grexis
我倾向于在正常脚本行为的一部分使用exit,而在调试时使用die。我见过其他人也使用这个约定。它们做相同的事情,但是这个约定很有用。 - Louis-Philippe Huberdeau
我喜欢一行代码,所以 die(header("location: {$url}")); - s3c
6个回答

39

我也一直在寻找答案,以下是我发现的:

为什么使用die()或exit():

如果在header('Location: http://something')之后没有放置一个die()或exit(),那么您的脚本可能会继续执行,导致意外行为。这可能会导致泄露您实际上要通过重定向(HTTP 301)防止的内容。尽管对于最终用户来说可能没有直接可见的影响(由于301),但可能无法直接看到上述情况。总之,exit()和die()函数可以停止脚本的运行。

区别:

我也想知道这两个函数之间的区别,因为它们似乎没有区别。然而,在PHP中,Header输出存在明显的区别。 在下面的示例中,我选择使用不同的头部,但为了展示exit()和die()之间的区别,这并不重要。

Exit()演示

<?php
    header('HTTP/1.1 304 Not Modified');
    exit();
?>

结果为:

HTTP/1.1 304 Not Modified 
Connection: Keep-Alive 
Keep-Alive: timeout=5, max=100

Die() 的实际应用

<?php
    header('HTTP/1.1 304 Not Modified');
    die();
?>

结果为:

HTTP/1.1 304 Not Modified 
Connection: close

区别

die()会关闭连接,而exit()则不会。它取决于你是否想保持连接的开启或关闭,这与性能有关。两者都有优点和缺点,具体取决于您的特定需求。

维基百科上关于HTTP持久连接的文章


我的HTTP知识在本学期的这个阶段有点模糊 - 当我们执行301时,浏览器会(通常情况下;即正确的规范)关闭连接并打开另一个GET请求,不是吗?还是它会使用现有的连接再次请求? - lol
1
你也可以使用 exit(header('Location: xxxxx.php')); 进行连接。 - mowgli
14
"exit" 和 "die" 在 PHP 中是相同的。 - mpen
3
刚刚进行了测试,exitdie 的作用方式相同,它们都会断开连接。 - Grzegorz Adam Kowalski
4
由于“die”和“exit”确实是完全相同的,所以我已将其下降投票。 - s3c
Die() 相当于 exit()。它是否关闭连接取决于其他条件。 - Eugene Zakharenko

11

4

答案已经被接受,但似乎每个人都忽略了问题中显而易见的 WTF:

header("Location: " . getenv("HTTP_REFERER"));
  1. 用户代理返回referer是可选的

  2. referer很容易被伪造

  3. 没有方法告诉用户登录失败了

  4. 没有HTTP语义化通信来表示验证失败

  5. 虽然HTTP_REFERER环境变量应该与请求头变量相同,但它在RFC 3875中未指定,因此即使在请求中向Web服务器提供,getenv("HTTP_REFERER")可能会返回不同的值。


在我的login.php中,我让它检查用户是否使用正确的凭据成功登录 - 如果是,则设置一个cookie - 然后header("Location");到引荐页面。通过这种方式,无论他们在网站上的哪个位置,当他们登录时,它都会将他们带回他们登录的页面,而不是将他们带到主页或login.php。那么,有比这更好的方法吗? - Aaron
1
在渲染登录页面之前,可以通过设置cookie来存储目标页面的URL,或者将URL作为$_GET变量传递,也可以将目标URL存储在会话中。 - symcbean

2

好的,自上次回答以来已经有很长时间了。无论如何:D我偶然发现一个类似的问题,并看到我的解决方案是:

die( Header( "Location: mytarget.php?arg1=foobar" ) );

一石二鸟 - 对我来说似乎可行。

这将把header()函数的返回值存储在一个临时变量中,并传递给die()。它可以正常工作,因为header()的返回值总是null。另一个差异是它不允许调试器在die()header()之间创建断点。 - ksiimson

0
for($i = 0; $i < 10; $i++)
{
    if ($i == 2)
    {
        exit("\n Using exit(), We are done");
    }
}

现在让我们使用die();函数来看同样的例子。

for($i = 0; $i < 10; $i++)
{
    if ($i == 2)
    {
        die("\n Using die(), We are done");
    }
}

每个的输出将分别为:“使用exit(),我们完成了。使用die(),我们完成了。”现在让我们尝试使用它们来输出一个数字。
for($i = 0; $i < 10; $i++)
{
    if ($i == 2)
    {
        exit(-1);
    }
}

通过使用die()函数查看相同示例的输出结果。

for($i = 0; $i < 10; $i++)
{
    if ($i == 2)
    {
        die(-1);
    }
}

这些示例是使用文本编辑器进行编辑的。上述两种情况的输出都是“工具完成,退出代码为-1”。

因此,“在php中die()和exit()之间有什么区别”的诚实答案是 - 这两个函数之间没有任何明显的区别。它们都是相同的,其中一个是另一个的别名。如果你们中的任何人能够找到真正的可见差异,那么我将感激您在此博客的评论部分发布它。

下次再见,愉快的PHP编程!


-1

当脚本结束时调用header(),无需调用exit()或者die(),因为:

与服务器的链接将在脚本执行结束时关闭,除非通过显式调用mysql_close()提前关闭。- php.net/function.mysql-connect


3
在发送“Location”头之后,一定要使用“exit”或“die”,因为无法保证浏览器会遵循该头信息。建议详细阅读可能出现的问题。 - maryisdead

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接