2010-10-21 10 views
9

Tenemos errores muy extraños de vez en cuando apareciendo en nuestra php logs: Trying to get property of non-object.PHP: objeto que es correcto NULL después de la creación

Este error exacto parece ser causado por el acceso al miembro de $shortName en la siguiente sentencia if:

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(); 

si yo tiro self::$system en un archivo de registro, veo que es NULL - justo después de haber sido construido con la palabra clave new.

Lo más interesante es que este archivo está incluido en todas y cada una de las solicitudes a nuestra página, por lo que se ejecuta ~ 10 veces por segundo. Pero de vez en cuando simplemente falla sin que nadie toque el código (o incluso el servidor).

¿Alguien más ha experimentado tal comportamiento en PHP?

+2

¿Hay algo dentro del código que pueda restablecer la instancia estática? – Gordon

+0

Hm ... ¿por qué estás creando una nueva instancia de la clase dentro de la clase? Probablemente estoy equivocado, pero ¿no tendría más sentido crear una sola instancia cuando inicialmente la llamas y consultarla desde dentro con la palabra clave '$ this'? – treeface

+0

@Gordon: el código que pegué está completo, no he dejado nada, pero tengo dificultades para creerlo. – soulmerge

Respuesta

1

Finalmente nos dimos cuenta que estábamos corriendo en php bug #50027. Después de establecer la variable php.ini zend.enable_gc en falso, el error desapareció.

0

probar el enfoque Singleton:

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 
… 

y ver lo que el valor de $ auto es

Su problema parece desovar de algo sobreescritura o simplemente porque tu no establecer el sistema variable $

con el enfoque singleton, se asegura de que la instancia solo se haya establecido una vez y de que nada lo sobrescriba.

p.s. ¿Qué hace el archivo en realidad?

+0

Apenas puedo cambiar el servidor de producción de esa manera. Pero tengo print_r() ed el valor en un archivo y '$ this' era' NULL'. – soulmerge

+0

por lo general tiene un servidor de desarrollo y un servidor de producción, pero también he experimentado trabajando directamente con el código de producción, así que no puedo editar mi respuesta. –

+0

@soulmerge: dijiste que tenías "print_r() ed el valor" de '$ this'. Hay 2 problemas con esa afirmación: 1. estás en una función estática, por lo que '$ this' nunca existirá; 2. 'print_r (NULL)' imprime nada, no "NULL". 'var_dump (NULL)' imprimirá "NULL". Supongo que quería decir algo como: "Tengo var_dump() ed el valor de' self :: $ system'? – Lee

-1

No estoy seguro de si lo descubrió, pero trataría de asignar el nuevo objeto directamente a una variable, luego lo asigne a self :: $ system más adelante. Algo como el siguiente código puede ayudar.

$newSystem = new self(); 
$newSystem->rfcName = SYSTEM_LOCALE_RFCNAME; 
$newSystem->shortName = strtolower(Locale::getRegion($rfcName)); 
.... 
self::$system = $newSystem 
0

¿Cuál es esta línea: self :: $ Sistema-> shortName = strtolower (Locale :: getRegion ($ rfcName)) ;? ¿De dónde viene el $ rfcName? Si no está definido antes de intentar usarlo, se produciría un error y el resto del código fallaría, lo que le daría el problema que describía.

Dado que no veo toda la clase, no tengo toda la información para responder a la pregunta, así que esto es sólo una suposición

0

Esto imprimirá el objeto una vez

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(); 
1

Gracias por todas las actualizaciones. (ver extensos comentarios arriba en la publicación original).

Desafortunadamente, estoy tan perplejo como usted, todo se ve bien con ese código.

De cualquier

  1. has encontrado algunos errores bastante oscura en php, o ...
  2. los síntomas que están engañando al pensar que el problema es en un solo lugar, cuando en realidad en otro lugar, o ...
  3. estamos todos falta algo en ese código que debe ser obvio para un grupo de desarrolladores de PHP sazonados. ;-)

Si fuera mi sistema de producción para hacer frente a, probablemente me comente la return NULL en el constructor, y se deja correr en la producción por un tiempo. Que el regreso no debe causar ningún problema, pero es la única cosa extraña que puedo ver aquí.

Lo siento, no puedo ayudar más que eso. Por favor regrese y avísenos si lo resuelve.

Cuestiones relacionadas