这是关于编程PHP时可能遇到的警告,错误和通知的一些答案,并且不知道如何解决它们。这也是社区Wiki,因此邀请每个人参与添加和维护此列表。
Stack Overflow上经常出现"Headers already sent"或"Calling a member of a non-object"等问题。这些问题的根本原因总是一样的。因此,这些问题的答案通常会重复这些问题,然后向OP显示在特定情况下要更改的行。这些答案不会为网站添加任何价值,因为它们仅适用于OP的特定代码。具有相同错误的其他用户不能轻易地从中读取解决方案,因为它们过于本地化。这很难过,因为一旦你理解了根本原因,修复错误是微不足道的。因此,该列表试图以一般的方式解释解决方案。
如果您的问题已被标记为此问题的副本,请在下面找到您的错误消息并将修复程序应用于您的代码。答案通常包含进一步的调查链接,以防单独从一般答案中得出结论。
如果您想贡献,请添加您的“收藏”错误消息,警告或通知,每个答案一个,简短描述含义(即使它只是突出显示其手册页的术语),可能的解决方案或调试方法和有价值的现有Q& A列表。此外,随时可以改善任何现有的答案。
另见,见:
答案 0 :(得分:259)
当您的脚本尝试向客户端发送HTTP标头但之前已经输出时,会发生这种情况,这导致标头已经发送到客户端。
这是一个E_WARNING
,它不会停止脚本。
典型的例子是这样的模板文件:
<html>
<?php session_start(); ?>
<head><title>My Page</title>
</html>
...
session_start()
函数将尝试将带有会话cookie的标头发送到客户端。但PHP在将<html>
元素写入输出流时已经发送了标头。您必须将session_start()
移至顶部。
您可以通过在之前行触发警告并检查输出位置来解决此问题。在该代码之前移动任何标题发送代码。
经常被忽视的输出是PHP关闭?>
后的新行。当它是文件中的最后一项时,忽略?>
被认为是标准做法。同样,这个警告的另一个常见原因是当开头<?php
前面有一个空的空格,行或不可见的字符时,导致Web服务器发送标题和空白/换行因此当PHP开始解析时赢了'能够提交任何标题。
如果您的文件中包含多个<?php ... ?>
代码块,则它们之间不应有任何空格。 (注意:如果您有自动构造的代码,则可能有多个块)
还要确保代码中没有任何字节顺序标记,例如当脚本的编码为带有BOM的UTF-8时。
相关问题:
答案 1 :(得分:178)
发生代码类似于xyz->method()
的代码,其中xyz
不是对象,因此无法调用method
。
这是一个致命的错误,它将停止脚本(向前兼容性通知:从PHP 7开始它将成为一个可捕获的错误)。
大多数情况下,这表示代码缺少对错误条件的检查。在调用其方法之前验证对象实际上是一个对象。
typical示例
// ... some code using PDO
$statement = $pdo->prepare('invalid query', ...);
$statement->execute(...);
在上面的示例中,无法准备查询,prepare()
会将false
分配给$statement
。尝试调用execute()
方法将导致致命错误,因为false
是“非对象”,因为该值是布尔值。
找出为什么你的函数返回一个布尔值而不是一个对象。例如,检查$pdo
对象是否发生了上一个错误。有关如何调试此问题的详细信息将取决于如何处理有问题的特定函数/对象/类的错误。
如果即使->prepare
失败,那么您的$pdo
数据库句柄对象didn't get passed into the current scope也是如此。找到它定义的位置。然后将其作为参数传递,将其存储为属性,或通过全局范围共享它。
另一个问题可能是有条件地创建一个对象,然后尝试调用该条件块之外的方法。例如
if ($someCondition) {
$myObj = new MyObj();
}
// ...
$myObj->someMethod();
通过尝试在条件块之外执行方法,可能无法定义您的对象。
相关问题:
答案 2 :(得分:112)
也称为白色死亡页面或白色死亡屏幕。当关闭错误报告并发生致命错误(通常是语法错误)时会发生这种情况。
如果启用了错误日志记录,您将在错误日志中找到具体的错误消息。这通常位于名为“php_errors.log”的文件中,位于中心位置(例如许多Linux环境中的/var/log/apache2
)或脚本本身的目录(有时在共享托管环境中使用)。 / p>
有时临时启用错误显示可能更为直接。然后白页将显示错误消息。请注意,因为访问该网站的每个人都可以看到这些错误。
这可以通过在脚本顶部添加以下PHP代码来轻松完成:
ini_set('display_errors', 1); error_reporting(~0);
代码将打开错误显示并将报告设置为最高级别。
由于ini_set()
在运行时执行,因此它对解析/语法错误没有影响。这些错误将出现在日志中。如果您想在输出中显示它们(例如在浏览器中),则必须将display_startup_errors
指令设置为true
。在php.ini
或.htaccess
或any other method that affects the configuration before runtime中执行此操作。
您可以使用相同的方法设置log_errors和error_log指令,以选择您自己的日志文件位置。
查看日志或使用显示,您将获得更好的错误消息以及脚本停止的代码行。
相关问题:
相关错误:
答案 3 :(得分:96)
当您尝试通过数组中不存在的键访问数组时发生。
Undefined Index
通知的典型示例是(demo)
$data = array('foo' => '42', 'bar');
echo $data['spinach'];
echo $data[1];
数组中不存在spinach
和1
,导致E_NOTICE
被触发。
解决方案是在访问索引之前确保索引或偏移量存在。这可能意味着您需要修复程序中的错误,以确保这些索引确实存在。或者它可能意味着您需要使用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
相关问题:
答案 4 :(得分:83)
首先是:
Please, don't use
mysql_*
functions in new code。它们不再被维护and are officially deprecated。请参阅red box?转而了解prepared statements,并使用PDO或MySQLi - this article将帮助您确定哪个。如果您选择PDO here is a good tutorial。
当您尝试从mysql_query
的结果中获取数据但查询失败时会发生这种情况。
这是一个警告,不会停止脚本,但会使您的程序出错。
您需要通过
检查mysql_query
返回的结果
$res = mysql_query($sql);
if (!$res) {
die(mysql_error());
}
// after checking, do the fetch
相关问题:
相关错误:
其他mysql*
函数也会将MySQL结果资源作为参数,但出于同样的原因会产生相同的错误。
答案 5 :(得分:74)
$this
is a special variable in 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
替换为其他替换变量。
相关问题:
答案 6 :(得分:72)
当您尝试调用尚未定义的函数时发生。常见原因包括缺少扩展和包含,条件函数声明,函数声明中的函数或简单的拼写错误。
示例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
在这种情况下,只有在fn
被调用时才会声明createFn()
。请注意,对createFn()
的后续调用将触发有关现有函数重新声明的错误。
您可能还会看到PHP内置函数。尝试在the official manual中搜索该函数,并检查它所属的“扩展”(PHP模块),以及哪些版本的PHP支持它。
如果缺少扩展名,请安装该扩展程序并在php.ini中启用它。请参阅PHP手册中的安装说明,了解您的功能所在的扩展程序。您也可以使用软件包管理器启用或安装扩展程序(例如,在Debian或Ubuntu中apt
,yum
in红帽或CentOS),或共享托管环境中的控制面板。
如果在您使用的PHP的较新版本中引入了该功能,您可以在手册或其注释部分找到替代实现的链接。如果它已从PHP中删除,请查找有关原因的信息,因为它可能不再需要。
如果包含缺失,请确保在调用函数之前包含声明该函数的文件。
如果是拼写错误,请修正拼写错误。
相关问题:
答案 7 :(得分:70)
当你在意想不到的地方T_XXX
token,不平衡(多余)的括号,使用短标签而不在php.ini中激活它时,会发生这种情况。等等。
相关问题:
如需进一步帮助,请参阅:
答案 8 :(得分:67)
直接在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)
。
相关问题:
答案 9 :(得分:61)
此错误通常是由于您忘记正确转义传递给MySQL查询的数据而引起的。
不要做的事情的例子(“坏主意”):
$query = "UPDATE `posts` SET my_text='{$_POST['text']}' WHERE id={$_GET['id']}";
mysqli_query($db, $query);
此代码可以包含在包含要提交的表单的页面中,其中包含http://example.com/edit.php?id=10等网址(编辑10号帖子)
如果提交的文字包含单引号会怎样? $query
最终会:
$query = "UPDATE `posts` SET my_text='I'm a PHP newbie' WHERE id=10';
当这个查询被发送到MySQL时,它会抱怨语法错误,因为中间有一个额外的单引号。
为避免此类错误,必须始终在查询中使用之前转义数据。
在SQL查询中使用之前转义数据也非常重要,因为如果不这样做,您的脚本将对SQL注入开放。 SQL注入可能会导致记录,表或整个数据库的更改,丢失或修改。这是一个非常严重的安全问题!
文档:
答案 10 :(得分:51)
没有足够的内存来运行脚本。 PHP已达到内存限制并停止执行它。此错误是致命的,脚本停止。可以在php.ini
文件中或在脚本中使用ini_set('memory_limit', '128 M');
(将覆盖php.ini
中定义的值)配置memory limit的值。内存限制的目的是防止单个PHP脚本吞噬所有可用内存并使整个Web服务器关闭。
要做的第一件事是尽量减少脚本所需的内存量。例如,如果您正在将大文件读入变量或从数据库中获取许多记录并将它们全部存储在数组中,则可能会占用大量内存。将代码更改为逐行读取文件或一次获取一个数据库记录,而不将它们全部存储在内存中。这需要对幕后发生的事情以及数据存储在内存与其他地方的情况有一点概念上的认识。
如果在脚本没有执行内存密集型工作时发生此错误,则需要检查代码以查看是否存在内存泄漏。 memory_get_usage
功能是你的朋友。
相关问题:
答案 11 :(得分:50)
当整个复杂变量构造未包含在{}
中时,当尝试使用引用键引用数组值以在双引号字符串内插值时,通常会遇到此错误
这将导致Unexpected T_ENCAPSED_AND_WHITESPACE
:
echo "This is a double-quoted string with a quoted array key in $array['key']";
//---------------------------------------------------------------------^^^^^
在双引号字符串中,PHP将允许使用 unquoted 来使用数组键字符串,并且不会发出E_NOTICE
。所以上面的内容可以写成:
echo "This is a double-quoted string with an un-quoted array key in $array[key]";
//------------------------------------------------------------------------^^^^^
整个复杂数组变量和键可以包含在{}
中,在这种情况下,应引用以避免E_NOTICE
。 The PHP documentation建议使用复杂变量的语法。
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.";
//----------------------------------------------------------^^^^^^^^^^^^^^^^^^^^^
供参考,请参阅the PHP Strings manual page
中变量解析部分答案 12 :(得分:42)
当您通常通过include
,require
或fopen
调用文件时,会发生这种情况,并且PHP无法找到该文件或者没有足够的权限来加载该文件。
这可能由于各种原因而发生:
一个常见错误是不使用绝对路径。这可以通过使用完整路径或__DIR__
dirname(__FILE__)
或include __DIR__ . '/inc/globals.inc.php';
来轻松解决:
require dirname(__FILE__) . '/inc/globals.inc.php';
或:
{{1}}
确保使用正确的路径是解决这些问题的一个步骤,这也可能与不存在的文件,文件系统的权限阻止访问或PHP本身的开放基础限制有关。
快速解决此问题的最佳方法是按照下面的故障排除检查清单进行操作。
相关问题:
相关错误:
答案 13 :(得分:41)
范围解析算子也被称为希伯来语פעמייםנקודתיים的“Paamayim Nekudotayim”。这意味着“双冒号”或“双点”两次。
如果您无意中将::
放入代码中,则通常会发生此错误。
相关问题:
文档:
答案 14 :(得分:40)
这意味着您要么两次使用相同的函数/类名,需要重命名其中一个,要么是因为您使用了require
或include
应该使用require_once
或include_once
1}}或<?php
class MyClass
{
public function doSomething()
{
// do stuff here
}
}
。
当在PHP中声明类或函数时,它是不可变的,以后不能用新值声明。
请考虑以下代码:
class.php
<?php
function do_stuff()
{
require 'class.php';
$obj = new MyClass;
$obj->doSomething();
}
do_stuff();
do_stuff();
的index.php
do_stuff()
对require
的第二次调用将产生上述错误。通过将require_once
更改为MyClass
,我们可以确定包含{{1}}定义的文件只会加载一次,并且可以避免错误。
答案 15 :(得分:40)
或者,在PHP 7.2或更高版本中:
当在代码中使用令牌并且看起来是常量时会发生此通知,但未定义该名称的常量。
此通知的最常见原因之一是未能引用用作关联数组键的字符串。
例如:
// Wrong
echo $array[key];
// Right
echo $array['key'];
另一个常见原因是变量名称前面缺少$
(美元)符号:
// Wrong
echo varName;
// Right
echo $varName;
或许您拼错了其他一些常量或关键字:
// Wrong
$foo = fasle;
// Right
$foo = false;
当您尝试访问该库定义的常量时,它也可能表示缺少所需的PHP扩展或库。
相关问题:
答案 16 :(得分:36)
当您尝试使用之前未定义的变量时会发生。
典型的例子是
foreach ($items as $item) {
// do something with item
$counter++;
}
如果您之前未定义$counter
,则上述代码将触发通知。
正确的方法是在使用它之前设置变量,即使它只是一个空字符串,如
$counter = 0;
foreach ($items as $item) {
// do something with item
$counter++;
}
此错误意味着大致相同的事情,但指的是对象的属性。重用上面的示例,此代码将触发错误,因为尚未设置counter
属性。
$obj = new stdclass;
$obj->property = 2342;
foreach ($items as $item) {
// do something with item
$obj->counter++;
}
相关问题:
答案 17 :(得分:32)
可能的情况
我似乎无法找到我的代码出错的地方。这是我的完整错误:
解析错误:语法错误,第x行意外的T_VARIABLE
我在尝试什么
$sql = 'SELECT * FROM dealer WHERE id="'$id.'"';
答案
解析错误:程序语法存在问题,例如在分支语句结尾处留下分号,或者像上面的情况一样,错过了.
运算符。解释器在遇到解析错误时停止运行程序。
简单来说,这是一个语法错误,这意味着代码中有一些东西会阻止它被正确解析并因此运行。
你应该做什么仔细检查错误所在的行是否有任何简单的错误。
该错误消息意味着在文件的第x行,PHP解释器期望看到一个打开的括号,但它遇到了一个名为T_VARIABLE
的东西。 T_VARIABLE
事件被称为token
。它是PHP解释器表达程序不同基本部分的方式。当解释程序读入程序时,它会将您编写的内容转换为令牌列表。无论你在程序中放置一个变量,解释器列表中都有一个T_VARIABLE
标记。
Good read: List of Parser Tokens
因此,请务必在E_PARSE
中至少启用php.ini
。生产脚本中不应存在解析错误。
我总是建议在编码时添加以下语句:
error_reporting(E_ALL);
另外,最好使用一个IDE,让您在键入时知道解析错误。您可以使用:
答案 18 :(得分:32)
*
如名称所示,当您最有可能尝试迭代或从具有不存在键的数组中查找值时,会发生此类错误。
考虑一下,正试图展示$string
$string = 'ABCD';
for ($i=0, $len = strlen($string); $i <= $len; $i++){
echo "$string[$i] \n";
}
以上示例将生成(online demo):
A
B
C
D
Notice: Uninitialized string offset: 4 in XXX on line X
并且,一旦脚本完成回显D
,您将收到错误,因为在for()
循环内,您已告诉PHP向您显示来自{的第一个到第五个字符串字符{1}}存在,但是由于循环从'ABCD'
开始计数并且在到达0
时回显D
,它将抛出偏移错误。
类似错误:
答案 19 :(得分:28)
此错误有两种变化:
$arr = [1, 2, 3];
此数组初始化程序语法仅在PHP 5.4中引入;它会在之前的版本上引发解析器错误。如果可能,请升级安装或使用旧语法:
$arr = array(1, 2, 3);
另请参阅手册中的this example。
$suffix = explode(',', 'foo,bar')[1];
PHP 5.4中还引入了数组解除引用功能结果。如果无法升级,则需要使用(临时)变量:
$parts = explode(',', 'foo,bar');
$suffix = $parts[1];
另请参阅手册中的this example。
答案 20 :(得分:28)
当您尝试在没有对象时访问对象的属性时发生。
非对象通知的典型示例是
$users = json_decode('[{"name": "hakre"}]');
echo $users->name; # Notice: Trying to get property of non-object
在这种情况下,$users
是一个数组(因此不是对象),它没有任何属性。
这类似于访问数组的不存在的索引或键(请参阅Notice: Undefined Index)。
这个例子很简单。大多数情况下,这种通知表示未经检查的返回值,例如,当一个库返回NULL
时,如果一个对象不存在或只是一个意外的非对象值(例如在Xpath结果,具有意外格式的JSON结构,具有意外格式的XML等)但代码不检查这样的条件。
由于这些非对象经常被进一步处理,因此通常在非对象上调用对象方法时会发生致命错误(请参阅:Fatal error: Call to a member function ... on a non-object)暂停脚本。
通过检查错误条件和/或变量是否符合预期,可以很容易地防止这种情况。这是一个带有 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;
相关错误:
答案 21 :(得分:28)
此警告可以显示与文件和目录访问相关的各种功能。它警告配置问题。
当它出现时,表示禁止访问某些文件。
警告本身不会破坏任何内容,但如果阻止文件访问,大多数情况下脚本都无法正常工作。
此修复通常会更改PHP configuration,相关设置称为open_basedir
。
有时使用错误的文件或目录名称,然后修复使用正确的文件或目录名称。
相关问题:
答案 22 :(得分:23)
(Warning: mysql_fetch_array() expects parameter 1 to be resource, boolean given的更一般变体)
PHP中的资源是type(如字符串,整数或对象)。资源是一个不透明的blob,它本身没有固有的有意义的值。资源特定于某些PHP函数或扩展,并由其定义。例如,Mysql扩展名defines two resource types:
MySQL模块中使用了两种资源类型。第一个是数据库连接的链接标识符,第二个是保存查询结果的资源。
cURL扩展程序定义了另一个two resource types:
......一个cURL句柄和一个cURL多句柄。
var_dump
时,值如下所示:
$resource = curl_init();
var_dump($resource);
resource(1) of type (curl)
所有大多数资源都是某种类型的数字标识符((1)
)((curl)
)。
您携带这些资源并将其传递给不同的功能,而这些资源意味着什么。通常,这些函数在后台分配某些数据,而资源只是一个用于在内部跟踪这些数据的参考。
“ ...期望参数1为资源,布尔给定”错误通常是应该创建资源的未经检查操作的结果,但返回false
而不是。例如,fopen
function有这样的描述:
返回值
成功时返回文件指针资源,或者出错时返回
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);
相关错误:
答案 23 :(得分:21)
当您尝试使用方括号语法访问数组元素时会发生这种情况,但是您在字符串上执行此操作,而不是在数组上执行此操作,因此操作显然没有意义
示例:
$var = "test";
echo $var["a_key"];
如果您认为变量应该是一个数组,请查看它的来源并解决问题。
答案 24 :(得分:19)
如果您没有看到PHP代码的结果和/或您在网页中看到部分文字PHP源代码输出,那么您可以非常确定您的PHP实际上并未执行。如果您在浏览器中使用View Source,您可能会看到整个PHP源代码文件。由于PHP代码嵌入在<?php ?>
标记中,浏览器会尝试将这些代码解释为HTML标记,结果可能看起来有些混乱。
要实际运行PHP脚本,您需要:
*除非您重新配置,否则可以配置所有内容。
最后一个特别重要。只需双击该文件,就可以使用以下地址在浏览器中打开它:
file://C:/path/to/my/file.php
这完全绕过了您可能已运行的任何Web服务器,并且文件未被解释。您需要访问Web服务器上的文件的URL,可能是:
http://localhost/my/file.php
您可能还想检查是否使用短开标记<?
而不是<?php
,并且您的PHP配置已关闭短开标记。
另见PHP code is not being executed, instead code shows on the page
答案 25 :(得分:16)
如果您尝试将数组视为字符串,则会发生这种情况:
$arr = array('foo', 'bar');
echo $arr; // Notice: Array to string conversion
$str = 'Something, ' . $arr; // Notice: Array to string conversion
数组不能简单地为echo
或与字符串连接,因为结果没有很好地定义。 PHP将使用字符串&#34; Array&#34;代替数组,并触发通知指出,这可能不是预期的,你应该在这里检查你的代码。你可能想要这样的东西:
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
}
如果此通知出现在您不希望的某个地方,则表示您认为是字符串的变量实际上是一个数组。这意味着你的代码中有一个错误,它使这个变量成为一个数组而不是你期望的字符串。
答案 26 :(得分:12)
警告消息“除以零”是新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
}
相关问题:
答案 27 :(得分:8)
当您尝试在类上调用非静态方法时会发生这种情况,因为它是静态的,并且您的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及更高版本,E_STRICT
[ref]中包含E_ALL
。但那是不可取的。解决方案是将您想要的静态函数定义为实际的static
:
public static function br() {
echo '<br>';
}
或按惯例调用该函数:
$html = new HTML();
$html->br();
相关问题:
答案 28 :(得分:4)
当一个类尝试use
multiple Traits,其中两个或多个特征具有相同名称的defined a property且属性具有不同的初始值时发生。
示例:
<?php
trait TraitA
{
public $x = 'a';
}
trait TraitB
{
public $x = 'b';
}
class ClassC
{
use TraitA, TraitB;
}
有问题:虽然可以解决competing methods之间的冲突,但目前没有语法可以解决两个竞争属性之间的冲突。目前唯一的解决方案是refactor;即,避免产生致命错误的属性名称之间的冲突。
相关问题:
答案 29 :(得分:4)
HTTP状态代码500和典型的Apache或浏览器警告是非常广泛的消息。这不是实际的错误。要弄清这是Web服务器配置错误(.htaccess
还是PHP致命错误,您必须查看 error.log
。
通常可以在以下位置找到网络服务器error.log
:
/var/log/apache2
在Linux服务器上,通常用于本地和虚拟主机。/var/www/_user12345_/logs
或类似的共享主机计划。logs/
文件夹旁边都有一个htdocs/
目录。C:\xampp\apache\logs\error.log
用于Apache + PHP的WAMP / XAMPP发行版。httpd.conf
及其ErrorLog
指令。/var/log/nginx/nginx_error.log
for NGINX。C:\inetpub\logs\LogFiles
for IIS。这是一个文本文件。搜索与错误时间最接近的条目,并使用错误消息的重要部分(从“ PHP错误:…”到“在线…”)进行进一步的谷歌搜索。
[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's error.log。通常,保留默认值更简单,只需启用error_display
+ error_reporting
即可显示具体错误。毕竟,HTTP 500全包页面只是PHP's white screen of death的一种变体。
另请参阅:
答案 30 :(得分:3)
这意味着您没有执行匿名功能(或闭包)。
使用箭头函数在此示例中将引发错误:
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,它的名称为added in PHP 7。
答案 31 :(得分:2)
如果将错误类型的参数传递给函数-并且PHP无法自动将其转换-将引发警告。此警告标识出问题所在的参数以及期望的数据类型。解决方法:将指示的参数更改为正确的数据类型。
例如此代码:
echo substr(["foo"], 23);
输出结果:
PHP警告:substr()期望参数1为字符串,给定数组
答案 32 :(得分:2)
在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 for this change链接到一个PHP script,该PHP试图机械地修复它。
答案 33 :(得分:1)
警告:count():参数必须是在...中实现Countable的数组或对象。
不言自明;传递给count()
函数的参数必须是可数的,通常是数组。
可能的问题是传递了标量值(例如字符串或整数),或者传递了未实现Countable
接口的对象。在有问题的变量上使用var_dump()
可以显示情况是否如此。
答案 34 :(得分:1)
此错误自行解释。您的代码尝试调用 some_function()
并将错误类型的数据作为参数之一传递。例如:
<?php declare(strict_types=1);
function multiply(int $x, int $y) { return $x * $y; }
echo multiply("3", 4);
因为被调用函数的第一个参数是 int
标量类型,并且调用是在一个启用了严格类型(stict_types=1
)的文件中,所以它在传递 {{1 }}到它:
致命错误:未捕获的类型错误:multiply():参数 #1 ($x) 必须是整数类型,字符串在...中给出