这是什么?

这是一些关于在编程PHP时可能遇到的警告、错误和注意事项的答案,而不知道如何修复它们。这也是一个社区维基,所以每个人都被邀请加入和维护这个列表。

为什么会这样?

Questions like "Headers already sent" or "Calling a member of a non-object" pop up frequently on Stack Overflow. The root cause of those questions is always the same. So the answers to those questions typically repeat them and then show the OP which line to change in their particular case. These answers do not add any value to the site because they only apply to the OP's particular code. Other users having the same error cannot easily read the solution out of it because they are too localized. That is sad because once you understood the root cause, fixing the error is trivial. Hence, this list tries to explain the solution in a general way to apply.

我该怎么做呢?

如果您的问题被标记为此问题的副本,请在下面找到您的错误消息并将修复应用于您的代码。答案通常包含进一步的调查链接,以防仅从一般答案中不清楚。

如果您想投稿,请添加您“最喜欢的”错误消息、警告或通知,每个答案一条,简短描述它的含义(即使它只是突出显示手册页的术语),可能的解决方案或调试方法,以及现有的有价值的问答列表。此外,请随意改进任何现有的答案。

列表

Nothing is seen. The page is empty and white. (also known as White Page/Screen Of Death) Code doesn't run/what looks like parts of my PHP code are output Warning: Cannot modify header information - headers already sent Warning: mysql_fetch_array() expects parameter 1 to be resource, boolean given a.k.a. Warning: mysql_fetch_array(): supplied argument is not a valid MySQL result resource Warning: [function] expects parameter 1 to be resource, boolean given Warning: [function]: failed to open stream: [reason] Warning: open_basedir restriction in effect Warning: Division by zero Warning: Illegal string offset 'XXX' Warning: count(): Parameter must be an array or an object that implements Countable Parse error: syntax error, unexpected '[' Parse error: syntax error, unexpected T_XXX Parse error: syntax error, unexpected T_ENCAPSED_AND_WHITESPACE Parse error: syntax error, unexpected T_PAAMAYIM_NEKUDOTAYIM Parse error: syntax error, unexpected 'require_once' (T_REQUIRE_ONCE), expecting function (T_FUNCTION) Parse error: syntax error, unexpected T_VARIABLE Fatal error: Allowed memory size of XXX bytes exhausted (tried to allocate XXX bytes) Fatal error: Maximum execution time of XX seconds exceeded Fatal error: Call to a member function ... on a non-object or null Fatal Error: Call to Undefined function XXX Fatal Error: Cannot redeclare XXX Fatal error: Can't use function return value in write context Fatal error: Declaration of AAA::BBB() must be compatible with that of CCC::BBB()' Return type of AAA::BBB() should either be compatible with CCC::BBB(), or the #[\ReturnTypeWillChange] attribute should be used Fatal error: Using $this when not in object context Fatal error: Object of class Closure could not be converted to string Fatal error: Undefined class constant Fatal error: Uncaught TypeError: Argument #n must be of type x, y given Notice: Array to string conversion (< PHP 8.0) or Warning: Array to string conversion (>= PHP 8.0) Notice: Trying to get property of non-object error Notice: Undefined variable or property "Notice: Undefined Index", or "Warning: Undefined array key" Notice: Undefined offset XXX [Reference] Notice: Uninitialized string offset: XXX Notice: Use of undefined constant XXX - assumed 'XXX' / Error: Undefined constant XXX MySQL: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ... at line ... Strict Standards: Non-static method [<class>::<method>] should not be called statically Warning: function expects parameter X to be boolean/string/integer HTTP Error 500 - Internal server error Deprecated: Arrays and strings offset access syntax with curly braces is deprecated

还看到:

这个符号在PHP中是什么意思?


当前回答

some_function():参数#1必须是给定的x, y类型

这个错误不言自明。您的代码试图调用some_function(),并将错误类型的数据作为参数之一传递。例如:

<?php declare(strict_types=1);

function multiply(int $x, int $y) { return $x * $y; }

echo multiply("3", 4);

因为被调用的函数的第一个参数是int标量类型,并且调用是在一个启用了严格类型的文件中(stict_types=1),所以当传递字符串给它时,它会出现类型错误:

TypeError: multiply():参数#1 ($x)必须是类型为整型,字符串在…

这个例子来自3v4l.org。

其他回答

严格标准:非静态方法[<class>::<method>]不应该被静态调用

当您试图在类上调用静态的非静态方法时发生,并且您在error_reporting()设置中也有E_STRICT标志。

例子:

class HTML {
   public function br() {
      echo '<br>';
   }
}

HTML::br()或$ HTML::br()

实际上,您可以通过不向error_reporting()添加E_STRICT来避免此错误,例如

error_reporting(E_ALL & ~E_STRICT);

因为对于PHP 5.4.0及以上版本,E_STRICT包含在E_ALL [ref]中。但这并不可取。解决方案是将你想要的静态函数定义为实际的静态函数:

public static function br() {
  echo '<br>';
}

或者按常规调用函数:

$html = new HTML();
$html->br();

相关问题:

我如何解决“非静态方法xxx:xxx()不应该在PHP 5.4中被静态调用?”

注意:使用未定义的常量XXX -假设“XXX”

或者,在PHP 7.2或更高版本中:

警告:使用未定义的常量XXX -假设“XXX”(这将在未来的PHP版本中抛出错误)

或者,在PHP 8.0或更高版本中:

错误:未定义常量XXX

这种情况发生在代码中使用令牌并且看起来是常量,但没有定义该名称的常量时。

引起此通知的最常见原因之一是没有引用用作关联数组键的字符串。

例如:

// Wrong
echo $array[key];

// Right
echo $array['key'];

另一个常见的原因是变量名前缺少$ (dollar)符号:

// Wrong
echo varName;

// Right
echo $varName;

或者你可能拼写错了其他常数或关键字:

// Wrong
$foo = fasle;

// Right
$foo = false;

当您试图访问由该库定义的常量时,这也可能表明缺少所需的PHP扩展或库。

相关问题:

PHP错误消息“注意:使用未定义的常量”是什么意思?

致命错误:闭包类的对象不能转换为字符串

这意味着您没有执行匿名函数(或闭包)。

在这个例子中,使用箭头函数会抛出一个错误:

echo $fn = fn($x = 42) => $x;

或者对任何匿名函数

echo function($x = 42) { return $x; };

要解决这个错误,您需要执行闭包。

echo $fn = (fn($x = 42) => $x)(30); // take notice of the 2 sets of brackets

echo (function($x = 42) { return $x; })(30);

这种语法叫做IIFE,是在PHP 7中添加的。

致命错误:无法重新声明类[类名]

致命错误:无法重新声明[函数名]

这意味着您要么使用了相同的函数/类名两次,并且需要重命名其中一个,要么是因为您在应该使用require_once或include_once的地方使用了require或include。

在PHP中声明类或函数时,它是不可变的,以后不能用新值声明。

考虑下面的代码:

class.php

<?php

class MyClass
{
    public function doSomething()
    {
        // do stuff here
    }
}

index . php

<?php

function do_stuff()
{
   require 'class.php';
   $obj = new MyClass;
   $obj->doSomething();
}

do_stuff();
do_stuff();

对do_stuff()的第二次调用将产生上述错误。通过将require更改为require_once,我们可以确定包含MyClass定义的文件将只被加载一次,并且可以避免错误。

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

在PHP 8.0及以上版本中,该消息改为:

语法错误,意外的字符串内容“”,期望“-”或标识符或变量或数字

当试图在双引号字符串中引用带有引号键的数组值时,当整个复杂变量结构没有包含在{}中时,最常遇到此错误。

错误情况:

这将导致意外的T_ENCAPSED_AND_WHITESPACE:

echo "This is a double-quoted string with a quoted array key in $array['key']";
//---------------------------------------------------------------------^^^^^

可能的修复:

在双引号字符串中,PHP将允许数组关键字字符串不带引号使用,并且不会发出E_NOTICE。所以上面可以写成:

echo "This is a double-quoted string with an un-quoted array key in $array[key]";
//------------------------------------------------------------------------^^^^^

整个复杂数组变量和键可以被括在{}中,在这种情况下,它们应该被引用以避免E_NOTICE。PHP文档对于复杂变量推荐使用这种语法。

echo "This is a double-quoted string with a quoted array key in {$array['key']}";
//--------------------------------------------------------------^^^^^^^^^^^^^^^
// Or a complex array property of an object:
echo "This is a a double-quoted string with a complex {$object->property->array['key']}";

当然,上述任何一种方法的替代方法都是将数组变量连接到,而不是插值它:

echo "This is a double-quoted string with an array variable". $array['key'] . " concatenated inside.";
//----------------------------------------------------------^^^^^^^^^^^^^^^^^^^^^

如需参考,请参阅PHP字符串手册页中的变量解析部分