【问题标题】:Can this work? Execute PHP once based on Variable + header redirect?这能行吗?基于变量+标头重定向执行一次PHP?
【发布时间】:2012-11-24 02:38:50
【问题描述】:

我想要做的是一个秘密链接,例如 website.com/?secret=yes 当他们访问这个页面时,我想从 URL 中删除这个变量,所以我有以下内容:

<?php
if(isset($_GET['secret']) && $_GET['secret'] === 'yes') {
    header('Location: http://website.com');
    $secret="yes"; <--take note this is what I'm testing 
}
?>

上面的代码将立即重定向,因此 url 中没有变量,我尝试使用 $secret="yes"; 自己制作这个变量;能够通过以下代码使用它:

<?php if( 'yes' === $secret ) : ?>
secret content here
 <?php endif; ?>

这可能吗?我怎样才能使我的代码工作?我不想使用会话,因为我希望它只执行一次,或者每次他们通过秘密链接访问时,如果他们在没有它的情况下访问时不会显示。

【问题讨论】:

  • 也许你可以做这样的事情stackoverflow.com/questions/4281900/…
  • @lucentx 我不使用任何通过 url 需要的表单。
  • 哦,那我猜你别无选择,只能使用 session 然后在使用后取消设置。

标签: php wordpress


【解决方案1】:

不,这行不通。变量不会通过重新加载页面持续存在。但是,您可以使用会话或 cookie 来执行此操作:

<?php
session_start();
if(isset($_GET['secret']) && $_GET['secret'] === 'yes') {
    $_SESSION['secret']="yes";
    header('Location: http://website.com');
    exit();
}
?>

<?php if( $_SESSION['secret']=='yes'){ 
unset($_SESSION['secret']); //unset so when the page reloads the secret data will be gone
?>
secret content here
 <?php } ?>

【讨论】:

  • 会话+1。用户完全不知道 Session 变量中有什么,只是知道某处有一个。只是不要忘记在设置位置标头后die()exit,为了便于阅读,理想情况下$_SESSION['secret']='yes' 应该在header() 之前。
  • 您可能还想在设置会话变量后exit;,以确保在不应该执行以下代码时不会执行以下代码。
  • 啊哈,这也很好,我不知道 SESSION 没有设置!
  • 非常感谢我将使用它的解决方案
  • @TimWithers 如果我在页面的几个部分有秘密内容,我应该使用更多会话吗?像 $_SESSION['secret2']="yes";并取消设置?
【解决方案2】:

您可以通过以下其他方式实现。

创建一个像 skey.txt 这样的文本文件

并编写如下代码:

 $filename = 'skey.txt';
if(isset($_GET['secret']) && $_GET['secret'] === 'yes') {
    $data = file_get_contents($filename);
    header('Location: http://localhost/'.$_SERVER['PHP_SELF']);
    file_put_contents($filename, $data."\n".$_SERVER['REMOTE_ADDR'].'secret=yes');
}

$filename = 'skey.txt';
if(isset($_GET['secret']) && $_GET['secret'] === 'yes') {
    $data = file_get_contents($filename);
    file_put_contents($filename, $data."\n".$_SERVER['REMOTE_ADDR'].'secret=yes');
    header('Location: http://localhost/'.$_SERVER['PHP_SELF']);
}

当您将被重定向到页面时。你可以检查如下:

$data = file($filename);
if(!empty($data) && in_array($_SERVER['REMOTE_ADDR'].'secret=yes', $data)) {
    echo 'hello';
    $getlines = array_keys($data, $_SERVER['REMOTE_ADDR'].'secret=yes');
    foreach($getlines as $lkey) {
        unset($data[$lkey]);
    }

    file_put_contents($filename, implode("\n", $data));
}

我认为它对你有用......

【讨论】:

  • 这不起作用,因为在其他人访问了秘密 URL 后,访问该站点的任何人都可以使用相同的文件。如果你真的想走这条路,你可以使用 IP 地址或其他一些独特的细节作为文件名的(部分)。或者,您可以像在其他答案中一样使用 Session,并更简单地获得更好的结果。
【解决方案3】:

由于 HTTP 的无状态特性,您需要以一种或另一种方式传递秘密令牌。如果您想确保一旦您可以对一些唯一信息(IP、用户代理等)进行 MD 哈希并传递它,就可以访问内容。您应该能够将变量添加到标头调用中:

header('Location:http://website.com/?secret=yes');

请注意,您将使用

检查值
<?php if ($_GET['secret'] == "yes"): ?>


// secret content
<?php endif; ?>

这不是一个安全的解决方案,因为任何人都可以将 ?sectet=true 附加到链接,哈希会更好,因为它可以是事物的组合。如果您决定使用哈希,请确保您使用的是盐,否则您可能会面临碰撞/彩虹表攻击的风险

【讨论】:

  • 哈希似乎是一种有趣的方法我的网站已经很重了,这种方法会更慢吗?
  • 并不显着,实际上 SESSIONS 在内部使用哈希,但是您曾说过您不想使用 SESSIOS。我正在谈论的技术称为基于令牌的身份验证。话虽如此,Tim 的上述出色解决方案似乎是最简单的路线
猜你喜欢
  • 2013-01-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-11-06
  • 2014-08-25
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多