我正在运行一个PHP脚本,并继续收到错误,如:

注意:未定义变量my_variable_name在C:\wamp\www\mypath\index.php第10行 注意:第11行未定义索引:my_index C:\wamp\www\mypath\index.php 警告:在C:\wamp\www\mypath\index.php第11行未定义数组键“my_index”

第10和11行是这样的:

echo "My variable value is: " . $my_variable_name;
echo "My index value is: " . $my_array["my_index"];

这些错误消息的含义是什么?

为什么他们会突然出现?我曾经使用这个脚本多年,从来没有任何问题。

我该如何修复它们?


这是一个一般参考问题,供人们链接作为副本,而不是需要一遍又一遍地解释这个问题。我觉得这很有必要,因为现实世界中关于这个问题的答案都非常具体。 相关元讨论: 如何应对重复的问题? “参考问题”有意义吗?


当前回答

关于这部分问题:

为什么他们会突然出现?我曾经使用这个脚本多年,从来没有任何问题。

没有明确的答案,但这里有一些可能的解释,为什么设置可以“突然”改变:

您已经将PHP升级到一个新的版本,该版本可以为error_reporting、display_errors或其他相关设置设置其他默认值。 您已经删除或引入了一些在运行时使用ini_set()或error_reporting()设置相关设置的代码(可能是在依赖项中)(在代码中搜索这些代码) 你改变了web服务器配置(假设这里是apache): .htaccess文件和vhost配置也可以操作php设置。 通常通知不会被显示/报告(参见PHP手册) 因此,在设置服务器时,php.ini文件可能因为某些原因(文件权限??)而无法加载,而您使用的是默认设置。稍后,“错误”已经解决(意外),现在它可以加载正确的php.ini文件与error_reporting设置显示通知。

其他回答

在PHP中,首先需要定义变量。之后你就可以使用它了。

我们可以以一种非常有效的方式检查变量是否定义!

// If you only want to check variable has value and value has true and false value.
// But variable must be defined first.

if($my_variable_name){

}

// If you want to check if the variable is defined or undefined
// Isset() does not check that variable has a true or false value
// But it checks the null value of a variable
if(isset($my_variable_name)){

}

简单的解释

// It will work with: true, false, and NULL
$defineVariable = false;
if($defineVariable){
    echo "true";
}else{
    echo "false";
}

// It will check if the variable is defined or not and if the variable has a null value.
if(isset($unDefineVariable)){
    echo "true";
}else{
    echo "false";
}

这是因为变量'$user_location'没有被定义。如果你在里面使用任何If循环,你声明了'$user_location'变量,那么你也必须有一个else循环并定义相同的。例如:

$a = 10;
if($a == 5) {
    $user_location = 'Paris';
}
else {
}
echo $user_location;

上面的代码将创建一个错误,因为if循环不满足,并且在else循环中没有定义“$user_location”。PHP仍然被要求回显变量。所以要修改代码,你必须做到以下几点:

$a = 10;
if($a == 5) {
    $user_location='Paris';
}
else {
    $user_location='SOMETHING OR BLANK';
}
echo $user_location;

我不想禁用通知功能,因为它很有帮助,但我想避免太多的输入。

我的解是这个函数:

function ifexists($varname)
{
  return(isset($$varname) ? $varname : null);
}

因此,如果我想引用$name和echo if存在,我简单地写:

<?= ifexists('name') ?>

对于数组元素:

function ifexistsidx($var,$index)
{
  return(isset($var[$index]) ? $var[$index] : null);
}

在一个页面中,如果我想引用$_REQUEST['name']:

<?= ifexistsidx($_REQUEST, 'name') ?>

我曾经诅咒过这个错误,但是提醒您转义用户输入是有帮助的。

例如,如果你认为这是聪明的,速记代码:

// Echo whatever the hell this is
<?=$_POST['something']?>

...再想想!更好的解决方案是:

// If this is set, echo a filtered version
<?=isset($_POST['something']) ? html($_POST['something']) : ''?>

(我使用自定义html()函数来转义字符,您的里程可能会有所不同)

为什么会这样?

随着时间的推移,PHP已经成为一种更加关注安全的语言。以前默认关闭的设置现在默认打开了。E_STRICT就是一个很好的例子,它在PHP 5.4.0时默认开启。

此外,根据PHP文档,默认情况下,E_NOTICE在PHP .ini文件中是禁用的。PHP文档建议为了调试目的打开它。然而,当我从Ubuntu存储库和BitNami的Windows堆栈中下载PHP时,我看到了其他东西。

; Common Values:
;   E_ALL (Show all errors, warnings and notices including coding standards.)
;   E_ALL & ~E_NOTICE  (Show all errors, except for notices)
;   E_ALL & ~E_NOTICE & ~E_STRICT  (Show all errors, except for notices and coding standards warnings.)
;   E_COMPILE_ERROR|E_RECOVERABLE_ERROR|E_ERROR|E_CORE_ERROR  (Show only errors)
; Default Value: E_ALL & ~E_NOTICE & ~E_STRICT & ~E_DEPRECATED
; Development Value: E_ALL
; Production Value: E_ALL & ~E_DEPRECATED & ~E_STRICT
; http://php.net/error-reporting
error_reporting = E_ALL & ~E_DEPRECATED & ~E_STRICT

注意,error_reporting实际上默认设置为生产值,而不是默认设置为“default”值。这有点令人困惑,并且在php.ini之外没有记录,所以我没有在其他发行版上验证这一点。

为了回答你的问题,然而,这个错误现在弹出时,它没有弹出之前,因为:

您安装了PHP,新的默认设置的文档很少,但不排除E_NOTICE。 E_NOTICE警告,如未定义变量和未定义索引,实际上有助于使您的代码更干净和更安全。我可以告诉你,几年前,保持E_NOTICE启用迫使我声明我的变量。在C语言中,不声明变量是一个更大的麻烦。

我能做些什么呢?

通过复制“默认值”E_ALL & ~E_NOTICE & ~E_STRICT & ~E_DEPRECATED并将其替换为error_reporting =中的等号后当前未注释的内容来关闭E_NOTICE。如果使用CGI或FPM,则重新启动Apache或PHP。确保你编辑的是“正确的”php.ini文件。如果你用Apache运行PHP,正确的选择是Apache,如果用PHP- fpm,选择fpm或PHP- fpm,如果用PHP- cgi,选择cgi,等等。这不是推荐的方法,但如果您有难以编辑的遗留代码,那么它可能是您最好的选择。 关闭文件或文件夹级别的E_NOTICE。如果您有一些遗留代码,但希望以“正确”的方式做事,那么这可能更可取。要做到这一点,你应该咨询Apache 2, Nginx或任何你选择的服务器。在Apache中,您可以在<Directory>中使用php_value。 重写代码,使其更清晰。如果你在转移到生产环境时需要这样做,或者不想让别人看到你的错误,确保你禁用了任何错误显示,只记录你的错误(参见php.ini和你的服务器设置中的display_errors和log_errors)。

扩展选项3:这是最理想的。如果你可以走这条路,你就应该走。如果您最初没有走这条路,请考虑最终通过在开发环境中测试您的代码来移动这条路。在此过程中,去掉~E_STRICT和~E_DEPRECATED,看看将来会出现什么问题。您将看到许多不熟悉的错误,但这将使您在将来需要升级PHP时避免遇到任何不愉快的问题。

这些错误意味着什么?

未定义变量:my_variable_name—当变量在使用前没有定义时,会发生这种情况。当PHP脚本执行时,它在内部只假定一个空值。但是,在哪种情况下需要在定义变量之前检查它呢?归根结底,这是对“草率代码”的论证。作为一名开发人员,我可以告诉您,当我看到一个开源项目在其作用域中尽可能高地定义变量时,我非常喜欢。它可以更容易地判断将来会弹出哪些变量,也可以更容易地阅读/学习代码。

function foo()
{
    $my_variable_name = '';

    //....

    if ($my_variable_name) {
        // perform some logic
    }
}

未定义索引:my_index -当你试图访问一个数组中的值,而它不存在时,会发生这种情况。要避免此错误,请执行条件检查。

// verbose way - generally better
if (isset($my_array['my_index'])) {
    echo "My index value is: " . $my_array['my_index'];
}

// non-verbose ternary example - I use this sometimes for small rules.
$my_index_val = isset($my_array['my_index'])?$my_array['my_index']:'(undefined)';
echo "My index value is: " . $my_index_val;

另一种选择是在函数的顶部声明一个空数组。这并不总是可能的。

$my_array = array(
    'my_index' => ''
);

//...

$my_array['my_index'] = 'new string';

(额外的小费)

当我遇到这些和其他问题时,我使用了netbeans IDE(免费),它给了我许多警告和注意。其中一些提供了非常有用的建议。这不是一个要求,除了大型项目,我不再使用ide了。我现在更有活力了:)。