这是什么?

这是一些关于在编程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中是什么意思?


当前回答

警告:open_basedir限制生效

此警告可以与与文件和目录访问相关的各种函数一起出现。它警告一个配置问题。

当它出现时,这意味着已禁止访问某些文件。

警告本身不会破坏任何东西,但如果文件访问被阻止,脚本通常无法正常工作。

修复方法通常是更改PHP配置,相关设置称为open_basedir。

有时使用了错误的文件或目录名称,解决方法是使用正确的名称。

相关问题:

Open_basedir限制生效。文件(/)不在允许路径内: 所有PHP的“警告:open_basedir限制在有效”的查询在Stackoverflow

其他回答

注意:使用未定义的常量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错误消息“注意:使用未定义的常量”是什么意思?

致命错误:调用成员函数…在一个非物体上

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

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

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

一个典型的例子是

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

在上面的例子中,查询不能被准备,并且prepare()会将false赋值给$statement。尝试调用execute()方法将导致致命错误,因为false是一个“非对象”,因为该值是一个布尔值。

弄清楚为什么函数返回一个布尔值而不是一个对象。例如,检查$pdo对象中最近发生的错误。关于如何调试的细节将取决于如何处理特定函数/对象/类的错误。

如果->准备失败,那么你的$pdo数据库句柄对象没有被传递到当前作用域。找到它被定义的地方。然后将其作为参数传递,将其作为属性存储,或通过全局作用域共享。

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

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

如果试图在条件块之外执行方法,则可能无法定义对象。

相关问题:

调用非对象上的成员函数 列出所有PHP“致命错误:调用成员函数…”关于Stackoverflow的问题

注意:试图获取非对象错误的属性

在没有对象时试图访问对象的属性时发生。

非对象通知的一个典型例子是

$users = json_decode('[{"name": "hakre"}]');
echo $users->name; # Notice: Trying to get property of non-object

在本例中,$users是一个数组(因此不是一个对象),它没有任何属性。

这类似于访问数组中不存在的索引或键(参见注意:未定义索引)。

这个例子简化了很多。大多数情况下,这样的通知表示一个未检查的返回值,例如,如果一个对象不存在,或者只是一个意外的非对象值(例如,在Xpath结果中,具有意外格式的JSON结构,具有意外格式的XML等),库将返回NULL,但代码不会检查这样的条件。

由于这些非对象通常会被进一步处理,因此在对非对象调用对象方法时经常会发生致命错误(参见:致命错误:调用成员函数…在非对象上)停止脚本。

通过检查错误条件和/或变量是否符合期望,可以很容易地防止这种情况。下面是一个带有DOMXPath示例的通知:

$result  = $xpath->query("//*[@id='detail-sections']/div[1]");
$divText = $result->item(0)->nodeValue; # Notice: Trying to get property of non-object

问题是访问第一项的nodeValue属性(字段),而没有检查它是否存在于$result集合中。相反,通过将变量分配给代码所操作的对象,可以使代码更加显式:

$result  = $xpath->query("//*[@id='detail-sections']/div[1]");
$div     = $result->item(0);
$divText = "-/-";
if (is_object($div)) {
    $divText = $div->nodeValue;
}
echo $divText;

相关的错误:

注意:未定义索引 致命错误:调用成员函数…在一个非物体上

致命错误:调用未定义的函数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中删除,请查找有关原因的信息,因为可能不再需要它了。

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

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

相关问题:

https://stackoverflow.com/search?q=Fatal+error%3A+Call+to+undefined+function

警告:mysql_fetch_array()期望参数1是resource, boolean给定

首先,也是最重要的:

请不要在新代码中使用mysql_*函数。它们不再被维护,并且已被正式弃用。看到红框了吗?转而学习准备语句,并使用PDO或MySQLi——本文将帮助您选择哪一种。如果您选择PDO,这里有一个很好的教程。


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

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

您需要检查mysql_query返回的结果by

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

相关问题:

Mysql_fetch_array()期望参数1是resource,在select中给出的布尔值 所有“mysql_fetch_array()期望参数1是资源,布尔给定”的问题

相关的错误:

警告:[function]期望参数1是给定的布尔值

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