PHP:对象在创建后立即为空

PHP:对象在创建后立即为空,php,Php,我们的:中偶尔会出现非常奇怪的错误,试图获取非对象的属性。 这个确切的错误似乎是由于访问以下if语句中的成员$shortName引起的: class MyLocaleWrapper extends SomeOtherClass { … protected static $system = NULL; public static function getSystemLocale() { if (self::$system === NULL) {

我们的:
中偶尔会出现非常奇怪的错误,试图获取非对象的属性。

这个确切的错误似乎是由于访问以下if语句中的成员
$shortName
引起的:

class MyLocaleWrapper extends SomeOtherClass {
    …
    protected static $system = NULL;
    public static function getSystemLocale() {
        if (self::$system === NULL) {
            self::$system = new self();
            debug(self::$system);
            self::$system->rfcName = SYSTEM_LOCALE_RFCNAME;
            self::$system->shortName = strtolower(Locale::getRegion(self::$system->rfcName));
            if (self::$system->shortName == '') {
                self::$system->shortName = strtolower(self::$system->rfcName);
            }
            …

# in another file:
class SomeOtherClass {
    …
    public function __construct() {
        # Some documentation about features that have been
        # removed from the constructor, but no real code in here.
        return NULL;
    }
    …

# in yet another file:
MyLocaleWrapper::getSystemLocale();
如果我将
self::$system
转储到日志文件中,我会看到它是
NULL
——就在使用关键字
new
构造之后

最有趣的是,这个文件包含在我们页面的每个请求中,因此每秒执行10次。但有时它只是在没有任何人接触代码(甚至服务器)的情况下失败


还有人在PHP中经历过这样的行为吗?

试试单例方法:

class MyLocaleWrapper {
    …
    private static $system = NULL;//set it to private, and instead of accessing it as $this->system, access it with self::getInstance() or parent::getInstance() if your trying to get the parent instance
    public static function getInstance() {
        if (!(self::$system instanceof self)){
            self::$system = new self();
        }
        return self::$system;
    }
    final private function __construct() { }// Do not allow an explicit call of the constructor: $v = new Singleton();
    final private function __clone() { }// Do not allow the clone operation: $x = clone $v;
    public static function getSystemLocale() {
        $self = self::getInstance();
        log($self);//dump the value into a file with you function
…
看看$self的价值是多少

您的问题似乎是由于某些内容被覆盖,或者只是因为您没有设置$system变量

使用单例方法,您可以确保实例只设置了一次,并且没有任何内容覆盖它


p、 文件实际上是做什么的?

不确定您是否理解了这一点,但我会尝试将新对象直接分配给变量,然后稍后将其分配给self::$system。下面的代码可能会有所帮助

$newSystem = new self();
$newSystem->rfcName = SYSTEM_LOCALE_RFCNAME;
$newSystem->shortName = strtolower(Locale::getRegion($rfcName));
....
self::$system = $newSystem
这条线是什么 self::$system->shortName=strtolower(Locale::getRegion($rfcName));? $rfcName来自哪里? 如果在您尝试使用它之前未定义它,则会导致错误,导致其余代码失败,从而导致您描述的问题


因为我没有看到你的全班同学,所以我没有回答这个问题的所有信息,所以这只是一个猜测,这将打印一次对象

class MyLocaleWrapper extends SomeOtherClass {

    protected static $system = NULL;
    public static function getSystemLocale() {
        if (self::$system === NULL) {
            self::$system = new MyLocaleWrapper();

            self::$system->rfcName = 'test';
            self::$system->shortName = strtolower('test');
            if (self::$system->shortName == '') {
                self::$system->shortName = strtolower('test');
            }
                print_r(self::$system);

        }
        return self::$system;
    }
}

# in another file:
class SomeOtherClass {

    public function __construct() {
        # Some documentation about features that have been
        # removed from the constructor, but no real code in here.
        return NULL;
    }
}

# in yet another file:
$l = MyLocaleWrapper::getSystemLocale();
$l = MyLocaleWrapper::getSystemLocale();

谢谢你的更新。(见上文原始帖子的大量评论)

不幸的是,我和你一样感到困惑——使用这些代码看起来一切都很好

或者

  • 您在php中发现了一些相当模糊的错误,或者
  • 这些症状诱使你认为问题出在某个地方,而实际上问题出在其他地方,或者
  • 我们在代码中都遗漏了一些对一批经验丰富的php开发人员来说应该是显而易见的东西 如果要处理的是我的生产系统,我可能会在构造函数中注释掉
    returnnull
    ,让它在生产环境中运行一段时间。这种回归应该不会造成任何问题,但这是我在这里看到的唯一奇怪的事情


    对不起,我帮不了你。如果你能找到答案,请回来告诉我们。

    我们终于发现我们遇到了麻烦。将php.ini-variable
    zend.enable\u gc
    设置为false后,错误消失。

    代码中是否有任何东西可以重置静态实例?嗯……为什么要从类中创建新的类实例?我可能错了,但是当您最初调用它时,创建一个实例,并用
    $this
    关键字从内部引用它,这难道不是更有意义吗?@Gordon:我粘贴的代码是完整的,我没有遗漏任何东西-但我自己也很难相信这一点。@treeface这不是一个单例,而是一个内置的工厂。应用程序中可以有多个区域设置,但其中一个是系统区域设置。@soulmerge我想您必须使用XDebug来获取有关运行时发生的情况的更多信息。我很难像这样更改生产服务器。但我已将值打印到文件中,
    $this
    NULL
    。通常您有开发服务器和生产服务器,但我也有直接使用生产代码的经验,因此我将编辑我的答案。@soulmerge:您说您已“打印了
    $this
    的值”。这种说法有两个问题:1。您处于静态函数中,因此,
    $this
    将永远不存在;2. <代码>打印\u r(空)不打印任何内容--不是“空”<代码>变量转储(NULL)将打印“NULL”。我想你的意思是:“我已经对
    self:$system
    ?@Lee:1]的值进行了var_dump()运算。)对不起,我的意思是
    $system
    NULL
    2。)我使用了一个自定义调试函数,该函数验证了值是
    NULL
    (我已经使用该函数好几年了,我非常怀疑它有这样的bug)