=== 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)
为什么结果不是1,1,1?
发布于 2015-09-09 22:08:32
试一试
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
变量content被精确地复制到当前的状态。不备份静态变量的原始值。
这意味着,当绑定类A
时,当静态变量为0
时,A::e()
将使用0
作为静态值;如果为1
,则A::e()
也将使用1
作为值。
与B::e()
类似,因为Base::e()
和A::e()
在值被复制时是独立的(没有引用)。它还将具有与绑定B
时的Base::e()
相同的静态变量。
发布于 2015-09-09 21:34:36
我对这个问题做了一些研究,这真的很奇怪。
方法中的静态属性在对象实例之间保持其状态。这可能会让人感到困惑。还有两个静态变量,一个是静态函数,另一个是方法内部的静态变量。
它可能与自动加载器连接。我用你的例子做了类似的例子,但没有使用静态方法,而是在方法中使用了静态变量。使用自动加载器和同一个文件的结果是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";
而不是自动加载器功能,它可以工作。为什么我不知道我试图用autoloader找到任何考虑静态变量的东西,但是没有成功。然而,这个答案可能会给你一些线索。
https://stackoverflow.com/questions/32474618
复制相似问题