PHP自动加载和静态变量函数


PHP autoload and static variable in function

=== 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,结果为

int(1)
int(2)
int(2)

为什么result不是1,1,1?

Try

require "Base.php";
Base::e();
require "A.php";
A::e();

require "Base.php";
require "A.php";
Base::e();
A::e();

前者产int(1) int(2),后者产int(1) int(1)

为什么?

当一个类被绑定时,static变量的内容被精确地复制到它当前的位置。静态变量的原始值没有备份。

表示绑定A类时,静态变量为0时,A::e()将以0为静态值;在1的情况下,A::e()也将1作为值。

B::e()类似,因为Base::e()A::e()是独立的,因为它们的值是复制的(没有引用)。它还将具有与B绑定时Base::e()相同的静态变量。

我对这个问题做了一些研究,它真的很奇怪。

方法中的静态属性在对象实例之间保持其状态。这可能令人困惑。也有两个静态,一个是静态函数,另一个是静态变量的方法。

可连接自动装弹机。我做了类似的例子,但没有使用静态方法,而是使用静态变量内部方法。使用自动加载器和相同的文件,结果是1:1:1。

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

如果你不执行Base::e(),结果是正确的。

我做了require_once没有自动加载,它仍然工作。所以肯定是因为自动装弹器。

如果你把

require_once "Base.php";
require_once "A.php";
require_once "B.php";

而不是自动加载功能,它工作。为什么我不知道我试图找到任何考虑静态变量的自动加载器,但没有成功。然而,这个答案可能会给你一些提示。