这是什么?
这是一些关于在编程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中是什么意思?
警告:数组到字符串的转换
注意:数组到字符串的转换
(PHP 7.4之前的一个通知,PHP 8.0之后的一个警告)
如果你试图将数组视为字符串,就会发生这种情况:
$arr = array('foo', 'bar');
echo $arr; // Notice: Array to string conversion
$str = 'Something, ' . $arr; // Notice: Array to string conversion
数组不能简单地与字符串回显或连接,因为结果没有很好地定义。PHP将使用字符串“Array”来代替数组,并触发通知,指出这可能不是预期的结果,您应该检查这里的代码。你可能想要这样的东西:
echo $arr[0]; // displays foo
$str = 'Something ' . join(', ', $arr); //displays Something, foo, bar
或者循环数组:
foreach($arr as $key => $value) {
echo "array $key = $value";
// displays first: array 0 = foo
// displays next: array 1 = bar
}
如果这个通知出现在您意想不到的地方,这意味着您认为是字符串的变量实际上是一个数组。这意味着你的代码中有一个错误,使这个变量成为一个数组,而不是你期望的字符串。
注意:使用未定义的常量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错误消息“注意:使用未定义的常量”是什么意思?
注意:试图获取非对象错误的属性
在没有对象时试图访问对象的属性时发生。
非对象通知的一个典型例子是
$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;
相关的错误:
注意:未定义索引
致命错误:调用成员函数…在一个非物体上
注意:未定义变量
在尝试使用以前未定义的变量时发生。
一个典型的例子是
foreach ($items as $item) {
// do something with item
$counter++;
}
如果您之前没有定义$counter,上面的代码将触发通知。
正确的方法是在使用变量之前设置它
$counter = 0;
foreach ($items as $item) {
// do something with item
$counter++;
}
类似地,变量在其作用域之外是不可访问的,例如在使用匿名函数时。
$prefix = "Blueberry";
$food = ["cake", "cheese", "pie"];
$prefixedFood = array_map(function ($food) {
// Prefix is undefined
return "${prefix} ${food}";
}, $food);
这应该使用use来传递
$prefix = "Blueberry";
$food = ["cake", "cheese", "pie"];
$prefixedFood = array_map(function ($food) use ($prefix) {
return "${prefix} ${food}";
}, $food);
注意:未定义的属性
此错误的含义大致相同,但指的是对象的属性。重用上面的示例,这段代码将触发错误,因为没有设置counter属性。
$obj = new stdclass;
$obj->property = 2342;
foreach ($items as $item) {
// do something with item
$obj->counter++;
}
相关问题:
所有关于Stackoverflow的PHP“注意:未定义变量”问题
“注意:未定义的变量”,“注意:未定义的索引”,“注意:未定义的偏移量”使用PHP
参考:什么是变量作用域,哪些变量可以从哪里访问,什么是“未定义变量”错误?
警告:[function]期望参数1是给定的布尔值
(一个更通用的警告:mysql_fetch_array()期望参数1是resource,给定布尔值)
资源是PHP中的一种类型(就像字符串、整数或对象一样)。资源是一个不透明的blob,本身没有固有的有意义的值。资源特定于一组PHP函数或扩展并由其定义。例如,Mysql扩展定义了两种资源类型:
MySQL模块中使用了两种资源类型。第一个是数据库连接的链接标识符,第二个是保存查询结果的资源。
cURL扩展定义了另外两种资源类型:
... 一个卷曲手柄和一个卷曲多手柄。
当var_dump时,这些值看起来像这样:
$resource = curl_init();
var_dump($resource);
resource(1) of type (curl)
这就是大多数资源的全部,某种类型((curl))的数字标识符((1))。
您携带这些资源并将它们传递给不同的函数,这些资源对这些函数有一定的意义。通常,这些函数在后台分配特定的数据,而资源只是它们用来在内部跟踪这些数据的引用。
“…期望参数1为resource,给定布尔值”的错误通常是一个未检查的操作的结果,该操作应该创建一个资源,但却返回false。例如,fopen函数有这样的描述:
返回值
成功时返回文件指针资源,错误时返回FALSE。
因此在这段代码中,$fp要么是类型为(stream)的资源(x),要么为false:
$fp = fopen(...);
如果你没有检查fopen操作是否成功或失败,因此$fp是一个有效的资源还是假的,并将$fp传递给另一个期望资源的函数,你可能会得到上述错误:
$fp = fopen(...);
$data = fread($fp, 1024);
Warning: fread() expects parameter 1 to be resource, boolean given
你总是需要错误检查函数的返回值,这些函数试图分配资源,可能会失败:
$fp = fopen(...);
if (!$fp) {
trigger_error('Failed to allocate resource');
exit;
}
$data = fread($fp, 1024);
相关的错误:
警告:mysql_fetch_array()期望参数1是resource, boolean给定