【问题标题】:why does $_GET not work in header-function?为什么 $_GET 在标头函数中不起作用?
【发布时间】:2013-05-17 08:58:18
【问题描述】:

我已经对这个问题有疑问,但还有一个属于 $_GET 和 header-function 的问题:

我有一个多语言网站。当调用一个不存在的页面时,.htaccess会引用根目录下的404.php

.htaccess 看起来像这样:

ErrorDocument 404 /404.php

根方向的404.php 只是查看SESSIONCOOKIE 设置的默认语言,并引用语言子目录/language/404.php

404.php 看起来像这样:

include_once "scripts/pref_language.php";

if (isset ($_GET['uri']) ){
    $get = $_GET['uri'];

    header("Location: /$pref_language/404.php?uri=$get");
    exit;
}

$url = urlencode($_SERVER['REQUEST_URI']);

header("Location: /$pref_language/404.php?uri=$url");

参考语言子目录,贴出来的URL是这个样子的,参数uri还是不一样的:

http://www.example.com/english/404.php?uri=somedata

或使用其他语言:

http://www.example.com/german/404.php?uri=somedata

/english/404.php的代码如下:

<?php
error_reporting(E_ALL);
ob_start();
session_start();
header ("Content-Type: text/html; charset=utf-8");

include_once "../scripts/db_connect.php";
include_once "../scripts/functions.php";
include_once "../scripts/browser_identification.php";
include_once "../scripts/pref_language.php";

...some text variables in its specific language

include_once "../templates/template_404.php";
?>

模板只是一些 HTML 样式。将包含在template_404.php 中的页脚是发送数据的主要吸引力。在该页脚中,可以选择更改语言设置和在语言路径之间切换。如果要提交表单,SESSIONCOOKIE 将被更改,并且页面将启动标题功能。

下面是来自页脚的代码:

if (isset($_GET['uri']) ) {
    $uri = urlencode($_GET['uri']);
    echo "TEST URI: $uri";
}

...

$basename = basename($_SERVER['SCRIPT_NAME'], ".php"); 

if ($basename === "index") {
    $form_action = rtrim($_SERVER['PHP_SELF'], 'index.php');
} else{
    $form_action = htmlentities($_SERVER['PHP_SELF']);
}

...

if ( isset($_POST['pref_lang']) ) {

    $content = $_POST['pref_lang'];

    if ($content === "german") {

        if ($basename === "about") {
            $basename = "info";
        } else if ($basename === "contact") {
            $basename = "kontakt";
        }           
    }
    $_SESSION['pref_language'] = $_POST['pref_lang'];

    setcookie('pref_language', '', time()- 999999, '/', '.example.de' );
    setcookie('pref_language', $content, time()+60*60*24*365, '/', '.example.de');

    if ($basename === "404"){

        header("Location: ../$content/404.php?uri=$uri");

    } else {

        header("Location: ../$content/$basename");  
    }
}
?>
<div id="data">
    <fieldset>
        <ul>
            <li>
                <form action="<?php echo $form_action;?>" method="post">      
                    <input type="submit" id="german" name="pref_lang" value="german"/><label for="german">german</label>
                </form>
            </li>
        </ul>
    </fieldset>
</div>

问题是当一个页面有URL的时候

http://www.example.com/**english**/404.php?uri=somedata

我将提交$_POST 将语言更改为德语,例如:

http://www.example.com/**german**/404.php?uri=somedata

例如,$_GET['uri'] 将为空,URL 看起来像:

http://www.example.com/**german**/404.php?uri=

启动头功能后。我尝试回显该行而不是标题,我将收到一条消息,指出 uri 未定义。

Undefined variable: uri in /customers/7/4/1/example.com/httpd.www/scripts/footer_en.php on line 102
Location: ../english/404.php?uri=

奇怪的是,当我在发送$_POST 之前调用该页面并查看该站点的源代码时,变量$uri 将正确读出$_GET 参数,但稍后它会正确读出在标头功能中不再起作用。问题是为什么这不起作用?

因此,如果有人能告诉我如何处理这个问题,那就太好了。我真的很感激。

非常感谢。

更新:

我试图将 $_GET 参数保存到 SESSION 中,但是在发布表单并重定向到其他语言站点时,SESSION 的内容似乎是错误的,因为它不会是 $_GET参数而不是那个来自html头的css链接的东西,比如css/colorbox.css

目前我尝试通过将form action 设置为该值来获取它:

...
if ($basename === "index") {
    $form_action = rtrim($_SERVER['PHP_SELF'], 'index.php');
}  

if ($basename === "404") {
    $form_action = "";
}

if  ($basename !== "index" AND $basename !== "404") {
    $form_action = htmlentities($_SERVER['PHP_SELF']);
}
...

<li>
    <form action="<?php echo $form_action. ( (isset($_GET['uri']) ) ? "/english/?uri=".urlencode($_GET['uri']) : "" );?>" method="post">
        <input type="submit" id="english" name="pref_lang" value="en"/><label for="en">englisch</label>
    </form>
</li>

【问题讨论】:

  • GET 会消失,因为提交后页面会刷新并且没有给出 GET 参数。您可以将其存储在会话变量中吗?
  • 老实说:TL;DR。但对我来说相当明显的是,您需要对值进行正确的 URL 编码,然后再将其作为查询参数再次附加。 $_GET 中的值已经自动进行 URL 解码。见blog.lunatech.com/2009/02/03/…
  • @Marijke 当我将通过 SESSION 完成时,其内容是完整的,而不是应有的内容。由于某种原因,会话将类似于 css/colorbox.css ...这是我不明白的。
  • 为什么要重定向到特定语言的 404 模板? include 不适合你吗?

标签: php html variables get global-variables


【解决方案1】:

如果我理解正确,你想从:

http://www.example.com/**english**/404.php?uri=somedata

收件人:

http://www.example.com/**german**/404.php?uri=somedata

使用表单提交按钮。为此,您需要在标签上设置操作以包含当前页面中的 uri,以便将其传递到新的语言 404 页面。

<form action="<?php echo $form_action . ((isset($_GET['uri']))?$_GET['uri']:""); ?>" method="post">

【讨论】:

  • 您好,感谢您回答这个问题。我尝试使用你的方法,但它并没有像我想象的那样奏效。我更新了我的问题。谢谢。
  • 或许把上面代码创建的url贴出来让我调整一下?
  • 好的,您的代码会创建该网址:http://www.example.com/english/404.php/english/404
  • 您的代码似乎只是替换了$_GET 参数,以防设置。如果将代码更改为:&lt;form action="&lt;?php echo $form_action . ( (isset($_GET['uri']) ) ? "?uri=".$_GET['uri'] : "" ); ?&gt;" method="post"&gt;,似乎root/404.php 将被调用,而URL 只是:http://www.example.com/english/404
【解决方案2】:

扩展 jwheel12 的答案。表单操作将作为没有 http:// 的相对路径工作。因此将您的 action="" 附加到当前 URL。尽可能使用绝对路径。

<form action="http://www.example.com/english/404.php<?php echo ( $_SERVER['QUERY_STRING'] )?
"?".$_SERVER['QUERY_STRING']) : "" );?>" method="post">

或者您可以将变量作为隐藏输入类型传递

foreach ($_GET as $key => $value) {
echo '<input type="hidden" name="'.$key.'" value"'.$value.'">';
}

我喜欢使用像下面这样的自定义函数,它将遍历数组“$ary”中的所有项目并返回最后一个不为空的项目。

$myVariable = getVar('myVariable');

function getVar($var) {
$ary = array('_SESSION', '_COOKIE', '_POST', '_GET');
foreach ($ary as $a) {
    if ($GLOBALS[$a][$var] != '') {
        $return = $GLOBALS[$a][$var];
    };
};
return $return;
};

最后,如果您只想在两种语言之间切换,您可以使用 preg_replace 和超链接

$currentURL = "http://$_SERVER[HTTP_HOST]$_SERVER[REQUEST_URI]";
if (preg_match('/german/i', $currentURL)){
$newURL = preg_replace('/german/i', 'english',$currentURL);
$currentLanguage = "german";
}
else {
$newURL = preg_replace('/english/i', 'german',$currentURL);
$currentLanguage = "english";
};
echo '<a href ="'.$newURL. '">'($currentLanguage == "german"? "View in English": "Sehen Sie auf Deutsch";). '</a>';

【讨论】:

  • 您好,感谢您回答这个问题。我用你的提示来获取这个,但仍然有一个小问题。当我发布表格时,将显示正确的语言,但页脚本身将是错误的。 session/cookie 上的更改生效,所以我猜该站点将被重新加载,但页脚不会。谢谢。
【解决方案3】:

来自文档:

Note:

HTTP/1.1 requires an absolute URI as argument to » Location: including the scheme, hostname and absolute path, but some clients accept relative URIs. You can usually use $_SERVER['HTTP_HOST'], $_SERVER['PHP_SELF'] and dirname() to make an absolute URI from a relative one yourself:

<?php
/* Redirect to a different page in the current directory that was requested */
$host  = $_SERVER['HTTP_HOST'];
$uri   = rtrim(dirname($_SERVER['PHP_SELF']), '/\\');
$extra = 'mypage.php';
header("Location: http://$host$uri/$extra");
exit;
?>

此外,我认为 FireFox 和其他 HTTP 1.1 投诉浏览器需要 http://。

或许可以试试类似的方法?

【讨论】:

    【解决方案4】:

    保持在同一个页面上会不会更容易,但内容会发生变化? 如果语言是英语,则加载英语 404 信息,对于德语,加载德语等。

    只是一个想法。我可以想象它对于大型网站可能不实用。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-03-08
      • 2017-03-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-12-21
      相关资源
      最近更新 更多