【问题标题】:Spurious PHP undeclared static property虚假的 PHP 未声明的静态属性
【发布时间】:2011-10-22 12:51:26
【问题描述】:

使用 PHP 5.3.x 运行 Debian Squeeze 服务器(Apache 和 nginx 都会发生)我看到随机出现的致命错误 undeclared static property。这通常指的是以下代码:

class aliro extends aliroBase {
        private static $instance = null;

        public static function getInstance () {
            return self::$instance instanceof self ? self::$instance : (self::$instance = new self());
        }
...

并声明aliro::$instance 在上面显示的最后一行未声明(不包括大括号)。然而,变量在前面几行就很清楚地声明了。 (确切的错误消息是“PHP 致命错误:访问未声明的静态属性:第 91 行 /var/www/apic/public_html/aliro.php 中的 aliro::$instance”)。

对于服务器的每个请求都会执行此代码,目前该服务器每小时运行大约 1,250 个请求。但错误似乎每小时发生一次。

同时,syslog 可能会显示 suhosin 错误消息:

Oct 22 11:29:45 apic suhosin[20764]: ALERT-SIMULATION - 
canary mismatch on efree() - heap overflow detected at 0x2ec9118

或内核错误,如:

Oct 22 10:29:43 apic kernel: [83469.382141] php[9479] general protection 
ip:6a8161 sp:7fffa270ec20 error:0 in php5[400000+6f9000]

Oct 22 09:29:45 apic kernel: [79871.245018] php[705]: segfault at 27f2298 
ip 00007f24229e640e sp 00007fff13aca388 error 6 in 
libc-2.11.2.so[7f2422968000+158000]

Cron 每五分钟运行一次以触发 munin-node,但错误每小时只发生一次。这可能是什么原因造成的?

由于不可重复,目前尚不清楚可以执行哪些操作,尽管错误会造成数据损坏的风险。有什么建议吗?

【问题讨论】:

  • 您从 PHP 错误日志中得到的确切错误是什么?
  • 您运行的是什么版本的 PHP 5.3 - 是最新的吗?
  • 相同的代码在多台服务器上运行,不同的PHP 5.3.x版本,错误似乎与特定的PHP版本无关。
  • halfer:PHP 5.3.8-1~dotdeb.2 在一个(nginx)上,5.3.3-7+squeeze3 在另一个(apache)上。

标签: php linux debian


【解决方案1】:

此代码不是(至少不应该是问题)。我会检查代码的其他部分,您可能会从 aliro 类外部引用 aliro::$instance。如果您尝试在类之外触摸它,则 $instance 是私有的会触发您抛出的确切错误(未声明的静态属性)。我会将其更改为受保护的(我也讨厌私有属性,它们很少需要私有而不是受保护)-这将提供更好的错误消息(您正在尝试访问非公开的属性),我也认为它应该给出你的文件和它出现的行。

【讨论】:

  • 谢谢。这似乎不对。从类外部或子类引用 aliro::$instance 的测试给出:“PHP 致命错误:无法访问私有属性 aliro::$instance”。尽可能使用 parent::$instance 不会改变错误消息。它不必是私有的,但由于该类不打算被子类化(可能是最终的),它并没有真正的区别。它确实给出了文件和行 - 它是上面引用的最后一行代码。
  • 经过反思,虽然我同意对象属性通常最好是受保护的,但对于类(静态)属性而言,情况并非如此。在单例实例变量(这是)的情况下,即使有一个子类,也很难看出从子类访问它有什么意义。由于这没有任何意义,因此最好通过将变量设为私有来表示这一点。
【解决方案2】:

我会检查正在扩展的课程。

当它调用self::$instance = new self()时,会调用基类的构造函数。

我注意到$instance 被声明为私有的,所以如果基类试图对那个变量做任何事情,它可能会抛出一个错误。

尝试将$instance 更改为protected 而不是private;如果这是问题所在,这样做应该可以解决它。

【讨论】:

  • 谢谢,但是 SFAIK 类根本不能引用子类中的静态变量。该类不知道(没有相当多的麻烦)它在哪里被子类化。无论如何,基类绝对不是指 aliro::$instance。更改为受保护没有区别。
猜你喜欢
  • 2015-02-24
  • 2017-03-23
  • 2011-10-24
  • 2017-07-06
  • 2016-10-06
  • 1970-01-01
  • 1970-01-01
  • 2015-02-13
  • 1970-01-01
相关资源
最近更新 更多