Sí, la diferencia fundamental es que los métodos declarados static
no tienen acceso a la variable de contexto de objeto, $this
.
Además, la invocación de un método no estático cuando no está en el contexto del objeto provocará un evento de error E_STRICT
. Cuando está habilitado, el comportamiento predeterminado de ese evento es enviar un mensaje al registro de errores (o STDERR), pero permitirá que el programa continúe ejecutando.
Además, cualquier intento de referencia $this
cuando no se encuentre en un contexto de objeto desencadenará un evento E_ERROR
. El comportamiento de ese evento es dar salida a un mensaje en el registro de error (o STDERR) y para salir del programa con el estado 255.
Por ejemplo:
<?php
error_reporting(-1);
//error_reporting(E_ALL);
class DualNature {
public static function fnStatic() {
if (isset($this)) {
// never ever gets here
$myValue = $this->_instanceValue;
} else {
// always gets here
$myValue = self::$_staticValue;
}
return $myValue;
}
public function fnInstance() {
if (isset($this)) {
// gets here on instance (->) reference only
$myValue = $this->_instanceValue;
} else {
// gets here in all other situations
$myValue = self::$_staticValue;
}
return $myValue;
}
public static function fnStaticDeath() {
return $this->_instanceValue;
}
private static $_staticValue = 'no access to $this';
private $_instanceValue = '$this is available';
}
$thing = new DualNature();
echo "==========\n";
printf("DualNature::fnStatic(): \"%s\"\n", DualNature::fnStatic());
echo "==========\n";
printf("\$thing::fnStatic(): \"%s\"\n", $thing::fnStatic());
echo "==========\n";
printf("\$thing->fnStatic(): \"%s\"\n", $thing->fnStatic());
echo "==========\n";
printf("DualNature::fnInstance(): \"%s\"\n", DualNature::fnInstance());
echo "==========\n";
printf("\$thing::fnInstance(): \"%s\"\n", $thing::fnInstance());
echo "==========\n";
printf("\$thing->fnInstance(): \"%s\"\n", $thing->fnInstance());
echo "==========\n";
printf("\$thing->fnStaticDeath(): \"%s\"\n", $thing->fnStaticDeath());
echo "==========\n";
echo "I'M ALIVE!!!\n";
La salida del anterior es:
==========
PHP Strict Standards: Non-static method DualNature::fnInstance() should not be called statically in example.php on line 45
DualNature::fnStatic(): "no access to $this"
==========
$thing::fnStatic(): "no access to $this"
==========
$thing->fnStatic(): "no access to $this"
PHP Strict Standards: Non-static method DualNature::fnInstance() should not be called statically in example.php on line 47
==========
DualNature::fnInstance(): "no access to $this"
==========
$thing::fnInstance(): "no access to $this"
==========
$thing->fnInstance(): "$this is available"
==========
PHP Fatal error: Using $this when not in object context in example.php on line 29
Al cambiar el nivel de informe de error a E_ALL
se suprimirán los mensajes de advertencia predeterminados E_STRICT
(el evento se seguirá propagando), pero la referencia no válida a $this
seguirá causando un error fatal y saldrá del programa.
Guau, en realidad funciona. PHP es realmente un desastre. – Gumbo
@Gumbo: PHP4 backcompat, si te gusta estricto, lanza excepciones en los errores estrictos. – hakre