这是什么?
这是一些关于在编程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中是什么意思?
致命错误:允许的内存大小XXX字节已耗尽(已尝试分配XXX字节)
没有足够的内存来运行脚本。PHP已达到内存限制并停止执行。这个错误是致命的,脚本停止。内存限制的值可以在php.ini文件中配置,也可以使用ini_set('memory_limit', '128 M');在脚本中(将覆盖php.ini中定义的值)。内存限制的目的是防止一个PHP脚本占用所有可用内存,导致整个web服务器瘫痪。
The first thing to do is to minimise the amount of memory your script needs. For instance, if you're reading a large file into a variable or are fetching many records from a database and are storing them all in an array, that may use a lot of memory. Change your code to instead read the file line by line or fetch database records one at a time without storing them all in memory. This does require a bit of a conceptual awareness of what's going on behind the scenes and when data is stored in memory vs. elsewhere.
如果在脚本没有执行内存密集型工作时发生此错误,则需要检查代码以查看是否存在内存泄漏。memory_get_usage函数是您的朋友。
相关问题:
所有“Fatal error: Allowed memory size of XXX bytes exhausted”问题
HTTP错误500 -内部服务器错误
HTTP状态代码500和典型的Apache或浏览器警告是一个非常广泛的消息。这不是实际的错误。要弄清楚是web服务器配置错误(.htaccess)还是PHP致命错误,你必须查看error.log。
你通常可以在下面找到webservers日志:
/var/log/apache2 on Linux servers, often used for local and virtual hosts.
/var/www/_user12345_/logs or similar on shared hosting plans.
Usually there's a logs/ directory alongside each htdocs/ folder.
C:\xampp\apache\logs\error.log for WAMP/XAMPP distributions of Apache+PHP.
Alternatively just use a file search feature to locate anything called "error.log".
Or look into your Apache httpd.conf and its ErrorLog directive.
/var/log/nginx/nginx_error.log for NGINX.
C:\inetpub\logs\LogFiles for IIS.
Luckily this is uncommon still, but journalctl -r -u apache2.service could also hold parts of the log on Linux setups.
它是一个文本文件。搜索与错误时间最接近的条目,并使用错误消息的重要部分(从“PHP error:…”到“in line…”)进行进一步的google搜索。
[Mon 22:10] [:error] [pid 12345] [client 127.0.0.1] FastCGI: server "/fcgi/p73" stderr: PHP message:PHP error: Unfiltered inputvariable $_JSON['pokestop_lng'] in filyfile.php on line 845
对于FPM设置,你经常会看到致命的PHP错误。而旧的mod_php(共享主机)配置经常混合警告和通知(通常也值得检查)。
如果没有配置为使用系统或Apache日志机制,您可能还需要查看PHP的error.log。一般来说,保留默认值并启用error_display + error_reporting来显示具体的错误会更简单。HTTP 500全捕获页面不过是PHP死机白屏幕的一个变种。
参见:
500内部服务器错误的php文件,而不是html
我怎么能让PHP显示错误,而不是给我500内部服务器错误
如何在IIS7上显示和记录PHP错误?
如何修复WordPress内部服务器的500个错误
致命错误:调用未定义的函数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
致命错误:调用成员函数…在一个非物体上
发生在类似于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的问题
致命错误:超过XX秒的最大执行时间
每个PHP页面请求或脚本调用都度量PHP代码执行了多长时间。如果达到配置的限制,脚本将使用此消息中止。
注意,时间通常不包括发生在PHP“外部”的事情,例如等待数据库结果的时间,或使用shell_exec执行的外部程序等。例外情况是当PHP在Windows上运行时,测量的时间是“时钟时间”,并且确实包括这些外部等待时间。
常见的原因
无限循环。写错的while, do…while或for循环可能永远不会完成,这意味着PHP将永远持续运行。甚至foreach循环也可以是无限的,例如循环遍历一个Iterator对象或生成器函数。
庞大的数据集。即使您的循环不是无限的,如果它正在做很多工作,如果它正在处理大量的结果,它可能需要很长时间才能完成。
改变限制
如果你知道你有一个缓慢的过程,你可以配置时间限制:
在php.ini中,使用max_execution_time设置。
在脚本运行时,使用set_time_limit函数。注意,调用这个函数会将测量的时间重置为零,因此执行set_time_limit(10);意思是“再给10秒钟,不管脚本已经花了多长时间”。
这两种机制都应该给出一个秒数,或者特殊值0,表示“不限制”。设置“无限制”对于你真正想在后台永远运行的命令行脚本是最有用的;对于网页,最好设置一些有限值,即使它非常大,以防止代码中的错误导致整个系统失去响应。