这是什么?

这是一些关于在编程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:你的SQL语法有错误;检查手册,对应于您的MySQL服务器版本的正确语法使用近…排队……

这个错误通常是因为您忘记正确转义传递给MySQL查询的数据。

一个不应该做的事情(“坏主意”)的例子:

$query = "UPDATE `posts` SET my_text='{$_POST['text']}' WHERE id={$_GET['id']}";
mysqli_query($db, $query);

这段代码可以包含在一个表单提交的页面中,URL为http://example.com/edit.php?id=10(编辑帖子n°10)

如果提交的文本包含单引号会发生什么?$query将以:

$query = "UPDATE `posts` SET my_text='I'm a PHP newbie' WHERE id=10';

当这个查询被发送到MySQL时,它会抱怨语法错误,因为中间有一个额外的单引号。

为了避免这样的错误,在查询中使用数据之前,必须始终转义数据。

在SQL查询中使用数据之前转义数据也是非常重要的,因为如果您不这样做,您的脚本将对SQL注入开放。SQL注入可能导致记录、表或整个数据库的更改、丢失或修改。这是一个非常严重的安全问题!

文档:

如何防止PHP中的SQL注入? mysql_real_escape_string () mysqli_real_escape_string () 如何从“Bobby表”XKCD漫画的SQL注入工作? 绕过mysql_real_escape_string()的SQL注入

其他回答

致命错误:不能在写上下文中使用函数返回值

这通常发生在直接使用带有empty的函数时。

例子:

if (empty(is_null(null))) {
  echo 'empty';
}

这是因为empty是一个语言结构,而不是一个函数,在5.5之前的PHP版本中,它不能用表达式作为参数调用。在PHP 5.5之前,empty()的参数必须是变量,但在PHP 5.5+中允许任意表达式(例如函数的返回值)。

Empty,尽管它的名字,实际上并不检查一个变量是否为“空”。相反,它检查变量是否存在,或== false。表达式(如示例中的is_null(null))将始终被视为存在,因此这里的empty仅检查它是否等于false。你可以在这里用!替换empty(),例如if (!is_null(null)),或者显式地与false进行比较,例如if (is_null(null) == false)。

相关问题:

致命错误:不能使用函数返回值

代码不运行/我的PHP代码的某些部分被输出

如果你的PHP代码没有任何结果,或者你在网页中看到你的PHP源代码输出的部分文字,你可以很确定你的PHP实际上没有被执行。如果在浏览器中使用“查看源代码”,则可能会看到完整的PHP源代码文件。因为PHP代码嵌入在<?php ?>标记时,浏览器将尝试将它们解释为HTML标记,结果可能看起来有些混乱。

要真正运行PHP脚本,您需要:

执行脚本的web服务器 将文件扩展名设置为.php,否则web服务器不会将其解释为* 通过web服务器访问你的。php文件

*除非你重新配置,否则一切都可以配置。

最后一点尤其重要。只需双击该文件,就可以在浏览器中使用如下地址打开它:

file://C:/path/to/my/file.php

这完全绕过了您可能正在运行的任何web服务器,并且文件没有得到解释。你需要在你的web服务器上访问文件的URL,可能是这样的:

http://localhost/my/file.php

您可能还想检查是否使用了短的打开标记<?而不是<?php和您的php配置已关闭短打开标记。

还可以看到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”问题

"注意:未定义索引"或"警告:未定义数组键"

当您试图通过数组中不存在的键访问数组时发生。

一个典型的Undefined Index通知的例子是(demo)

$data = array('foo' => '42', 'bar');
echo $data['spinach'];
echo $data[1];

数组中菠菜和1都不存在,会触发E_NOTICE。在PHP 8.0中,这是一个E_WARNING。

解决方案是确保在访问索引之前存在索引或偏移量。这可能意味着您需要修复程序中的一个错误,以确保这些索引在您期望它们存在时确实存在。或者这可能意味着你需要使用array_key_exists或isset来测试索引是否存在:

$data = array('foo' => '42', 'bar');
if (array_key_exists('spinach', $data)) {
    echo $data['spinach'];
}
else {
    echo 'No key spinach in the array';
}

如果你有这样的代码:

<?php echo $_POST['message']; ?>
<form method="post" action="">
    <input type="text" name="message">
    ...

那么$_POST['message']将不会在这个页面第一次加载时设置,你将得到上述错误。只有在提交表单并再次运行此代码时,数组索引才会存在。你通常用以下方法检查:

if ($_POST)  ..  // if the $_POST array is not empty
// or
if ($_SERVER['REQUEST_METHOD'] == 'POST') ..  // page was requested with POST

相关问题:

参考文献:“Notice: Undefined variable”和“Notice: Undefined index” 所有关于Stackoverflow的PHP“注意:未定义的索引”问题 http://php.net/arrays

致命错误:[TraitA]和[TraitB]在[ClassC]组合中定义相同的属性([$x])

当类试图使用多个trait时发生,其中两个或多个trait定义了同名的属性,且属性具有不同的初始值。

例子:

<?php
trait TraitA
{
    public $x = 'a';
}
trait TraitB
{
    public $x = 'b';
}
class ClassC
{
    use TraitA, TraitB;
}

问题:虽然可以解决相互竞争的方法之间的冲突,但目前没有语法可以解决两个相互竞争的属性之间的冲突。此时唯一的解决方案是重构;也就是说,避免属性名之间产生致命错误的冲突。


相关问题:

PHP特征:如何解决属性名称冲突? 特征-属性与父类冲突