提问人: 提问时间:10/7/2012 最后编辑:85 revs, 33 users 27%miken32 更新时间:5/21/2023 访问量:276248
参考 - 这个错误在PHP中是什么意思?
Reference - What does this error mean in PHP?
问:
这是怎麽?
这是关于您在编写 PHP 时可能遇到的警告、错误和通知的一些答案,并且不知道如何修复它们。这也是一个社区维基,所以每个人都被邀请参与添加和维护这个列表。
为什么会这样?
Stack Overflow 上经常出现“标头已发送”或“调用非对象的成员”等问题。这些问题的根本原因总是一样的。因此,这些问题的答案通常会重复它们,然后向 OP 显示在其特定情况下要更改哪一行。这些答案不会为网站增加任何价值,因为它们仅适用于 OP 的特定代码。遇到相同错误的其他用户无法轻易地从中读出解决方案,因为他们过于本地化。这很可悲,因为一旦你了解了根本原因,修复错误就变得微不足道了。因此,此列表试图以一般方式解释解决方案以应用。
我应该怎么做?
如果您的问题被标记为与此问题重复,请在下面找到您的错误消息,并将修复程序应用于您的代码。答案通常包含进一步的调查链接,以防仅从一般答案中看不清楚。
如果你想做出贡献,请添加你“最喜欢的”错误消息、警告或通知,每个答案一个,一个简短的描述它的含义(即使它只是在他们的手册页面上突出显示术语),一个可能的解决方案或调试方法,以及一个有价值的现有问答列表。此外,请随时改进任何现有答案。
名单
- 什么也看不见。页面是空的和白色的。(也称为白页/死亡屏幕)
- 代码不运行/输出看起来像我的 PHP 代码的一部分
- 警告:无法修改标头信息 - 标头已发送
- 警告:mysql_fetch_array() 期望参数 1 是资源,布尔值给定,又名警告
:mysql_fetch_array():提供的参数不是有效的 MySQL 结果资源 - 警告:[function] 期望参数 1 为资源,给定布尔值
- 警告:[功能]:无法打开流:[原因]
- 警告:open_basedir限制生效
- 警告:除以零
- 警告:非法字符串偏移量“XXX”
- 警告:count():参数必须是实现 Countable 的数组或对象
- 解析错误:语法错误,意外的“[”
- 解析错误:语法错误、意外T_XXX
- 解析错误:语法错误、意外T_ENCAPSED_AND_WHITESPACE
- 解析错误:语法错误、意外T_PAAMAYIM_NEKUDOTAYIM
- 解析错误:语法错误、意外的“require_once”(T_REQUIRE_ONCE)、预期函数(T_FUNCTION)
- 解析错误:语法错误、意外T_VARIABLE
- 致命错误:允许的 XXX 字节内存大小已用尽(尝试分配 XXX 字节)
- 致命错误:超出 XX 秒的最大执行时间
- 致命错误:调用成员函数...在非对象或 null 上
- 致命错误:调用未定义的函数 XXX
- 致命错误:无法重新声明 XXX
- 致命错误:无法在写入上下文中使用函数返回值
- 致命错误:AAA::BBB() 的声明必须与 CCC::BBB() 的声明兼容'
- AAA::BBB() 的返回类型应与 CCC::BBB() 兼容,或者应使用 #[\ReturnTypeWillChange] 属性
- 致命错误:在不在对象上下文中使用$this
- 致命错误:无法将类 Closure 的对象转换为字符串
- 致命错误:未定义的类常量
- 致命错误:未捕获的 TypeError:参数 #n 必须是给定的 x、y 类型
- 注意:数组到字符串的转换(<PHP 8.0)或警告:数组到字符串的转换(>= PHP 8.0)
- 注意:尝试获取非对象错误的属性
- 注意:未定义的变量或属性
- “注意:未定义的索引”或“警告:未定义的数组键”
- 注意:未定义偏移量 XXX [参考]
- 注意:未初始化的字符串偏移量:XXX
- 注意:使用未定义的常量 XXX - 假定为“XXX”/错误:未定义的常量 XXX
- MySQL:您的 SQL 语法有错误;检查与您的MySQL服务器版本相对应的手册,以获取正确的语法以在...在线...
- 严格标准:非静态方法 [<class>::<method>] 不应静态调用
- 警告:函数期望参数 X 为布尔值/字符串/整数
- HTTP 错误 500 - 内部服务器错误
- 已弃用:不推荐使用大括号的数组和字符串偏移访问语法
另请参阅:
答:
致命错误:调用成员函数...在非对象上
发生在类似于 where is not an object 的代码中,因此无法调用。xyz->method()
xyz
method
这是一个致命错误,它将停止脚本(向前兼容性通知:从 PHP 7 开始,它将成为可捕获的错误)。
大多数情况下,这表示代码缺少对错误条件的检查。在调用对象的方法之前,请验证对象是否确实是对象。
一个典型的例子是
// ... some code using PDO
$statement = $pdo->prepare('invalid query', ...);
$statement->execute(...);
在上面的示例中,无法准备查询,并将分配给 。然后尝试调用该方法将导致致命错误,因为该值是布尔值,因此是“非对象”。prepare()
false
$statement
execute()
false
弄清楚为什么你的函数返回的是布尔值而不是对象。例如,检查对象中是否存在发生的最后一个错误。有关如何调试的详细信息将取决于如何处理所讨论的特定函数/对象/类的错误。$pdo
如果即使失败,则数据库句柄对象未传递到当前作用域。查找它的定义位置。然后将其作为参数传递,将其存储为属性,或通过全局范围共享它。->prepare
$pdo
另一个问题可能是有条件地创建一个对象,然后尝试调用该条件块之外的方法。例如
if ($someCondition) {
$myObj = new MyObj();
}
// ...
$myObj->someMethod();
如果尝试在条件块外部执行该方法,则可能无法定义对象。
相关问题:
警告:mysql_fetch_array() 期望参数 1 为资源,给定布尔值
首先也是最重要的:
请不要在新代码中使用
mysql_*
函数。它们不再维护,并被正式弃用。看到红框了吗?请改用预准备语句,并使用 PDO 或 MySQLi - 本文将帮助您确定哪个语句。如果你选择PDO,这里有一个很好的教程。
当您尝试从 的结果中获取数据但查询失败时,会发生这种情况。mysql_query
这是一个警告,不会停止脚本,但会使程序出错。
您需要检查 返回的结果mysql_query
$res = mysql_query($sql);
if (!$res) {
trigger_error(mysql_error(),E_USER_ERROR);
}
// after checking, do the fetch
相关问题:
- mysql_fetch_array() 期望参数 1 是资源,布尔值在 select 中给出
- 所有“mysql_fetch_array() 期望参数 1 是资源,给定布尔值” 关于 Stackoverflow 的问题
相关错误:
其他也需要MySQL结果资源作为参数的函数将出于相同的原因产生相同的错误。mysql*
评论
mysql_query
or die
$res = mysql_query($query)
mysql_query
mysql_fetch_array()
mysql_fetch_array() expects parameter 1 to be resource, boolean given in select
mysql_fetch_array()
警告:无法修改标头信息 - 标头已发送
当您的脚本尝试将 HTTP 标头发送到客户端但之前已经有输出时,会发生此事件,这导致标头已发送到客户端。
这是一个E_WARNING
,它不会停止脚本。
一个典型的例子是这样的模板文件:
<html>
<?php session_start(); ?>
<head><title>My Page</title>
</html>
...
该函数将尝试将带有会话 cookie 的标头发送到客户端。但是 PHP 在将元素写入输出流时已经发送了标头。你必须把它移到顶部。session_start()
<html>
session_start()
您可以通过浏览触发警告的代码之前的行并检查其输出位置来解决此问题。将任何标头发送代码移到该代码之前。
一个经常被忽视的输出是PHP关闭后的新行。当它是文件中的最后一项内容时,省略它被认为是一种标准做法。同样,此警告的另一个常见原因是当开头之前有一个空格、行或不可见字符时,导致 Web 服务器发送标头和空格/换行符,因此当 PHP 开始解析时将无法提交任何标头。?>
?>
<?php
如果文件中有多个代码块,则它们之间不应有任何空格。(注意:如果您有自动构造的代码,则可能有多个块)<?php ... ?>
此外,请确保代码中没有任何字节顺序标记,例如,当脚本的编码为 UTF-8 和 BOM 时。
相关问题:
评论
<?php ?>
<?php ?> <?php ?>
解析错误:语法错误、意外T_XXX
当您在意想不到的位置有T_XXX
令牌、不平衡(多余的)括号、使用短标签而没有在 php.ini 中激活它等等时,就会发生这种情况。
相关问题:
- 参考资料:PHP解析/语法错误;以及如何解决它们?
- 解析错误:语法错误:意外的“{”
- 解析错误:语法错误,我的PHP代码中意外的文件结尾
- 解析错误:语法错误,意外的“<”在 - 修复?
- 解析错误:语法错误,意外的“?'
如需进一步帮助,请参阅:
- http://phpcodechecker.com/ - 这确实为您的语法问题提供了一些更有用的解释。
解析错误:语法错误、意外T_PAAMAYIM_NEKUDOTAYIM
范围解析运算符在希伯来语 פעמיים נקודתיים 中也称为“Paamayim Nekudotayim”。意思是“双冒号”。
如果您无意中输入了代码,通常会发生此错误。::
相关问题:
- 参考资料:PHP解析/语法错误;以及如何解决它们?
- PHP中的两个冒号是什么意思?
- PHP中的::(双冒号)和->(箭头)有什么区别?
- 意想不到的T_PAAMAYIM_NEKUDOTAYIM,期待T_NS_Separator
文档:
评论
a()::b;
$a=::;
致命错误:允许的 XXX 字节内存大小已用尽(尝试分配 XXX 字节)
内存不足,无法运行脚本。PHP 已达到内存限制并停止执行。此错误是致命的,脚本将停止。内存限制的值可以在文件中配置,也可以在脚本中使用(这将覆盖 中定义的值)。内存限制的目的是防止单个 PHP 脚本吞噬所有可用内存并使整个 Web 服务器瘫痪。php.ini
ini_set('memory_limit', '128 M');
php.ini
首先要做的是尽量减少脚本所需的内存量。例如,如果要将大文件读取到变量中,或者从数据库中获取许多记录并将它们全部存储在数组中,则可能会占用大量内存。更改代码,改为逐行读取文件或一次读取一个数据库记录,而无需将它们全部存储在内存中。这确实需要对幕后发生的事情以及数据存储在内存中而不是其他地方的情况有一点概念性的认识。
如果此错误发生在脚本未执行内存密集型工作时,则需要检查代码以查看是否存在内存泄漏。memory_get_usage
功能是你的朋友。
相关问题:
致命错误:在不在对象上下文中使用$this
$this
是 PHP 中一个特殊的变量,不能赋值。如果在不存在的上下文中访问它,则会给出此致命错误。
可能会发生以下错误:
如果静态调用非静态方法。例:
class Foo { protected $var; public function __construct($var) { $this->var = $var; } public static function bar () { // ^^^^^^ echo $this->var; // ^^^^^ } } Foo::bar();
如何修复:再次查看代码,只能在对象上下文中使用,而不应在静态方法中使用。此外,静态方法不应访问非静态属性。用于访问静态属性。
$this
self::$static_property
如果类方法中的代码已被复制到普通函数中,或者只是全局范围并保留特殊变量。
解决方法:查看代码并替换为其他替换变量。$this
$this
相关问题:
- 将非静态方法作为静态方法调用:PHP 致命错误:不在对象上下文中使用$this
- 复制代码:致命错误:不在对象上下文中使用$this
- Stackoverflow 上的所有“在不在对象上下文中使用$this”问题
评论
$closure = function() { self::method(); }
$this
$closure = function() { $this->method(); };
致命错误:无法在写入上下文中使用函数返回值
这通常发生在直接使用 函数时。empty
例:
if (empty(is_null(null))) {
echo 'empty';
}
这是因为 empty
是一种语言结构而不是函数,因此在 5.5 之前的 PHP 版本中不能使用表达式作为参数来调用它。在 PHP 5.5 之前,参数 to 必须是变量,但在 PHP 5.5+ 中允许使用任意表达式(例如函数的返回值)。empty()
empty
,尽管它的名字,实际上并没有检查变量是否为“空”。相反,它会检查变量是否不存在,或者 .表达式(如示例中所示)将始终被视为存在,因此这里仅检查它是否等于 false。您可以在此处替换为 ,例如 ,或显式与 false 进行比较,例如 。== false
is_null(null)
empty
empty()
!
if (!is_null(null))
if (is_null(null) == false)
相关问题:
“注意:未定义的索引”或“警告:未定义的数组键”
当您尝试通过数组中不存在的键访问数组时发生。
通知的典型示例是(演示Undefined Index
)
$data = array('foo' => '42', 'bar');
echo $data['spinach'];
echo $data[1];
数组中不存在 和 ,从而触发E_NOTICE
。在 PHP 8.0 中,这是一个E_WARNING。spinach
1
解决方案是在访问索引或偏移量之前确保该索引或偏移量存在。这可能意味着您需要修复程序中的错误,以确保这些索引确实存在。或者,这可能意味着您需要使用 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
相关问题:
评论
if(!empty($_POST['message'])){ //do stuff }
MySQL:您的 SQL 语法有错误;检查与您的MySQL服务器版本相对应的手册,以获取正确的语法以在...在线...
此错误通常是因为您忘记正确转义传递给MySQL查询的数据。
不该做什么的例子(“坏主意”):
$query = "UPDATE `posts` SET my_text='{$_POST['text']}' WHERE id={$_GET['id']}";
mysqli_query($db, $query);
此代码可以包含在带有要提交的表单的页面中,其中包含 http://example.com/edit.php?id=10 等 URL(用于编辑帖子 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 Tables”XKCD 漫画中的 SQL 注入是如何工作的?
- 绕过 mysql_real_escape_string() 的 SQL 注入
评论
警告:open_basedir限制生效
此警告可能与与文件和目录访问相关的各种功能一起出现。它会警告配置问题。
当它出现时,表示已禁止访问某些文件。
警告本身不会破坏任何内容,但如果阻止文件访问,脚本通常无法正常工作。
解决方法通常是更改PHP配置,相关设置称为open_basedir
。
有时使用错误的文件或目录名称,解决方法是使用正确的文件或目录名称。
相关问题:
评论
什么也看不见。页面是空的和白色的。
也称为死亡白页或死亡白屏。当错误报告关闭并发生致命错误(通常是语法错误)时,会发生这种情况。
如果启用了错误日志记录,则会在错误日志中找到具体的错误消息。这通常位于一个名为“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“死亡白页”问题
相关错误:
评论
error_reporting(~0);
为什么不呢?这就是评估的内容,并且不那么神秘。-1
~0
~0
1111'1111'1111'1111
1111'1111'1111'1111
return false;
注意:使用未定义的常量 XXX - 假定为“XXX”
或者,在 PHP 7.2 或更高版本中:
警告:使用未定义的常量 XXX - 假定为“XXX”(这将在未来版本的 PHP 中抛出错误)
或者,在 PHP 8.0 或更高版本中:
错误:未定义的常量 XXX
当代码中使用令牌并且看起来是一个常量,但未定义该名称的常量时,会发生这种情况。
此通知的最常见原因之一是未能引用用作关联数组键的字符串。
例如:
// Wrong
echo $array[key];
// Right
echo $array['key'];
另一个常见原因是变量名称前面缺少(美元)符号:$
// Wrong
echo varName;
// Right
echo $varName;
或者,您可能拼错了其他常量或关键字:
// Wrong
$foo = fasle;
// Right
$foo = false;
当您尝试访问由该库定义的常量时,它也可能表明缺少所需的 PHP 扩展或库。
相关问题:
评论
注意:未定义的变量
当您尝试使用以前未定义的变量时发生。
一个典型的例子是
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 的 “Notice: Undefined variable”, “Notice: Undefined index” 和 “Notice: Undefined offset”
- 参考:什么是变量范围,哪些变量可以从何处访问,什么是“未定义的变量”错误?
致命错误:调用未定义的函数 XXX
当您尝试调用尚未定义的函数时发生。常见原因包括缺少扩展名和包含、条件函数声明、函数声明中的函数或简单的拼写错误。
示例 1 - 条件函数声明
$someCondition = false;
if ($someCondition === true) {
function fn() {
return 1;
}
}
echo fn(); // triggers error
在这种情况下,永远不会被声明,因为不为 true。fn()
$someCondition
示例 2 - 函数声明中的函数
function createFn()
{
function fn() {
return 1;
}
}
echo fn(); // triggers error
在这种情况下,只会在调用一次时声明。请注意,后续调用 将触发有关重新声明现有函数的错误。fn
createFn()
createFn()
您可能还会在 PHP 内置函数中看到这一点。尝试在官方手册中搜索该函数,并查看它所属的“扩展”(PHP模块),以及支持它的PHP版本。
如果缺少扩展,请安装该扩展并在 php.ini 中启用它。请参阅 PHP 手册中的安装说明,了解函数所在的扩展。您也可以使用包管理器(例如 在 Debian 或 Ubuntu 中,在 Red Hat 或 CentOS 中),或共享主机环境中的控制面板。apt
yum
如果该函数是在您正在使用的较新版本的 PHP 中引入的,您可以在手册或其注释部分找到指向替代实现的链接。如果它已从 PHP 中删除,请查找有关原因的信息,因为它可能不再需要。
如果缺少 include,请确保在调用函数之前包含声明函数的文件。
如果出现错别字,请纠正错别字。
相关问题:
警告:[功能]:无法打开流:[原因]
当您通常通过 调用文件时,就会发生这种情况,或者 PHP 找不到该文件或没有足够的权限来加载该文件。include
require
fopen
发生这种情况的原因有多种:
- 文件路径错误
- 文件路径是相对路径
- 包含路径错误
- 权限限制性太强
- SELinux 生效
- 还有很多......
一个常见的错误是不使用绝对路径。这可以通过使用完整路径或魔术常量(如 或 )轻松解决:__DIR__
dirname(__FILE__)
include __DIR__ . '/inc/globals.inc.php';
或:
require dirname(__FILE__) . '/inc/globals.inc.php';
确保使用正确的路径是解决这些问题的一个步骤,这也可能与不存在的文件、阻止访问的文件系统权限或 PHP 本身的开放限制有关。
快速解决此问题的最佳方法是遵循下面的故障排除清单。
相关问题:
相关错误:
致命错误:无法重新声明类 [类名]
致命错误:无法重新声明 [函数名称]
这意味着您要么两次使用相同的函数/类名,并且需要重命名其中一个,要么是因为您已经使用了 or 应该在何处使用 or .require
include
require_once
include_once
当一个类或函数在 PHP 中声明时,它是不可变的,以后不能用新值声明。
请考虑以下代码:
类.php
<?php
class MyClass
{
public function doSomething()
{
// do stuff here
}
}
索引.php
<?php
function do_stuff()
{
require 'class.php';
$obj = new MyClass;
$obj->doSomething();
}
do_stuff();
do_stuff();
第二次调用 将产生上述错误。通过更改为 ,我们可以确定包含定义的文件只会加载一次,并且可以避免错误。do_stuff()
require
require_once
MyClass
评论
解析错误:语法错误、意外T_ENCAPSED_AND_WHITESPACE
在 PHP 8.0 及更高版本中,消息是:
语法错误,意外的字符串内容“”,需要“-”或标识符、变量或数字
当整个复数变量构造未包含在 中时,尝试使用带引号的键引用数组值以在双引号字符串中进行插值时,最常遇到此错误。{}
错误案例:
这将导致:Unexpected 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]";
//------------------------------------------------------------------------^^^^^
整个复数组变量和键可以括在 中,在这种情况下,应将它们括起来以避免 .PHP 文档建议对复杂变量使用这种语法。{}
E_NOTICE
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 字符串 手册页中有关变量解析的部分
警告:[function] 期望参数 1 为资源,给定布尔值
(警告的更一般变体:mysql_fetch_array() 期望参数 1 是资源,给定布尔值)
资源是 PHP 中的一种类型(如字符串、整数或对象)。资源是一个不透明的 blob,其本身没有内在的意义值。资源特定于一组特定的 PHP 函数或扩展,并由其定义。例如,Mysql 扩展定义了两种资源类型:
MySQL模块中使用了两种资源类型。第一个是数据库连接的链接标识符,第二个是保存查询结果的资源。
cURL 扩展定义了另外两种资源类型:
...cURL 句柄和 cURL 多句柄。
当 ed 时,这些值如下所示:var_dump
$resource = curl_init();
var_dump($resource);
resource(1) of type (curl)
这就是大多数资源的全部内容,即某种类型的数字标识符 () ()。(1)
(curl)
你随身携带这些资源,并将它们传递给不同的功能,这些资源对它们有意义。通常,这些函数在后台分配某些数据,资源只是一个参考,它们用来在内部跟踪这些数据。
“......期望参数 1 是 Resource,Boolean Given“错误通常是未经检查的操作的结果,该操作本应创建资源,但实际上返回了该操作。例如,fopen
函数有这样的描述:false
返回值
在成功或错误时返回文件指针资源。
FALSE
因此,在此代码中,要么是:$fp
resource(x) of type (stream)
false
$fp = fopen(...);
如果不检查操作是成功还是失败,因此是有效资源还是传递给另一个需要资源的函数,则可能会出现上述错误:fopen
$fp
false
$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);
相关错误:
解析错误:语法错误、意外T_VARIABLE
可能的情况
我似乎找不到我的代码哪里出错了。这是我的完整错误:
解析错误:语法错误,x 行出现意外T_VARIABLE
我正在尝试什么
$sql = 'SELECT * FROM dealer WHERE id="'$id.'"';
答
解析错误:程序的语法问题,例如在语句末尾留下分号,或者像上面的情况一样,缺少运算符。解释器在遇到解析错误时停止运行程序。.
简单来说,这是一个语法错误,这意味着您的代码中有某些东西阻止了它被正确解析并因此运行。
您应该做的是仔细检查错误所在的行是否有任何简单的错误。
该错误消息意味着在文件的第 x 行中,PHP 解释器希望看到一个左括号,但相反,它遇到了一个名为 .那个东西叫做.这是PHP解释器表达程序不同基本部分的方式。当解释器在程序中读取时,它会将您编写的内容转换为标记列表。无论你在程序中放置一个变量,解释器的列表中都有一个标记。T_VARIABLE
T_VARIABLE
token
T_VARIABLE
因此,请确保至少在 .生产脚本中不应存在分析错误。E_PARSE
php.ini
我总是建议在编码时添加以下语句:
error_reporting(E_ALL);
此外,使用 IDE 是个好主意,它可以让您知道在键入时解析错误。您可以使用:
相关问题:
- 参考资料:PHP解析/语法错误;以及如何解决它们?
注意:未初始化的字符串偏移量:*
顾名思义,当您最有可能尝试遍历或从具有不存在键的数组中查找值时,就会发生此类错误。
考虑你,正试图显示每个字母$string
$string = 'ABCD';
for ($i=0, $len = strlen($string); $i <= $len; $i++){
echo "$string[$i] \n";
}
上面的例子将生成(在线演示):
A
B
C
D
Notice: Uninitialized string offset: 4 in XXX on line X
而且,一旦脚本完成回显,你就会得到错误,因为在循环中,你已经告诉 PHP 向你显示 Which, 存在的第一个到第五个字符串字符,但由于循环开始计数并从它到达时回显,它将抛出一个偏移错误。D
for()
'ABCD'
0
D
4
类似错误:
警告:除以零
警告消息“除以零”是PHP新开发人员最常被问到的问题之一。此错误不会导致异常,因此,某些开发人员偶尔会通过在表达式前添加错误抑制运算符 @ 来抑制警告。例如:
$value = @(2 / 0);
但是,与任何警告一样,最好的方法是追踪警告的原因并解决它。警告的原因将来自您尝试除以 0、等于 0 的变量或尚未赋值的变量(因为 NULL == 0)的任何实例,因为结果将是“未定义”。
若要更正此警告,应重写表达式以检查值是否为 0,如果是,请执行其他操作。如果该值为零,则不应除以,或者应将值更改为 1,然后再除以,因此除法的结果等同于仅除以附加变量。
if ( $var1 == 0 ) { // check if var1 equals zero
$var1 = 1; // var1 equaled zero so change var1 to equal one instead
$var3 = ($var2 / $var1); // divide var1/var2 ie. 1/1
} else {
$var3 = ($var2 / $var1); // if var1 does not equal zero, divide
}
相关问题:
评论
$var1
$var3
$var2
if
严格标准:非静态方法 [<class>::<method>] 不应静态调用
当您尝试在类上调用非静态方法时发生,因为它是静态的,并且您的设置中也有该标志。E_STRICT
error_reporting()
例:
class HTML {
public function br() {
echo '<br>';
}
}
HTML::br()
或$html::br()
实际上,您可以通过不添加 来避免此错误,例如E_STRICT
error_reporting()
error_reporting(E_ALL & ~E_STRICT);
因为 PHP 5.4.0 及以上版本,包含在 [ref] 中。但这是不可取的。解决方案是将预期的静态函数定义为实际函数:E_STRICT
E_ALL
static
public static function br() {
echo '<br>';
}
或常规调用函数:
$html = new HTML();
$html->br();
相关问题:
解析错误:语法错误,意外的“[”
此错误来自两个变量:
变体 1
$arr = [1, 2, 3];
这个数组初始值设定项语法仅在 PHP 5.4 中引入;它将在此之前的版本上引发解析器错误。如果可能,请升级安装或使用旧语法:
$arr = array(1, 2, 3);
另请参阅手册中的此示例。
变体 2
$suffix = explode(',', 'foo,bar')[1];
PHP 5.4 中还引入了数组取消引用函数结果。如果无法升级,则需要使用(临时)变量:
$parts = explode(',', 'foo,bar');
$suffix = $parts[1];
另请参阅手册中的此示例。
代码不运行/输出看起来像我的 PHP 代码的一部分
如果你没有看到你的PHP代码有任何结果,和/或者你在网页中看到你的PHP源代码输出的一部分,你可以非常确定你的PHP实际上没有被执行。如果您在浏览器中使用“查看源代码”,您可能会看到整个 PHP 源代码文件。由于PHP代码嵌入在标签中,浏览器将尝试将其解释为HTML标签,结果可能看起来有些混乱。<?php ?>
要实际运行 PHP 脚本,您需要:
- 执行脚本的 Web 服务器
- 将文件扩展名设置为 .php,否则 Web 服务器不会将其解释为*
- 通过 Web 服务器访问 .php 文件
* 除非您重新配置它,否则一切都可以配置。
最后一个尤为重要。只需双击该文件,它可能会使用如下地址在浏览器中打开它:
file://C:/path/to/my/file.php
这完全绕过了您可能正在运行的任何 Web 服务器,并且文件没有得到解释。您需要在 Web 服务器上访问文件的 URL,可能如下所示:
http://localhost/my/file.php
您可能还想检查您是否正在使用短开放标签,而不是您的 PHP 配置是否关闭了短开放标签。<?
<?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
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
}
如果此通知出现在您意想不到的地方,则表示您认为是字符串的变量实际上是一个数组。这意味着你的代码中有一个错误,使这个变量成为一个数组,而不是你期望的字符串。
注意:尝试获取非对象错误的属性
当您尝试在没有对象的情况下访问对象的属性时发生。
非对象通知的典型示例是
$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;
相关错误:
评论
json_decode
现在默认返回一个实例,因此示例代码实际上可以工作。stdclass
json_decode
现在默认返回 stdclass
的实例”?我在更新日志中找不到。
json_decode('[{"name": "hakre"}]', true)
将返回一个数组,否则返回一个对象stdclass
警告:非法字符串偏移量“XXX”
当您尝试使用方括号语法访问数组元素时,会发生这种情况,但您是在字符串上执行此操作,而不是在数组上执行此操作,因此该操作显然没有意义。
例:
$var = "test";
echo $var["a_key"];
如果您认为该变量应该是一个数组,请查看它的来源并在那里解决问题。
警告:mysql_connect():用户“name”@“host”的访问被拒绝
当您使用无效或缺失的凭据(用户名/密码)连接到 MySQL/MariaDB 服务器时,会出现此警告。因此,这通常不是代码问题,而是服务器配置问题。
有关示例,请参见
mysql_connect(“localhost”, “user”, “pw”)
的手册页。检查您是否实际使用了 和 .
$username
$password
- 您不使用密码获得访问权限的情况并不常见 - 这就是警告时发生的情况: 说.
(using password: NO)
通常只有本地测试服务器允许使用用户名、无密码和数据库名称进行连接。
root
test
您可以使用命令行客户端测试它们是否真的正确:
mysql --user="username" --password="password" testdb
用户名和密码区分大小写,不会忽略空格。如果您的密码包含元字符,请转义它们,或将密码放在单引号中。
$
大多数共享主机提供商预先声明与 unix 用户帐户相关的 mysql 帐户(有时只是前缀或额外的数字后缀)。有关模式或文档,请参阅文档,以及用于设置密码的 CPanel 或任何接口。
请参阅MySQL手册中的使用命令行添加用户帐户。以管理员用户身份连接时,您可以发出如下查询:
CREATE USER 'username'@'localhost' IDENTIFIED BY 'newpassword';
如果您无法修复您的凭据,那么要求互联网“请帮忙”将不起作用。只有您和您的托管服务提供商才具有诊断和修复问题的权限和足够的访问权限。
- 您不使用密码获得访问权限的情况并不常见 - 这就是警告时发生的情况: 说.
验证是否可以使用提供程序提供的主机名访问数据库服务器:
ping dbserver.hoster.example.net
直接从 Web 服务器上的 SSH 控制台检查这一点。从本地开发客户端到共享托管服务器的测试几乎没有意义。
通常,您只希望服务器名称为 ,它通常在可用时使用本地命名套接字。其他时候,您可以尝试作为后备。
"localhost"
"127.0.0.1"
如果您的 MySQL/MariaDB 服务器侦听不同的端口,请使用 .
"servername:3306"
如果失败,则可能是防火墙问题。(题外话,不是编程问题。无法进行远程猜测帮助。
当使用常量时,例如 或者,检查它们是否已实际定义。
DB_USER
DB_PASSWORD
如果你得到 a 和 a ,那就是你的问题。
"Warning: Access defined for 'DB_USER'@'host'"
"Notice: use of undefined constant 'DB_PASS'"
验证您的例如 实际上包括在内等等。
xy/db-config.php
检查是否正确设置了
GRANT
权限。仅仅拥有 + 对是不够的。
username
password
每个 MySQL/MariaDB 帐户都可以有一组附加的权限。
这些可以限制允许连接到哪些数据库、连接可能来自哪个客户端/服务器以及允许哪些查询。
因此,如果您无权从特定表或 /(更常见的是任何内容)访问,则“拒绝访问”警告也可能出现在
mysql_query
调用中。SELECT
INSERT
UPDATE
DELETE
使用管理员帐户连接每个命令行客户端时,可以通过如下查询来调整帐户权限:
GRANT ALL ON yourdb.* TO 'username'@'localhost';
如果警告首先出现,则您可能有一个 php.ini 预配置的帐户/密码对。
Warning: mysql_query(): Access denied for user ''@'localhost'
检查并具有有意义的值。
mysql.default_user=
mysql.default_password=
通常,这是提供程序配置。因此,请联系他们的支持人员以解决不匹配的情况。
查找共享主机提供商的文档:
例如 HostGator、GoDaddy、1and1、DigitalOcean、BlueHost、DreamHost、MediaTemple、ixWebhosting、lunarhosting,或者只是谷歌你的。
否则,请通过他们的支持渠道咨询您的虚拟主机提供商。
请注意,您可能还耗尽了可用的连接池。对于并发连接过多,您将收到拒绝访问警告。(您必须调查设置。这是一个偏离主题的服务器配置问题,而不是编程问题。
您的 libmysql 客户端版本可能与数据库服务器不兼容。通常,MySQL和MariaDB服务器可以通过在驱动程序中编译的PHP访问。如果您有自定义设置,或者过时的 PHP 版本,以及更新得多的数据库服务器,或者明显过时的数据库服务器,那么版本不匹配可能会阻止连接。(不,你必须调查自己。没有人能猜到你的设置)。
更多参考资料:
- Serverfault:'root'@'name of the computer' 的 mysql 访问被拒绝
- 警告:mysql_connect():访问被拒绝
- 警告:用户 ''@'localhost' 的 mysql_select_db() 访问被拒绝(使用密码:NO)
- 用户“root”@“localhost”与 PHPMyAdmin 的访问被拒绝
顺便说一句,您可能不想再使用
mysql_*
函数了。新手经常迁移到 mysqli,但这同样乏味。相反,请阅读 PDO 和准备好的声明。
$db = new PDO("mysql:host=localhost;dbname=testdb", "username", "password");
评论
致命错误:[TraitA] 和 [TraitB] 在 [ClassC] 的组合中定义了相同的属性 ([$x])
当一个类尝试使用
多个 Trait 时发生,其中两个或多个 Trait 以相同的名称定义了一个属性,并且该属性具有不同的初始值。
例:
<?php
trait TraitA
{
public $x = 'a';
}
trait TraitB
{
public $x = 'b';
}
class ClassC
{
use TraitA, TraitB;
}
问题:虽然可以解决竞争方法之间的冲突,但目前没有语法可以解决两个竞争属性之间的冲突。目前唯一的解决方案是重构;即,避免属性名称之间的冲突,从而产生致命错误。
相关问题:
评论
警告:function() 期望参数 X 为布尔值(或整数、字符串等)
如果将错误类型的参数传递给函数,并且 PHP 无法自动转换它,则会抛出警告。此警告标识哪个参数是问题,以及预期的数据类型。解决方案:将指示的参数更改为正确的数据类型。
例如,以下代码:
echo substr(["foo"], 23);
结果如下:
PHP 警告:substr() 期望参数 1 是字符串,给定数组
HTTP 错误 500 - 内部服务器错误
HTTP 状态代码 500 和典型的 Apache 或浏览器警告是一个非常宽泛的消息。这不是实际的错误。要确定它是Web服务器配置错误()还是PHP致命错误,您必须查看错误.log
。.htaccess
您通常可以在以下位置找到 Web 服务器日志:
/var/log/apache2
在 Linux 服务器上,通常用于本地和虚拟主机。/var/www/_user12345_/logs
或共享主机计划中的类似内容。
通常每个文件夹旁边都有一个目录。logs/
htdocs/
C:\xampp\apache\logs\error.log
用于 Apache+PHP 的 WAMP/XAMPP 发行版。- 或者,只需使用文件搜索功能来查找称为“error.log”的任何内容。
或者查看您的 Apache 及其指令。httpd.conf
ErrorLog
/var/log/nginx/nginx_error.log
对于 NGINX。C:\inetpub\logs\LogFiles
用于 IIS。- 幸运的是,这仍然不常见,但也可能在 Linux 设置中保存部分日志。
journalctl -r -u apache2.service
这是一个文本文件。搜索与错误时间最匹配的条目,并使用错误消息的重要部分(来自“PHP Error: ...”直到“排队...”)进行进一步的谷歌搜索。
[Mon 22:10] [:error] [pid 12345] [client 127.0.0.1] FastCGI: server "/fcgi/p73" stderr: PHP message:
PHP Error: Unfiltered input
variable $_JSON['pokestop_lng'] in filyfile.php on line 845
对于 FPM 设置,您通常会在这里看到致命的 PHP 错误。而较旧的mod_php(共享主机)配置通常会混合警告和通知(通常也值得检查)。
如果未配置为使用系统或 Apache 日志记录机制,您可能还需要查看 PHP 的错误 .log。通常,保留默认值并启用 + 以显示具体错误会更简单。毕竟,HTTP 500 的包罗万象页面只是 PHP 白屏死机的变体。error_display
error_reporting
另请参阅:
- 500 php 文件而不是 html 的内部服务器错误
- 我怎样才能让PHP显示错误而不是给我500内部服务器错误
- 如何在 IIS7 上显示和记录 PHP 错误?
- 如何修复 WordPress 中的 500 内部服务器错误
警告:count():参数必须是实现 Countable 的数组或对象
明显;传递给函数的参数必须是可数的,通常是一个数组。count()
可能的问题是传递了标量值(如字符串或整数),或者传递了未实现接口的对象。使用相关变量可以显示是否是这种情况。Countable
var_dump()
致命错误:无法将 Closure 类的对象转换为字符串
这意味着您没有执行匿名函数(或闭包)。
对于此示例,使用箭头函数将引发错误:
echo $fn = fn($x = 42) => $x;
或用于任何匿名函数
echo function($x = 42) { return $x; };
要解决此错误,您需要执行闭包。
echo $fn = (fn($x = 42) => $x)(30); // take notice of the 2 sets of brackets
echo (function($x = 42) { return $x; })(30);
这种语法称为 IIFE,它是在 PHP 7 中添加的。
已弃用:不推荐使用大括号的数组和字符串偏移访问语法
在 PHP 7.4.0 之前,字符串偏移量和数组元素可以通过大括号访问:{}
$string = 'abc';
echo $string{0}; // a
$array = [1, 2, 3];
echo $array{0}; // 1
自 PHP 7.4.0 以来,这已被弃用,并生成警告:
已弃用:不推荐使用大括号的数组和字符串偏移访问语法
必须使用方括号来访问字符串偏移量和数组元素:[]
$string = 'abc';
echo $string[0]; // a
$array = [1, 2, 3];
echo $array[0]; // 1
此更改的 RFC 链接到一个 PHP 脚本,该脚本试图以机械方式修复此问题。
致命错误:未定义的类常量
此错误意味着您尝试使用不存在的类常量。与其他“未定义”通知和警告不同,这是一个致命错误,将立即停止脚本。
首先要检查的是印刷错误。确认在类中定义了常量,并使用适当的命名空间调用该常量。还要确认已包含所有适当的文件来解析该常量。
致命错误:未捕获的 TypeError:some_function():参数 #1 必须是给定的 x、y 类型
此错误本身就解释了。您的代码尝试调用并传递了错误类型的数据作为参数之一。例如:some_function()
<?php declare(strict_types=1);
function multiply(int $x, int $y) { return $x * $y; }
echo multiply("3", 4);
由于被调用函数的第一个参数是标量类型,并且调用位于启用了严格类型的文件中 (),因此在向其传递 a 时会出现类型错误:int
stict_types=1
string
致命错误:未捕获的 TypeError:multiply():参数 #1 ($x) 必须是整数类型,字符串在...
致命错误:超出 XX 秒的最大执行时间
每个 PHP 页面请求或脚本调用都会测量 PHP 代码执行了多长时间。如果达到配置的限制,脚本将中止并显示此消息。
请注意,时间通常不包括“在”PHP之外发生的事情,例如等待数据库结果的时间,或者用 执行的外部程序等。例外情况是当 PHP 在 Windows 上运行时,测量的时间是“时钟时间”,并且确实包括这些外部等待时间。shell_exec
常见原因
- 无限循环。错误编写的 或循环可能永远不会完成,这意味着 PHP 将永远持续运行。甚至循环也可以是无限的,例如,如果遍历 Iterator 对象或生成器函数。
while
do...while
for
foreach
- 大型数据集。即使你的循环不是无限的,如果它正在做很多工作,如果它正在处理大量结果,它可能需要太长时间才能完成。
更改限制
如果您知道您的进程很慢,则可以配置时间限制:
- 在 php.ini 中,使用 max_execution_time 设置。
- 在脚本运行时,使用 set_time_limit 函数。请注意,调用此函数会将测量时间重置为零,因此意味着“无论脚本已经花费了多长时间,都允许再留出 10 秒”。
set_time_limit(10);
这两种机制都应该被赋予秒数,或者表示“无限制”的特殊值。设置“无限制”对于您真正打算在后台永久运行的命令行脚本最有用;对于网页,最好设置一些有限值,即使它非常大,以防止代码中的错误导致整个系统无响应。0
评论