这是什么?
这是一些关于在编程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中是什么意思?
警告: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结果资源作为参数将出于同样的原因产生相同的错误。
致命错误:调用成员函数…在一个非物体上
发生在类似于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的问题
警告:不能修改报头信息-报头已经发送
当您的脚本试图向客户端发送HTTP报头,但之前已经有输出,导致报头已经发送到客户端时发生。
这是一个E_WARNING,它不会停止脚本。
一个典型的例子是这样的模板文件:
<html>
<?php session_start(); ?>
<head><title>My Page</title>
</html>
...
session_start()函数将尝试向客户端发送带有会话cookie的报头。但是PHP在将<html>元素写入输出流时已经发送了头文件。您必须将session_start()移到顶部。
您可以通过遍历代码触发Warning之前的行并检查它输出的位置来解决这个问题。移动任何头发送代码之前的代码。
一个经常被忽略的输出是PHP关闭?>后的新行。当?>是文件中的最后一个内容时,省略它被认为是一种标准实践。同样,出现此警告的另一个常见原因是当开头<?php前面有一个空格,行,或者不可见的字符,导致web服务器发送报头和空格/换行,这样当php开始解析时就不能提交任何报头。
如果您的文件有多个<?php……?>代码块,它们之间不应该有任何空格。(注意:如果你有自动构造的代码,你可能有多个块)
还要确保在代码中没有任何字节顺序标记,例如当脚本的编码是UTF-8和BOM时。
相关问题:
头文件已经被PHP发送
所有PHP“头已经发送”的问题在Stackoverflow
字节顺序标记
什么PHP函数可以创建输出?
什么也看不见。页面是空白的,白色的。
也被称为白页死亡或白屏幕死亡。当错误报告被关闭并且发生致命错误(通常是语法错误)时,就会发生这种情况。
如果启用了错误日志记录,您将在错误日志中找到具体的错误消息。这通常在一个名为“php_errors.log”的文件中,要么在一个中心位置(例如在许多Linux环境中是/var/log/apache2),要么在脚本本身的目录中(有时在共享主机环境中使用)。
有时,临时启用错误显示可能更直接。然后,白页将显示错误消息。要小心,因为这些错误对访问网站的每个人都是可见的。
这可以通过在脚本顶部添加以下PHP代码轻松完成:
ini_set('display_errors', 1); error_reporting(~0);
代码将打开错误显示并将报告设置为最高级别。
由于ini_set()是在运行时执行的,它对解析/语法错误没有影响。这些错误将出现在日志中。如果你想在输出中显示它们(例如在浏览器中),你必须将display_startup_errors指令设置为true。在php.ini或.htaccess或任何其他在运行时之前影响配置的方法中执行此操作。
您可以使用相同的方法设置log_errors和error_log指令来选择您自己的日志文件位置。
查看日志或使用显示,您将得到更好的错误消息和脚本停止的代码行。
相关问题:
PHP的白屏死机
白屏死机!
PHP不显示错误消息
PHP在错误时释放500 -在哪里有文档?
如何在PHP中获得有用的错误消息?
关于Stackoverflow的所有PHP“死亡白页”问题
相关的错误:
解析错误:语法错误,意外的T_XXX
致命错误:调用成员函数…在一个非物体上
代码不运行/我的PHP代码的某些部分被输出
解析错误:语法错误,意外的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字符串手册页中的变量解析部分