参考-此错误在PHP中意味着什么?


1137

这是什么?

这是有关警告,错误和注意事项的许多答案,这些警告,错误和注意事项在您对PHP进行编程时可能会遇到,并且不知道如何解决它们。这也是一个社区Wiki,因此邀请所有人参与添加并维护此列表。

为什么是这样?

诸如“已发送标题”“呼叫非对象成员”之类的问题经常在堆栈溢出中弹出。这些问题的根本原因总是相同的。因此,这些问题的答案通常会重复它们,然后向OP显示在特定情况下要更改的行。这些答案不会为网站增加任何价值,因为它们仅适用于OP的特定代码。具有相同错误的其他用户无法轻松地从中读取解决方案,因为他们过于本地化。令人遗憾的是,一旦您了解了根本原因,就可以轻松地修复错误。因此,该列表试图以一种通用的方式来解释该解决方案。

我应该在这里做什么?

如果您的问题已被标记为与此问题的重复,请在下面找到您的错误消息,并将修复程序应用于您的代码。答案通常包含进一步的链接,以进行调查,以免仅凭一般答案无法明确答案。

如果您想做出贡献,请添加“最喜欢的”错误消息,警告或通知,每个答案一个,简短说明其含义(即使只是在其手册页上突出显示术语),可能的解决方案或调试方法以及现有有价值的问答列表。此外,请随时改善任何现有答案。

名单

另请参阅:


7
另外,
要使



Answers:


275

警告:无法修改标头信息-标头已发送

当脚本尝试将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时。

相关问题:


2
如果您使用的是WordPress,请检查主题文件。当我将网站升级到新版本的WordPress时,由于主题几年未更新,因此无法更新主题。这个问题出现了。原来functions.php文件有多个<??>块之间有空格。
罗伊·勒班

2
@RoyLeban“如果您的文件中包含多个块...”,我不确定这意味着什么。什么是“块”?一个块会由组成,<?php ?>那么“多个块”将是<?php ?> <?php ?>
安德鲁·福克斯

2
如果可能的话,请打开PHP.ini配置文件中的``输出缓冲''功能,用于解决此问题。它将html文件发送到输出缓冲区中,并仅在脚本停止后才发送给客户端,因此如果两个标头在不同位置发出,然后旧标头将被替换为新标头。
Nidhin David

191

致命错误:在非对象上调用成员函数...

发生的代码类似于xyz->method()where 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();

通过尝试在条件块之外执行该方法,可能未定义您的对象。

相关问题:


115

一无所获。页面为空白。

也称为死亡白页死亡白屏。当错误报告关闭并且发生致命错误(通常是语法错误)时,会发生这种情况。

如果启用了错误日志记录,则将在错误日志中找到具体的错误消息。它通常位于中央位置(例如,/var/log/apache2在许多Linux环境中)或脚本本身的目录(有时在共享主机环境中使用)中的“ php_errors.log”文件中。

有时暂时启用错误显示可能会更直接。然后,白页将显示错误消息。请小心,因为这些错误对于访问该网站的每个人都是可见的。

通过在脚本顶部添加以下PHP代码,可以轻松完成此操作:

ini_set('display_errors', 1); error_reporting(~0);

该代码将打开错误显示,并将报告设置为最高级别。

由于ini_set()在运行时执行,因此对解析/语法错误没有影响。这些错误将出现在日志中。如果还要在输出中显示它们(例如在浏览器中),则必须将display_startup_errors指令设置为true。可以使用,php.ini.htaccess或通过任何其他会影响运行时之前的配置的方法来执行此操作。

您可以使用相同的方法来设置log_errorserror_log伪指令以选择自己的日志文件位置。

在日志中查看或使用显示,您将获得更好的错误消息以及中止脚本的代码行。

相关问题:

相关错误:


3
error_reporting(~0);为什么不-1呢?这就是~0评估的结果,而且不那么神秘。
法布里西奥磨砂

3
我认为两者都是类似的隐秘的。~0IMO更明确:取消空位集,即启用所有标志。-1并不意味着像C中的strpos()那样代表“未找到”,而是代表设置了所有标志的位集,因为-1是二进制的1111'1111'1111'1111(用于32位)。
2013年

2
糟糕,1111'1111'1111'1111确实是16位,但我希望您理解我的意思。
2013年

3
@IvanSolntsev,对不起,对于5.4之前的版本E_STRICT未包含在中E_ALLphp.net/manual/en/errorfunc.constants.php并向下滚动到E_STRICT
2014年

102

注意:未定义的索引

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

Undefined Index通知的典型示例是(demo

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

双方spinach1在阵列中不存在,造成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

相关问题:


我倾向于使用if(!empty($_POST['message'])){ //do stuff }
kurdtpage

85

警告:mysql_fetch_array()期望参数1为资源,给定布尔值

首先,最重要的是:

请不要mysql_*在新代码中使用函数。它们不再维护,已正式弃用。看到红色框了吗?了解准备的语句来代替,并使用 PDO库MySQLi -本文将帮助你决定哪些。如果您选择PDO,这是一个很好的教程


当您尝试从的结果中获取数据mysql_query但查询失败时,就会发生这种情况。

这是一个警告,不会停止脚本,但是会使您的程序出错。

您需要检查返回的结果mysql_query通过

$res = mysql_query($sql);
if (!$res) {
   die(mysql_error());
}
// after checking, do the fetch

相关问题:

相关错误:

mysql*由于同样的原因,其他也希望将MySQL结果资源用作参数的函数将产生相同的错误。


5
请注意。如果mysql_query还不够糟糕的话,or die在此基础上加重就是对伤害的侮辱。
马达拉的鬼魂

我遇到的问题是,$res = mysql_query($query)如果查询成功,则返回1,因此认为它是正确的。因此通过的结果时 mysql_query ,以 mysql_fetch_array() 该公告显示。
mboy

@mboy对于SELECT,SHOW,DESCRIBE,EXPLAIN和其他返回结果集的语句,mysql_query()成功时返回资源,错误时返回FALSE。对于其他类型的SQL语句,例如INSERT,UPDATE,DELETE,DROP等,mysql_query()成功返回TRUE,错误返回FALSE。
xdazz16年

@xdazz这是我面临的问题,插入更新返回TRUE,所以我无法摆脱此错误,mysql_fetch_array() expects parameter 1 to be resource, boolean given in select 请参阅-gist.github.com/romelemperado/93af4cdbd44ebf3a07cbfa0e3fc539d7 关于git摆脱此错误的任何建议吗?
mboy

2
@mboy mysql_fetch_array()用于选择查询,用于插入和更新,您不需要获取结果集(也没有可以获取的结果集)。
xdazz16年

79

致命错误:不在对象上下文中时使用$ this

$this是PHP中无法分配的特殊变量。如果在不存在的上下文中访问它,则会出现此致命错误。

可能会发生此错误:

  1. 如果非静态方法是静态调用的。例:

    class Foo {
       protected $var;
       public function __construct($var) {
           $this->var = $var;
       }
    
       public static function bar () {
           // ^^^^^^
           echo $this->var;
           //   ^^^^^
       }
    }
    
    Foo::bar();

    如何解决:如何再次检查代码,$this只能在对象上下文中使用,决不能在静态方法中使用。同样,静态方法不应访问非静态属性。使用self::$static_property访问静态属性。

  2. 如果来自类方法的代码已复制到普通函数或仅复制到全局范围保留$this特殊变量。
    如何解决:查看代码并$this用其他替换变量替换。

相关问题:

  1. 调用非静态方法作为静态方法:PHP致命错误:不在对象上下文中时使用$ this
  2. 复制代码:致命错误:不在对象上下文中时使用$ this
  3. 所有“不在对象上下文中时使用$ this”的问题

2
您可能还想提到带闭包的工作原理(即使在非静态方法中)以及它在5.4中的“固定”方式。
肯德尔·霍普金斯

2
@hakre我在说闭包内部的静态调用。像$closure = function() { self::method(); }
肯德尔·霍普金斯

2
@KendallHopkins:这是一个不同的错误:“致命错误:当没有类作用域处于活动状态时,无法访问self ::”但是$this您可以触发“致命错误:不在对象上下文中时使用$ this”$closure = function() { $this->method(); };
hakre

75

致命错误:调用未定义函数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

在这种情况下,fn只有在createFn()被调用时才会声明。请注意,随后对的调用createFn()将触发有关重新声明现有功能的错误。

您可能还会在PHP内置函数中看到此信息。尝试在官方手册中搜索该功能,并检查其所属的“扩展”(PHP模块)以及哪些版本的PHP支持该功能。

如果缺少扩展名,请安装该扩展名并在php.ini中启用它。请参阅PHP手册中的安装说明以获取功能所在的扩展名。您还可以使用软件包管理器(例如,apt在Debian或Ubuntu,yumRed Hat或CentOS中)或控制面板启用或安装扩展名。在共享托管环境中。

如果该功能是从所使用的PHP的较新版本中引入的,则可以在手册或其注释部分中找到替代实现的链接。如果已将其从PHP中删除,请查找有关原因的信息,因为可能不再需要它。

如果缺少包含,请在调用函数之前确保包含声明函数的文件。

如果出现错别字,请修正错字。

相关问题:


73

解析错误:语法错误,意外的T_XXX

当您将T_XXX令牌放置在意外的位置,不平衡的(多余的)括号,在php.ini中使用短标签而不激活它的情况下,就会发生这种情况。

相关问题:

有关更多帮助,请参见:


70

致命错误:无法在写入上下文中使用函数返回值

直接在中使用函数时,通常会发生这种情况empty

例:

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

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

empty,尽管有其名称,但实际上不会检查变量是否为“空”。相反,它检查变量是否不存在,或者== false。表达式(如is_null(null)示例中一样)将始终被视为存在,因此这里empty仅检查其是否等于false。您可以empty()在此处用替换!,例如if (!is_null(null)),或将显式比较为,例如if (is_null(null) == false)

相关问题:


64

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注入可能会导致记录,表或整个数据库的更改,丢失或修改。这是一个非常严重的安全问题!

说明文件:


3
此外,如果您不这样做,您的网站将自动被漫游器入侵
apscience 2012年

2
@gladoscc单击“编辑”并修改答案。我知道可以改善。
乔斯林

2
或使用准备好的sql查询。
2013年

53

致命错误:耗尽了XXX字节的允许的内存大小(尝试分配XXX字节)

没有足够的内存来运行您的脚本。PHP已达到内存限制并停止执行。此错误是致命的,脚本停止。所述的值存储限制可以在被配置php.ini文件,或通过使用ini_set('memory_limit', '128 M');在脚本中(其将覆盖在所定义的值php.ini)。内存限制的目的是防止单个PHP脚本吞噬所有可用内存并使整个Web服务器停机。

首先要做的是最小化脚本所需的内存量。例如,如果您正在将一个大文件读入一个变量,或者正在从数据库中获取许多记录并将它们全部存储在一个数组中,那么这可能会占用大量内存。更改代码以代替逐行读取文件或一次获取一个数据库记录而不将其全部存储在内存中。这确实需要对幕后发生的事情以及何时将数据存储在内存中或其他地方进行概念上的了解。

如果在脚本不执行占用大量内存的工作时发生此错误,则需要检查代码以查看是否存在内存泄漏。该memory_get_usage功能是您的朋友。

相关问题:


53

解析错误:语法错误,意外的T_ENCAPSED_AND_WHITESPACE

当未使用完整的复杂变量构造时,尝试使用带引号的键引用数组值以在双引号字符串内进行插值时,最常遇到此错误{}

错误情况:

这将导致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]";
//------------------------------------------------------------------------^^^^^

可以将整个复杂数组变量和键包含在内{},在这种情况下,使用引号将它们引起来,以避免出现E_NOTICEPHP文档针对复杂变量建议使用此语法。

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手册


45

警告:[功能]:无法打开流:[原因]

当您通常通过调用文件时includerequire或者fopenPHP找不到文件或没有足够的权限加载文件时,就会发生这种情况。

发生这种情况可能有多种原因:

  • 文件路径错误
  • 文件路径是相对的
  • 包含路径错误
  • 权限限制太严格
  • SELinux生效
  • 还有很多 ...

一个常见的错误是不使用绝对路径。这可以通过使用完整路径或魔术常数(例如__DIR__或) 轻松解决dirname(__FILE__)

include __DIR__ . '/inc/globals.inc.php';

要么:

require dirname(__FILE__) . '/inc/globals.inc.php';

确保使用正确的路径是解决这些问题的第一步,这还可能与不存在的文件,文件系统的权限阻止PHP本身进行访问或基于openir的限制有关。

快速解决此问题的最佳方法是遵循下面的故障排除清单。

相关问题:

相关错误:


44

解析错误:语法错误,意外T_PAAMAYIM_NEKUDOTAYIM

示波器解析算子也被称为“ Paamayim Nekudotayim”,来自希伯来语פעמייםנקודתיים。意思是“双冒号”。

如果您无意中::输入了代码,通常会发生此错误。

相关问题:

说明文件:


触发此错误的最简单方法是运行a()::b;$a=::;
伊斯梅尔·米格尔

43

注意:使用未定义常数XXX-假定为“ XXX”

或者,在PHP 7.2或更高版本中:

警告:使用未定义的常数XXX-假定为“ XXX”(这将在以后的PHP版本中引发错误)

当在代码中使用令牌并且看上去是一个常量,但未定义该名称的常量时,会出现此通知。

此通知的最常见原因之一是无法引用用作关联数组键的字符串。

例如:

// Wrong
echo $array[key];

// Right
echo $array['key'];

另一个常见原因是缺少 $变量名前面(美元)符号:

// Wrong
echo varName;

// Right
echo $varName;

也许您拼错了一些其他常量或关键字:

// Wrong
$foo = fasle;

// Right
$foo = false;

当您尝试访问该库定义的常量时,这也可能表明缺少所需的PHP扩展或库。

相关问题:


2
我会说最常见的原因是在变量而不是数组前面忘记了$。
2012年

42

致命错误:无法重新声明类[类名]

致命错误:无法重新声明 [函数名称]

这意味着您或者两次使用相同的函数/类名,并且需要重命名其中之一,或者是因为您已经使用过,require或者include应该在哪里使用require_onceinclude_once

当用PHP声明一个类或函数时,它是不可变的,以后不能用新值声明。

考虑以下代码:

class.php

<?php

class MyClass
{
    public function doSomething()
    {
        // do stuff here
    }
}

index.php

<?php

function do_stuff()
{
   require 'class.php';
   $obj = new MyClass;
   $obj->doSomething();
}

do_stuff();
do_stuff();

第二次调用do_stuff()将产生上面的错误。通过更改requirerequire_once,我们可以确定包含的定义的文件MyClass将仅加载一次,并且可以避免该错误。


3
值得一提的是,使用自动加载功能时,例如PSR-4甚至现在已弃用的PSR-0等标准都通过节省您自己使用require / include的需求(很多奇怪的情况)而摆脱了这一问题。
DanielM

39

注意:未定义的变量

当您尝试使用以前未定义的变量时发生。

一个典型的例子是

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++;
}

相关问题:


35

解析错误:语法错误,意外的T_VARIABLE

可能的情况

我似乎找不到我的代码出错的地方。这是我的完整错误:

解析错误:语法错误,第x行上出现意外的T_VARIABLE

我在想什么

$sql = 'SELECT * FROM dealer WHERE id="'$id.'"';

回答

解析错误:程序语法上的问题,例如在语句末尾留下分号,或者像上面的情况一样,缺少.运算符。遇到解析错误时,解释器将停止运行您的程序。

简而言之,这是一个语法错误,这意味着您的代码中有某些内容阻止其正确解析,因此无法运行。

您应该做的是仔细检查错误周围的行是否有任何简单的错误。

该错误消息表示,在文件的第x行中,PHP解释器期望看到一个开放的括号,但实际上遇到了T_VARIABLE。那T_VARIABLE东西叫做token。这是PHP解释器表示程序的不同基本部分的方式。当解释器读入程序时,它将把您编写的内容转换为令牌列表。无论您在程序中的何处放置变量,T_VARIABLE解释器的列表中都会有一个标记。

读物:解析器令牌列表

因此,请确保至少E_PARSE在中启用了php.ini。生产脚本中不应存在解析错误。

我总是建议在编码时添加以下语句:

error_reporting(E_ALL);

PHP错误报告

另外,使用IDE也是一个好主意,它将使您在键入时知道解析错误。您可以使用:

  1. NetBeans(精美的免费软件)(我认为是最好的)
  2. PhpStorm(戈登叔叔喜欢这个:P,付费计划,包含专有和免费软件)
  3. Eclipse(美女与野兽,免费软件)

相关问题:


34

注意:未初始化的字符串偏移量: *

顾名思义,当您最有可能试图遍历或使用不存在的键从数组中查找值时,会发生此类错误。

考虑到您,我们正试图显示来自 $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

并且,一旦脚本完成回显,D您将得到错误,因为在for()循环内,您已告诉PHP向您显示'ABCD'存在的第一个至第五个字符串字符,但是由于循环从0并开始计数并回显D到到达时4,将引发偏移错误。

类似错误:


32

注意:试图获取非对象错误的属性

当您尝试在没有对象的情况下访问对象的属性时发生。

非对象通知的典型示例是

$users = json_decode('[{"name": "hakre"}]');
echo $users->name; # Notice: Trying to get property of non-object

在这种情况下, $users是一个数组(因此不是对象),它没有任何属性。

这类似于访问数组的不存在的索引或键(请参阅注意:未定义的索引))。

此示例已大大简化。通常,此类通知表示未检查的返回值,例如,当库返回时NULL如果对象不存在,或者仅仅是意外的非对象值(例如,在Xpath结果中,意外格式的JSON结构,意外格式的XML等)。但是代码不会检查这种情况。

由于通常会进一步处理这些非对象,因此,在非对象上调用对象方法时,通常会发生致命错误(请参阅:致命错误:在非对象上调用成员函数...)脚本。

通过检查错误条件和/或变量是否符合预期,可以轻松地防止这种情况发生。这是一个带有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;

相关错误:


1
json_decode现在stdclass默认情况下返回一个实例,因此示例代码实际运行。
Hugo Zink

@HugoZink:实际上确实(并且总是这样做)返回该示例的数组:3v4l.org/SUDe0-还可以请您提供json_decode现在返回stdclass默认情况下的实例”的书面参考吗?我在变更日志中找不到。
hakre

根据PHP手册上json_decode的页面,默认情况下,该assoc参数设置为false。此参数确定函数是否返回a stdclass而不是关联数组。
Hugo Zink

json_decode('[{"name": "hakre"}]', true)将返回一个数组,否则返回一个stdclass对象
zanderwar

29

警告:open_basedir限制生效

该警告可能会出现与文件和目录访问相关的各种功能。它警告有关配置问题。

当它出现时,表明已禁止某些文件的访问。

警告本身不会破坏任何内容,但是如果阻止了文件访问,则脚本通常无法正常工作。

解决方法通常是更改PHP配置,相关设置称为open_basedir

有时使用了错误的文件或目录名称,然后使用正确的名称进行修复。

相关问题:


1
这种情况经常发生,一个共享的主机上,人们通常不会自己锁定的目录:-)
uınbɐɥs

28

解析错误:语法错误,意外的'['

该错误来自两个变量:

变体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];

另请参见手册中的此示例


23

警告:[函数]期望参数1为资源,给定布尔值

警告的更一般的变化:mysql_fetch_array()期望参数1为资源,给定布尔值

资源是PHP 中的一种类型(例如字符串,整数或对象)。资源是一个不透明的斑点,本身没有固有的有意义的价值。资源特定于一组PHP函数或扩展,并由它们定义。例如,Mysql扩展定义了两种资源类型

MySQL模块中使用了两种资源类型。第一个是数据库连接的链接标识符,第二个是保存查询结果的资源。

cURL扩展定义了另外两种资源类型

...一个cURL句柄和一个cURL多句柄。

var_dump主编,值这个样子:

$resource = curl_init();
var_dump($resource);

resource(1) of type (curl)

多数资源就是(1)某种类型的数字标识符()((curl)))。

您可以随身携带这些资源,并将它们传递给不同的功能,对于这些功能,这意味着某些意义。通常,这些函数在后台分配某些数据,而资源只是一个引用,它们用于内部跟踪这些数据。


...期望参数1是资源,给定布尔值 ”错误通常是由于未经检查的操作的结果,该操作应该创建资源,但是返回了false。例如,该fopen函数具有以下描述:

返回值

成功或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);

相关错误:


22

警告:字符串偏移量“ XXX”非法

当您尝试使用方括号语法访问数组元素时会发生这种情况,但是您是在字符串而不是数组上执行此操作,因此该操作显然没有意义

例:

$var = "test";
echo $var["a_key"];

如果您认为该变量应该是数组,请查看其来源并在那里解决问题。


20

代码未运行/输出了我的PHP代码的一部分

如果您没有从PHP代码中看到任何结果,并且/或者在网页中看到了部分PHP原代码输出,则可以确定您的PHP实际上没有得到执行。如果在浏览器中使用“查看源代码”,则可能会直接看到整个PHP源代码文件。由于PHP代码已嵌入<?php ?>标记中的,因此浏览器将尝试将它们解释为HTML标记,并且结果可能看起来有些混乱。

要实际运行PHP脚本,您需要:

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

*除非重新配置,否则所有内容都可以配置。

最后这一点特别重要。只需双击该文件,很可能会使用以下地址在浏览器中将其打开:

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

这完全绕开了您可能正在运行的任何Web服务器,并且文件没有得到解释。您需要访问Web服务器上文件的URL,可能类似于:

http://localhost/my/file.php

您可能还需要检查是否正在使用短开放标签 <?<?php而您的PHP配置已关闭短标记。

另请参见未执行PHP代码,而是页面上显示了代码


18

警告:mysql_connect():用户'name'@'host'的访问被拒绝

当您使用无效或缺少凭据(用户名/密码)连接到MySQL / MariaDB服务器时,将显示此警告。因此,这通常不是代码问题,而是服务器配置问题。

  • 有关mysql_connect("localhost", "user", "pw")示例,请参见手册页。

  • 检查您是否实际使用$username$password

    • 不使用密码就无法访问的情况很少见,这是在警告:提示时发生的情况(using password: NO)
    • 通常只有本地测试服务器允许使用username root,no password和test数据库名称进行连接。

    • 您可以使用命令行客户端测试它们是否正确
      mysql --user="username" --password="password" testdb

    • 用户名和密码区分大小写,并且不会忽略空格。如果您的密码包含元字符,例如$,请转义它们,或将密码放在单引号中

    • 大多数共享主机提供商预先声明与UNIX用户帐户有关的mysql帐户(有时只是前缀或额外的数字后缀)。有关格式或文档,请参阅文档,以及CPanel或用于设置密码的任何界面。

    • 请参阅有关使用命令行添加用户帐户的MySQL手册。以管理员用户身份连接时,您可以发出如下查询:
      CREATE USER 'username'@'localhost' IDENTIFIED BY 'newpassword';

    • 或使用AdminerWorkBench或任何其他图形工具来创建,检查或更正帐户详细信息。

    • 如果您不能修改您的凭据,那么要求互联网“请帮助”将无效。只有您和您的主机提供商才具有诊断和解决问题的权限和足够的访问权限。

  • 使用提供商提供的主机名验证您是否可以访问数据库服务器:
    ping dbserver.hoster.example.net

    • 直接从您的Web服务器上的SSH控制台中进行检查。从本地开发客户端到共享托管服务器的测试几乎没有意义。

    • 通常,您只希望服务器名称为"localhost",通常在可用时使用本地命名的套接字。有时您可以尝试"127.0.0.1"作为备用。

    • 如果您的MySQL / MariaDB服务器侦听其他端口,请使用"servername:3306"

    • 如果失败,则可能是防火墙问题。(离题,不是编程问题。无法提供远程猜测帮助。)

  • 使用诸如或的常数时,检查它们是否确实定义了DB_USERDB_PASSWORD

    • 如果得到a "Warning: Access defined for 'DB_USER'@'host'"和a "Notice: use of undefined constant 'DB_PASS'",那就是您的问题。

    • 验证您的eg xy/db-config.php是否确实包含在内。

  • 检查是否正确设置了GRANT权限

    • 仅有username+ password对是不够的。

    • 每个MySQL / MariaDB帐户可以具有一组权限。

    • 这些限制可以限制您允许连接到哪些数据库,该连接可能来自哪个客户端/服务器以及允许哪些查询。

    • 因此mysql_query,如果您无权访问SELECT特定表或INSERT/ UPDATE(更常见的是DELETE任何内容),则可能还会显示“拒绝访问”警告。

    • 当每个命令行客户端使用admin帐户和以下查询进行连接时,您可以调整帐户权限
      GRANT ALL ON yourdb.* TO 'username'@'localhost';

  • 如果首先显示警告,Warning: mysql_query(): Access denied for user ''@'localhost'则您可能具有php.ini预配置的帐户/密码对

    • 检查mysql.default_user=mysql.default_password=具有有意义的值。

    • 通常,这是提供者配置。因此,请联系他们的支持以获取不匹配信息。

  • 查找共享主机提供商的文档:

  • 请注意,您可能还耗尽了可用的连接池。对于过多的并发连接,您将收到拒绝访问警告。(您必须调查设置。这是一个脱机服务器配置问题,而不是编程问题。)

  • 您的libmysql客户端版本可能与数据库服务器不兼容。通常,可以使用在驱动程序中编译的PHP来访问MySQL和MariaDB服务器。如果您有一个自定义安装程序,一个过时的PHP版本,一个较新的数据库服务器或一台明显过时的数据库服务器,则版本不匹配可能会阻止连接。(不,您必须进行调查。没人能猜出您的设置)。

更多参考:

顺便说一句,您可能不再想要使用mysql_*函数了。新手经常迁移到mysqli,但是这同样乏味。相反,请阅读PDO和准备好的语句
$db = new PDO("mysql:host=localhost;dbname=testdb", "username", "password");


2
mysql允许通过php-ini设置自动连接,然后给相同的错误消息加上不同的命令前缀,例如“警告:mysql_query():拒绝用户” @'localhost”(使用密码:NO)的访问。 ..” -只是注意。
hakre 2015年

哈,完全忘记了!(可能最后一次使用PHP3左右。)
mario

18

注意:数组到字符串的转换

如果您尝试将数组视为字符串,则只会发生这种情况:

$arr = array('foo', 'bar');

echo $arr;  // Notice: Array to string conversion
$str = 'Something, ' . $arr;  // Notice: Array to string conversion

数组不能简单地由echo'd或与字符串连接,因为结果定义不明确。PHP将使用字符串“ Array”代替数组,并触发通知以指出这可能不是预期的,您应该在此处检查代码。您可能想要这样的东西:

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
}

如果此通知出现在您不希望看到的地方,则意味着您认为是字符串的变量实际上是数组。这意味着您的代码中存在一个错误,该错误使此变量成为数组而不是您期望的字符串。


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
}

相关问题:


如果将其设置为0,则将其设置为1将会停止错误,但这真的比您所说的不应该使用的抑制效果更好(我同意)吗?我建议大多数时候可能会返回其他消息或值。
James James

在此示例中,如果$var1== 0,则可以设置$var3$var2。即使不这样做,也根本不需要其他,因为两种情况下的分配都是相同的,因此无需分配,而是在if
James

8

严格标准:不应静态调用非静态方法[<class> :: <method>]

当您尝试在类上调用非静态方法(因为它是静态的)时发生,并且您E_STRICTerror_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包含在E_ALL[ ref ]中。但这是不可取的。解决方案是将所需的静态函数定义为实际的static

public static function br() {
  echo '<br>';
}

或按常规调用该函数:

$html = new HTML();
$html->br();

相关问题:


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 脚本,该脚本试图机械地解决此问题。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.