【问题标题】:PHP tutorial, issues with Undefined index and recommended isset fixesPHP 教程,未定义索引的问题和推荐的 isset 修复
【发布时间】:2018-03-31 03:57:03
【问题描述】:

在学习PHP的过程中,我一直在关注this series on youtube:到目前为止,它真的是一帆风顺。我正在使用 VS Code 1.21.1,我刚刚安装了 PHP 7,并且正在运行 XAMPP 7.2.3(目前只运行 Apache),并在 Chrome 中查看输出,全部在 Windows 7 中。完成教程中的代码看起来像这样

<form action="index.php" method="GET">
        Name:<br><input type="text" name="name"><br>
        Age:<br><input type="text" name="age" size="5"><br><br>
        <input type="submit" value="Submit">
    </form>

<?php

    $name = $_GET['name'];
    $age = $_GET['age']; 
if(isset($name) && isset($age) && !empty($name) && !empty($age)) {
    echo 'I am '.$name.' and I am '.$age.' years of age.';
} else {
    echo 'Please type something.';
}

?>

这对我没有用。

Tutorial 22 Undefined index screenshot

代码末尾的 if(isset) 语句应该避免“未定义索引”错误,但对我来说从来没有。我最终尝试了很多修复,包括添加 PHPCS linting,以防我遗漏了一些新的和令人兴奋的东西。前 9 个错误让我发现了教程遗漏的整个世界(也许大多数只是警告......但仍然......)

我的(部分?)解决方案是从另一个 youtube 视频中提取的,其中为提交按钮提供了一个名称,并且仅针对该字段进行了测试(在本教程中,测试也是这些字段不是空白的。此解决方案不检查这一点。)请注意,在尝试解决所有 linted 问题时还添加了大量其他样板文件,但都没有解决问题......但问题仍然存在,为什么这可以避免无效索引问题,但教程中的问题没有?

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>
<body>
    <form action="index.php" method="GET" enctype="form-data/multipart">
        Name:<br><input type="text" name="name"><br>
        Age:<br><input type="text" name="age" size="5"><br><br>
        <input type="submit" name="submit" value="Submit">
    </form>

<?php
/**
 * MyClass File Doc Comment
 *
 * PHP Version 7
 * 
 * @category MyClass
 * @package  MyPackage
 * @author   A N Other <another@gmail.com>
 * @license  http://www.gnu.org/copyleft/gpl.html GNU General Public License
 * @link     http://www.holygenericboilerplatebatman.com/
 */

if (isset($_GET['submit'])) { // It's before the variables, so it works?
    $name = $_GET['name'];
    $age = $_GET['age']; 

    echo 'I am '.$name.' and I am '.$age.' years old.';
} else {
    echo 'Please type something.';
}

?>

    </body>
</html>

我能看到的唯一明显区别是在声明变量之前放置了 if(isset) 语句,但是在该位置使用教程中的语句可以正确加载页面,但不会呈现输入的名称和年龄在表格下方,就像它应该的那样。 URL 会随着 PHP 条目而更新,但页面仍然会说“请输入一些内容”,而不是切换到填充了变量的另一行文本。

我不明白这些方法之间的区别足以知道我应该学习什么! :S

我在所有阅读/尝试中注意到的另一件事是,99% 的未定义索引错误建议都集中在“$_POST”方法上,而不是“$_GET”,包括这里的 SO。因此,我不认为这是一个重复的问题。这是我明显缺少的其他东西吗?提前致谢!

【问题讨论】:

  • 已经在这里检查了看起来像真正权威的答案,包括这个看起来像百科全书的答案:stackoverflow.com/questions/4261133/… 我只是尝试使用 PHP 7 空合并运算符,这也使页面正确显示,但在提交后仍然无法实际呈现完整的文本。

标签: php html xampp


【解决方案1】:

在将其分配给变量之前,您必须检查 isset。更改您的 php 脚本如下:

<?php

if(isset($_GET['name']) && isset($_GET['age']) && !empty($_GET['name']) && !empty($_GET['age'])) {
    $name = $_GET['name'];
    $age = $_GET['age'];
    echo 'I am '.$name.' and I am '.$age.' years of age.';
} else {
    echo 'Please type something.';
}

?>

【讨论】:

  • 这行得通,谢谢!您知道为什么代码(如第一个示例中所示)没有为演示者抛出未定义的索引错误吗?与他在 9 月份发布时所包含的任何技术相比,是否发生了一些变化?
【解决方案2】:

在您的第一个代码中,它显示了这些错误,因为 $_GET['name']$_GET['age'] 未定义。

要在您的情况下定义它们,您需要先提交表单。正如您在提交表单后所看到的,您的浏览器地址栏 URL 将显示为 - index.php?name=john&age=23 - 这就是那些 $_GET 变量的样子定义并设置它们的值。

当表单没有提交时,url 不会改变,没有定义 $_GET 变量,当你像在第一个代码中那样过早地使用它们时,你会收到错误通知.

无论如何,即使那些 $_GET 变量没有像往常一样定义,您仍然可以通过使用函数 isset() 检查它们是否在尝试使用它们之前是否已设置。

替换:

$name = $_GET['name'];
$age = $_GET['age']; 

与:

$name = "John Doe"; // default values
$age = "24";

if( isset( $_GET['name'] ) ) {
   $name = $_GET['name'];
}

if( isset( $_GET['age'] ) ) {
   $age = $_GET['age'];
}

【讨论】:

  • 我唯一不喜欢的是需要播种值(然后在第一次加载时显示在页面上),但除此之外,答案是有意义的。谢谢!
【解决方案3】:

试试这个

$name = $_GET['name'] ?? false;
$age = $_GET['age'] ?? false; 
if($name && $age) {

使用空合并??PHP7+

我刚刚安装了 PHP 7,

我注意到您使用的是 PHP7+,因此我们可以使用新功能(无论如何我需要练习)

现在您会收到未定义的索引通知,因为正如它所说,您正在尝试访问不存在的东西。有多种方法可以检查这不会发出错误。每个都有点不同,这里有两种最常见的方法。

  • empty 检查变量是否虚假,它可以设置或不设置。
    • 例如。对任何 false 值(例如 0''[]null 以及未设置时返回 true。
  • isset 检查是否设置了变量
    • 例如。未设置时返回 false,否则即使在虚假值上也返回 true,null 除外

由于 PHP 的松散类型,使用 empty 可能会有很大问题。 PHP 中的许多东西都被评估为 falseempty (AKA falsy),其中一些可能是完全有效的输入。一个简单的例子是值0 或一个空字符串'',每个都可以完全接受。但是,它们都被认为是emptyfalse(当不使用=== 时,它会进行类型检查)。

当变量被定义且不为空时,使用isset 返回布尔值true。换句话说,与empty 不同,isset 将在除null 之外的任何falsy 值上返回true

还有多种方法可以在条件逻辑中使用isset。新的?? 空合并返回列表中的第一个非空值(从左到右),使用与isset 相同的检查。因此,我们可以说它等同于isset

与使用“更多”传统条件块检查 isset 相比,这个新运算符有一些优势。

一些例子

使用long hand if 条件,如果您需要检查大量输入或可以替换的许多替代值,则可能会使您的代码膨胀。

if(isset($foo))
   $var = $foo;
elseif(isset($bar))
   $var = $bar;
elseif(isset($biz))
   $var = $biz;
else
   $var = false;

三元格式({condition} ? true : false;) 是对它的改进,但您一次只能做一个true 和一个false 分辨率。你可以嵌套它们,但很快就会变得不可读:

$var = isset($foo) ? $foo : isset($bar) ? $bar : isset($biz) ? $biz : false;

在 PHP7+ 中,我们有幸拥有 ?? 空合并运算符,我们可以像上面 2 个示例中所示做同样的事情,只是这样:

$var = $foo ?? $bar ?? $biz ?? false;

所有这些都大致等价,很容易看出使用新的空合并运算符的吸引力。

希望这有助于解释它。我自己还在习惯??,因为我们还没有开始在工作中使用PHP7。不用担心,只要我们进行了兼容性测试并“修复”它就会很快... :)

【讨论】:

  • 你至少可以解释为什么投反对票。只是投反对票是粗鲁的IMO。在 PHP7 中它是完全有效的。
  • 我已经解决了这个问题,我还没有在生产中使用 PHP7 :( 。还在习惯它。
  • 这行得通,而且非常简洁,并且不会引发在 VS Code 或 PHP CS 中一行超过 85 个字符的软错误。非常感谢它背后的推理!
  • 当然,听到你的赞赏让我微笑。很高兴我能回馈 SO 社区,因为我也从这里学到了很多东西。
【解决方案4】:

其实,在原来的问题上,它是这样正常工作的,停留在 PHP 5.6 ,停留在原来的教程:

if (isset($_GET['name']) && isset($_GET['age'])) {
    $name = $_GET['name'];
    $age = $_GET['age'];
}

if (isset($name) && isset($age) && !empty($name) && !empty($age)) {
    echo 'I am '.$name. ' and I am ' .$age. ' old';
  } else {
  echo 'Please type something';
}

或者更清楚:

if (isset($_GET['name']) && isset($_GET['age'])) {
    $name = $_GET['name'];
    $age = $_GET['age'];
}

if (!empty($name) && !empty($age)) {
    echo 'I am '.$name. ' and I am ' .$age. ' old';
  } else {
  echo 'Please type something';
}

【讨论】:

    猜你喜欢
    • 2021-02-04
    • 1970-01-01
    • 1970-01-01
    • 2014-05-08
    • 1970-01-01
    • 1970-01-01
    • 2019-03-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多