PHP $_GET和未定义的索引

55
我在一个不同的PHP服务器上运行我的脚本时出现了新问题。
在我的旧服务器上,即使没有声明“s”参数,以下代码似乎也可以正常工作。
<?php
 if ($_GET['s'] == 'jwshxnsyllabus')
echo "<body onload=\"loadSyllabi('syllabus', '../syllabi/jwshxnporsyllabus.xml',         '../bibliographies/jwshxnbibliography_')\">";
if ($_GET['s'] == 'aquinas')
echo "<body onload=\"loadSyllabi('syllabus', '../syllabi/AquinasSyllabus.xml')\">"; 
 if ($_GET['s'] == 'POP2')
echo "<body onload=\"loadSyllabi('POP2')\">";
elseif ($_GET['s'] == null)
echo "<body>"
?>

但是现在,在我的本地机器上(XAMPP - Apache),当未定义s的值时,我会收到以下错误。

Notice: Undefined index: s in C:\xampp\htdocs\teaching\index.php on line 43
Notice: Undefined index: s in C:\xampp\htdocs\teaching\index.php on line 45
Notice: Undefined index: s in C:\xampp\htdocs\teaching\index.php on line 47
Notice: Undefined index: s in C:\xampp\htdocs\teaching\index.php on line 49

我希望脚本在声明了s的值时调用特定的JavaScript函数,但如果没有声明任何值,则希望页面正常加载。

你能帮助我吗?


2
新服务器已启用调试通知。请检查 php.ini 中的 error_reporting。在生产服务器上,它不应该是 E_ALL - mario
1
你可以简单地使用 isset 函数来检查是否已正确接收。 - Anupam Haldkar
12个回答

85

由于错误报告未包含先前服务器的通知,所以您没有看到错误。

在尝试使用之前,您应该检查索引 s 是否实际存在于 $_GET 数组中。

类似以下代码将足够:

if (isset($_GET['s'])) {
    if ($_GET['s'] == 'jwshxnsyllabus')
        echo "<body onload=\"loadSyllabi('syllabus', '../syllabi/jwshxnporsyllabus.xml',         '../bibliographies/jwshxnbibliography_')\">";
    else if ($_GET['s'] == 'aquinas')
        echo "<body onload=\"loadSyllabi('syllabus', '../syllabi/AquinasSyllabus.xml')\">"; 
    else if ($_GET['s'] == 'POP2')
        echo "<body onload=\"loadSyllabi('POP2')\">";
} else {
    echo "<body>";
}

如果您计划添加更多情况,使用switch语句可以使您的代码更易读。

switch ((isset($_GET['s']) ? $_GET['s'] : '')) {
    case 'jwshxnsyllabus':
        echo "<body onload=\"loadSyllabi('syllabus', '../syllabi/jwshxnporsyllabus.xml',         '../bibliographies/jwshxnbibliography_')\">";
        break;
    case 'aquinas':
        echo "<body onload=\"loadSyllabi('syllabus', '../syllabi/AquinasSyllabus.xml')\">";
        break;
    case 'POP2':
        echo "<body onload=\"loadSyllabi('POP2')\">";
        break;
    default:
        echo "<body>";
        break;
}

编辑:顺便说一句,我写的第一组代码完全模拟了你的代码的意图。在?s=中出现异常值的预期结果是没有<body>标签输出,还是这是一个疏忽?请注意,使用开关将通过始终默认为<body>来修复此问题。


2
比我更好的解决方案,给予+1。 - Awais Qarni

8

养成使用isset检查变量是否可用的习惯,例如:

if (isset($_GET['s']))
{
     //do stuff that requires 's'
}
else
{
     //do stuff that doesn't need 's'
}

你可以禁用通知报告,但处理它们是良好的卫生习惯,并且可以使您发现可能会被忽略的问题。


8

我经常使用一个实用的函数/类来从 $_GET 和 $_POST 数组中读取数据,以避免不断地检查索引是否存在... 像这样的代码就可以解决问题。

class Input {
function get($name) {
    return isset($_GET[$name]) ? $_GET[$name] : null;
}

function post($name) {
    return isset($_POST[$name]) ? $_POST[$name] : null;
}

function get_post($name) {
    return $this->get($name) ? $this->get($name) : $this->post($name);
}
}
$input = new Input;
$page = $input->get_post('page');

3

我在使用xampp本地环境时遇到了同样的问题。现在我使用以下参数组合:

// Report all errors except E_NOTICE
// This is the default value set in php.ini
error_reporting(E_ALL ^ E_NOTICE);

php.net: http://php.net/manual/zh/function.error-reporting.php

这是PHP官方网站上有关error_reporting()函数的页面。该函数用于设置PHP报告哪些错误级别。在开发过程中,开启所有错误报告可以帮助找出代码中的问题。但在生产环境中,应该关闭某些错误报告以提高性能和安全性。


2

在你盲目访问数组之前,我建议你先检查一下它们:

if(isset($_GET['s'])){
    if ($_GET['s'] == 'jwshxnsyllabus')
        /* your code here*/
}

另一个(快速)解决方法是通过在脚本顶部写入以下内容来禁用错误报告:

error_reporting(0);  

在您的情况下,很有可能您的另一台服务器将错误报告配置设置为默认值0。
通过将error_reporting调用参数设置为0,您将关闭所有通知/警告和错误。更多详情请查看php手册
请记住,这只是一个快速修复方法,强烈建议避免错误而不是忽略它们。

1
这样做只是隐藏了实际问题,却没有解决它。这完全是错误的。 - erenon
1
@erenon:能否请大家停一下?这不是实际问题或错误,而是一个通知。它不会影响结果。请不要编故事。 - mario
@mario 确实,但关键是处理它们是一个好的实践。 - Rudi Visser
我很欣赏这个答案——它帮助我理解为什么以前没有收到错误通知,并帮助我更好地编写代码。我给你点赞。 - Jeff
在盲目地对答案进行负评之前,我希望您能阅读一下这个事实:这个答案帮助了原始问题的提出者。谢谢! - gion_13

2

首先检查 $_GET['s'] 是否被设置。将您的条件更改为以下内容:

<?php
if (isset($_GET['s']) && $_GET['s'] == 'jwshxnsyllabus')
echo "<body onload=\"loadSyllabi('syllabus', '../syllabi/jwshxnporsyllabus.xml',         '../bibliographies/jwshxnbibliography_')\">";
elseif (isset($_GET['s']) && $_GET['s'] == 'aquinas')
echo "<body onload=\"loadSyllabi('syllabus', '../syllabi/AquinasSyllabus.xml')\">"; 
elseif (isset($_GET['s']) && $_GET['s'] == 'POP2')
echo "<body onload=\"loadSyllabi('POP2')\">";
elseif (isset($_GET['s']) && $_GET['s'] == null)
echo "<body>"
?>

同时,也要正确处理你的ifelse条件。


1

在使用索引之前,应该检查其是否存在(进行比较)

if (isset($_GET['s']) AND $_GET['s'] == 'foobar') {
    echo "foo";
}

在开发中使用E_ALL | E_STRICT!

1

实际上,虽然提出的答案都是好的做法,但没有一个能消除警告。

为了正确起见,我会执行以下操作:

function getParameter($param, $defaultValue) {
    if (array_key_exists($param, $_GET)) {
        $value=$_GET[$param];
        return isSet($value)?$value:$defaultValue;
    }
    return $defaultValue;
}

这样,我检查_GET数组是否存在该键而不触发警告。禁用警告不是一个好主意,因为很多时候它们至少值得一看。
要使用该函数,只需执行以下操作:
$myvar = getParameter("getparamer", "defaultValue")

所以如果参数存在,你会得到它的值,如果不存在,则会得到默认值。


0

简单的函数,可以使用GET或POST方法。此外,您还可以分配默认值。

function GetPost($var,$default='') {
    return isset($_GET[$var]) ? $_GET[$var] : (isset($_POST[$var]) ? $_POST[$var] : $default);
}

0
避免使用if、else和elseif!
$loadMethod = "";
if(isset($_GET['s'])){
    switch($_GET['s']){
        case 'jwshxnsyllabus':
            $loadMethod = "loadSyllabi('syllabus', '../syllabi/jwshxnporsyllabus.xml', '../bibliographies/jwshxnbibliography_')";
        break;
        case 'aquinas':
            $loadMethod = "loadSyllabi('syllabus', '../syllabi/AquinasSyllabus.xml')";
        break;
        case 'POP2':
            $loadMethod = "loadSyllabi('POP2')";
    }
}

echo '<body onload="'.$loadMethod.'">';

清晰易读的代码是可维护的代码


1
这是很幼稚的想法。任何好的文本编辑器都有“查找匹配括号”,但没有一个有“查找此情况的结尾”。当然,糟糕的case块是糟糕的case块。但是,糟糕的if语句更容易理解。所以我们选择使用if语句!(是的,我见过3,000行代码长的ifswitch语句。我随时会选择if语句) - przemo_li

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