coding - psr-1 php
PHP autoload y variable estática en función (2)
Hice algunas investigaciones sobre este problema y es realmente extraño.
Las propiedades estáticas dentro de los métodos permanecen en su estado entre las instancias del objeto. Lo que puede ser confuso. También hay dos estadísticas: una es la función estática y la otra es una variable estática dentro del método.
Puede estar conectado con autoloader. Hice un ejemplo similar con su pero sin usar métodos estáticos pero usando una variable estática dentro del método. El resultado es 1: 1: 1 utilizando tanto el autocargador como el mismo archivo.
<?php
class Base
{
public function t()
{
static $number = 0;
$number++;
var_dump($number);
}
public static function e()
{
static $number = 0;
$number++;
var_dump($number);
}
}
$base = new Base();
$base->t();
$a = new A();
$a->t();
$b = new B();
$b->t();
Además, si no ejecuta Base::e()
el resultado es correcto.
He hecho require_once sin carga automática y todavía funciona. Así es definitivamente por autoloader.
Si pones
require_once "Base.php";
require_once "A.php";
require_once "B.php";
En lugar de la función de autocargador funciona. ¿Por qué es que no tengo idea de que he intentado encontrar algo considerando variables estáticas con autoloader pero sin éxito? Sin embargo, esta respuesta puede darle alguna pista.
=== Base.php ===
<?php
class Base
{
public static function e()
{
static $number = 0;
$number++;
var_dump($number);
}
}
=== A.php ===
<?php
class A extends Base {}
=== B.php ===
<?php
class B extends Base {}
=== test.php ===
function __autoload($classname)
{
require_once("{$classname}.php");
}
Base::e();
A::e();
B::e();
php test.php, el resultado es:
int(1)
int(2)
int(2)
¿Por qué no el resultado es 1,1,1?
Tratar
require "Base.php";
Base::e();
require "A.php";
A::e();
contra
require "Base.php";
require "A.php";
Base::e();
A::e();
El primero producirá int(1) int(2)
, mientras que el último producirá int(1) int(2)
int(1) int(1)
.
¿Por qué?
Cuando una clase está vinculada, el contenido de la variable static
se copia exactamente en ese momento como está actualmente. No hay una copia de seguridad del valor original de la variable estática.
Eso implica que cuando la variable estática es 0
cuando la clase A
está vinculada, A::e()
tendrá 0
como valor estático; en caso de que sea 1
, A::e()
también tendrá 1
como valor.
Similar para B::e()
entonces, ya que Base::e()
y A::e()
son independientes ya que los valores se copian (sin referencias). También tendrá la misma variable estática Base::e()
en el momento de la vinculación de B