参考 - 此错误在 PHP 中意味着什么?

这是什么?

这是有关警告,错误和注意事项的许多答案,这些警告,错误和注意事项在您对 PHP 进行编程时可能会遇到,并且不知道如何解决它们。这也是一个社区 Wiki,因此邀请所有人参与添加并维护此列表。

为什么是这样?

诸如“已发送标题”“呼叫非对象成员” 之类的问题经常在堆栈溢出中弹出。这些问题的根本原因总是相同的。因此,这些问题的答案通常会重复它们,然后向 OP 显示在特定情况下应更改的行。这些答案不会为网站增加任何价值,因为它们仅适用于 OP 的特定代码。具有相同错误的其他用户无法轻松地从中读取解决方案,因为他们过于本地化。令人遗憾的是,一旦您了解了根本原因,就可以轻松地修复错误。因此,此列表试图以一种通用的方式解释该解决方案。

我该怎么办?

如果您的问题已被标记为与此问题的重复,请在下面找到您的错误消息,并将修复程序应用于您的代码。答案通常包含进一步的链接,以进行调查,以免仅凭一般答案无法明确答案。

如果您想做出贡献,请添加 “最喜欢的” 错误消息,警告或通知,每个答案一个,简短说明其含义(即使只是在其手册页上突出显示术语),可能的解决方案或调试方法以及现有有价值的问答列表。此外,请随时改善任何现有答案。

名单

另请参阅:

答案

警告:无法修改标头信息 - 标头已发送

当脚本尝试将 HTTP 标头发送到客户端但之前已经有输出时,会发生此情况,这导致标头已经发送到客户端。

这是一个E_WARNING ,它不会停止脚本。

一个典型的示例是这样的模板文件:

<html>
    <?php session_start(); ?>
    <head><title>My Page</title>
</html>
...

session_start()函数将尝试将带有会话 cookie 的标头发送到客户端。但是 PHP 在将<html>元素写入输出流时已经发送了标头。您必须将session_start()移到顶部。

您可以通过在代码触发警告之前检查各行并检查其输出位置来解决此问题。将任何标头发送代码移到该代码之前。

一个经常被忽略的输出是 PHP 关闭?>之后的换行符。当文件中的最后一件事时,省略?>被认为是一种标准做法。同样,此警告的另一个常见原因是,当开始<?php有空格,行或不可见字符时,导致 Web 服务器发送标头和空白 / 换行符,因此当 PHP 开始解析时将不会能够提交任何标题。

如果文件中包含多个<?php ... ?>代码块,则它们之间不应有任何空格。 (注意:如果您具有自动构造的代码,则可能有多个块)

还要确保您的代码中没有任何字节顺序标记,例如,当脚本的编码为带有 BOM 的 UTF-8 时。

相关问题:

致命错误:在非对象上调用成员函数...

发生类似于xyz->method()代码,其中xyz不是对象,因此无法调用该method

这是一个致命错误,它将停止脚本(向前兼容性通知:从 PHP 7 开始,它将成为可捕获的错误)。

大多数情况下,这表明代码缺少对错误条件的检查。在调用对象的方法之前,先验证该对象实际上是对象。

一个典型的例子是

// ... some code using PDO
$statement = $pdo->prepare('invalid query', ...);
$statement->execute(...);

在上面的示例中,查询无法准备, prepare()false分配给$statement 。然后尝试调用execute()方法将导致致命错误,因为false是 “非对象”,因为值是布尔值。

弄清楚函数为什么返回布尔值而不是对象。例如,检查$pdo对象以查找最后发生的错误。有关如何进行调试的详细信息将取决于所处理的特定功能 / 对象 / 类的错误处理方式。

如果->prepare失败,那么您的$pdo数据库句柄对象也不会传递到当前范围内 。查找它的定义位置。然后将其作为参数传递,将其存储为属性或通过全局范围共享。

另一个问题可能是有条件地创建对象,然后尝试在该条件块之外调用方法。例如

if ($someCondition) {
    $myObj = new MyObj();
}
// ...
$myObj->someMethod();

通过尝试在条件块之外执行该方法,可能未定义您的对象。

相关问题:

一无所获。页面为空白。

也称为死亡白页死亡白屏 。当错误报告关闭并且发生致命错误(通常是语法错误)时,会发生这种情况。

如果启用了错误日志记录,则将在错误日志中找到具体的错误消息。它通常位于中央位置(例如,在许多 Linux 环境中为/var/log/apache2 )或脚本本身的目录中(有时在共享主机环境中使用),称为 “php_errors.log” 文件。

有时暂时启用错误显示可能会更直接。然后,白页将显示错误消息。请小心,因为这些错误对于访问该网站的每个人都是可见的。

通过在脚本顶部添加以下 PHP 代码,可以轻松完成此操作:

ini_set('display_errors', 1); error_reporting(~0);

该代码将打开错误显示,并将报告设置为最高级别。

由于ini_set()在运行时执行,因此对解析 / 语法错误没有影响。这些错误将出现在日志中。如果还要在输出中(例如,在浏览器中)显示它们,则必须将display_startup_errors指令设置为true 。可以在php.ini.htaccess执行此操作,也可以通过任何其他运行时影响配置的方法来执行此操作

您可以使用相同的方法来设置log_errorserror_log伪指令以选择自己的日志文件位置。

在日志中查看或使用显示,您将获得更好的错误消息以及中止脚本的代码行。

相关问题:

相关错误:

注意:未定义的索引

当您尝试通过阵列中不存在的键访问阵列时发生。

Undefined Index通知的典型示例是( demo

$data = array('foo' => '42', 'bar');
echo $data['spinach'];
echo $data[1];

spinach1不阵列中存在,引起E_NOTICE被触发。

解决方案是在访问索引之前确保索引或偏移量存在。这可能意味着您需要修复程序中的错误以确保这些索引在您期望的时候确实存在。或可能意味着您需要使用array_key_existsisset测试索引是否存在:

$data = array('foo' => '42', 'bar');
if (array_key_exists('spinach', $data)) {
    echo $data['spinach'];
}
else {
    echo 'No key spinach in the array';
}

如果您有如下代码:

<?php echo $_POST['message']; ?>
<form method="post" action="">
    <input type="text" name="message">
    ...

那么在首次加载此页面时不会设置$_POST['message']并且会出现上述错误。仅当提交表单并再次运行此代码时,数组索引才会存在。您通常使用以下方法进行检查:

if ($_POST)  ..  // if the $_POST array is not empty
// or
if ($_SERVER['REQUEST_METHOD'] == 'POST') ..  // page was requested with POST

相关问题:

警告:mysql_fetch_array()期望参数 1 为资源,给定布尔值

首先,最重要的是:

请不要在新代码中使用mysql_*函数 。它们不再维护,已正式弃用 。看到红色框了吗?相反,要了解准备好的语句 ,并使用PDOMySQLi- 本文将帮助您确定哪一个。如果您选择 PDO, 这是一个很好的教程


当您尝试从mysql_query的结果中获取数据但查询失败时,会发生这种情况。

这是一个警告,不会停止脚本,但是会使您的程序出错。

您需要通过以下方式检查mysql_query返回的结果

$res = mysql_query($sql);
if (!$res) {
   die(mysql_error());
}
// after checking, do the fetch

相关问题:

相关错误:

出于同样的原因,也希望将 MySQL 结果资源用作参数的其他mysql*函数将产生相同的错误。

致命错误:不在对象上下文中时使用 $ this

$this是 PHP中无法分配的特殊变量 。如果在不存在的上下文中访问它,则会出现此致命错误。

可能会发生此错误:

  1. 如果非静态方法是静态调用的。例:

    class Foo {
       protected $var;
       public function __construct($var) {
           $this->var = $var;
       }
    
       public static function bar () {
           // ^^^^^^
           echo $this->var;
           //   ^^^^^
       }
    }
    
    Foo::bar();

    如何解决:如何再次检查代码, $this只能在对象上下文中使用,决不能在静态方法中使用。同样,静态方法不应访问非静态属性。使用self::$static_property访问 static 属性。

  2. 如果来自类方法的代码已复制到普通函数或仅复制到全局范围中, 保留$this特殊变量。
    如何解决:查看代码并将$this替换$this其他替换变量。

相关问题:

  1. 调用非静态方法作为静态方法: PHP 致命错误:不在对象上下文中时使用 $ this
  2. 复制代码: 致命错误:不在对象上下文中时使用 $ this
  3. 所有 “不在对象上下文中时使用 $ this” 的问题

致命错误:调用未定义函数 XXX

尝试调用尚未定义的函数时发生。常见原因包括缺少扩展名,包括条件函数声明,函数声明中的函数或简单的拼写错误。

示例 1 - 条件函数声明

$someCondition = false;
if ($someCondition === true) {
    function fn() {
        return 1;
    }
}
echo fn(); // triggers error

在这种情况下,将不会声明fn()因为$someCondition不正确。

示例 2 - 函数声明中的函数

function createFn() 
{
    function fn() {
        return 1;
    }
}
echo fn(); // triggers error

在这种情况下,只有在调用createFn()后才声明fn 。请注意,随后对createFn()调用将触发有关重新声明现有函数的错误。

您可能还会在 PHP 内置函数中看到此信息。尝试在官方手册中搜索该功能,并检查其所属的 “扩展”(PHP 模块)以及哪些版本的 PHP 支持该功能。

如果缺少扩展名,请安装该扩展名并在 php.ini 中启用它。请参阅 PHP 手册中的安装说明,以获取功能所在的扩展名。您还可以使用软件包管理器(例如,Debian 或 Ubuntu 中的apt ,Red Hat 或 CentOS 中的yum )启用或安装扩展名。共享托管环境中的控制面板。

如果该功能是在您所使用的 PHP 的较新版本中引入的,则可以在手册或其注释部分中找到替代实现的链接。如果已将其从 PHP 中删除,请查找有关原因的信息,因为可能不再需要它。

如果缺少包含,请在调用函数之前确保包含声明函数的文件。

如果出现错别字,请修正错字。

相关问题:

解析错误:语法错误,意外的 T_XXX

当您将T_XXX令牌放置在意外的地方,不平衡的(多余的)括号,在 php.ini 中未使用短标签而不激活它的情况下,就会发生这种情况。

相关问题:

有关更多帮助,请参见:

致命错误:无法在写入上下文中使用函数返回值

当直接将函数与empty一起使用时,通常会发生这种情况。

例:

if (empty(is_null(null))) {
  echo 'empty';
}

这是因为empty是一种语言构造而非函数,在 5.5 之前的 PHP 版本中,不能使用表达式作为其参数来调用它。在 PHP 5.5 之前, empty()的参数必须是一个变量 ,但是 PHP 5.5 + 中允许使用任意表达式(例如函数的返回值)。

empty ,尽管它的名字,实际上不检查一个变量是 “空”。相反,它检查变量是否不存在或== false 。表达式(如示例中的is_null(null) )将始终被视为存在,因此这里的empty仅检查其是否等于 false。您可以在此处将empty()替换为! ,例如if (!is_null(null)) ,或显式比较 false,例如if (is_null(null) == false)

相关问题:

MySQL:SQL 语法有误;检查与您的 MySQL 服务器版本相对应的手册,以在第... 行附近使用正确的语法。

经常导致此错误,是因为您忘记了正确地转义传递给 MySQL 查询的数据。

什么不该做(以下简称 “坏主意”)的一个例子:

$query = "UPDATE `posts` SET my_text='{$_POST['text']}' WHERE id={$_GET['id']}";
mysqli_query($db, $query);

该代码可以包含在具有要提交的表单的页面中,并带有 URL,例如http://example.com/edit.php?id=10 (用于编辑帖子 n°10)。

如果提交的文本包含单引号会怎样? $query最终将带有:

$query = "UPDATE `posts` SET my_text='I'm a PHP newbie' WHERE id=10';

当此查询发送到 MySQL 时,它将抱怨语法错误,因为中间有一个额外的单引号。

为避免此类错误, 必须始终在查询中使用数据之前对其进行转义。

在 SQL 查询中使用前转义数据也非常重要,因为如果不转义,脚本将可以进行 SQL 注入。 SQL 注入可能会导致记录,表或整个数据库的更改,丢失或修改。这是一个非常严重的安全问题!

说明文件: