在PHP中传递错误信息

7

我在我的网站上有一个登录表单,用来检查提交的用户名和密码。如果没有匹配项,用户将被送回登录页面,并显示相应的错误信息。进行重定向的调用是这样的:

header("location:../login.php?error_message=$error_message");

这个代码可以正常运行,但在浏览器的地址栏中看起来很杂乱(特别是出现描述性错误信息时)。有没有方法可以在不使用$_GET变量的情况下自动重定向?我曾考虑过使用$_SESSION变量,但那似乎不是最佳编程实践。谢谢阅读。

我个人使用 $_SESSION 变量。 - Jacob Tomlinson
使用 $_SESSION 是一个好的实践。 - Voitcus
我对PHP相对较新,并且一直对使用$_SESSION持怀疑态度,因为它类似于其他语言中易用但危险的全局变量...但我很高兴重新评估。谢谢! - Rogare
为什么要进行重定向?重定向意味着对用户来说是不必要的往返,因此会造成延迟。如果验证失败,为什么不直接再次输出登录表单呢? - Francois Bourgeois
@FrancoisBourgeois 我可能没有正确理解你的问题,但我需要重定向,因为登录检查是在一个文件(check_login.php)中进行的,而我的表单在另一个文件(login.php)中。当我由于用户错误重新加载表单时,我需要发送一条描述该错误的消息。 - Rogare
显示剩余2条评论
5个回答

7
有没有更简单的GET变量?
// something.php
header ("Location: foo.php?err=1");

然后在处理错误的页面中:


// foo.php
$errors = array (
    1 => "Hello, world!",
    2 => "My house is on fire!"
);

$error_id = isset($_GET['err']) ? (int)$_GET['err'] : 0;
if ($error_id != 0 && in_array($error_id, $errors)) {
    echo $errors[$error_id];
}

希望这可以帮助到您。

太好了,谢谢你包含数组和if语句的简写形式 - 这些会很方便! - Rogare
1
应该使用array_key_exists($error_id, $errors)而不是in_array($error_id, $errors)。 - mcriecken

1

对于表单验证,你有三种选项:

  1. 使用AJAX进行验证——这样就完全不需要重定向。
  2. 使用重定向和会话来存储错误消息以及输入的数据。
  3. 将重定向作为POST/Redirect/GET模式的一部分使用

就个人而言,我会为我的表单实施(1)和(3)。(1)是为了普通用户的方便,而(3)是为了与像我这样的偏执狂保持向后兼容性。

对于基于重定向的验证,使用会话确实是最干净的方式,因为它不会在任何情况下在历史记录中留下已提交的页面。然而,在存在基于AJAX的验证的情况下,它似乎有点过度杀鸡。


1
这个问题的大部分答案都是完全有效的... 怎么回事。 - mishmash

1
如果您不想使用会话,可以改用错误代码代替:
header('Location: ../login.php?error=' . urlencode($error_code));

然后,在 login.php 内部:
if (isset($_GET['error'])) {
    switch ($_GET['error']) {
        case 123: // ...
            break;
    }
}

可以使用查找数组代替笨重的开关来处理错误消息(可能与语言有关)。

顺便说一句,在头部重定向中使用相对URI不是推荐的做法,最好使用绝对URI(例如/login.php)或完全限定的URI(例如http://example.org/login.php)。


谢谢你提供关于相对URL的指针。我一直在使用它们,以便可以轻松地在离线和在线测试之间移动网站,但看起来前缀“/”应该可以解决问题。谢谢! - Rogare

0

-3

使用会话是一个不错的选择。您可以在显示错误后立即清除会话值。但如果您不想使用会话,可以修改您的URL如下。

// login failed
header("location:../login.php?status=0");

我更喜欢使用会话(session)。


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