Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php 静态函数变量与静态类变量_Php_Oop_Php 7.2 - Fatal编程技术网

Php 静态函数变量与静态类变量

Php 静态函数变量与静态类变量,php,oop,php-7.2,Php,Oop,Php 7.2,考虑以下几点: class Super { static protected $class_var = 0; public function __construct() { static $function_var = 0; static::$class_var++; $function_var++; echo sprintf("class_name : %s, class_var : %s, func

考虑以下几点:

class Super
{
    static protected $class_var = 0;

    public function __construct()
    {
        static $function_var = 0;

        static::$class_var++;
        $function_var++;

        echo sprintf("class_name : %s, class_var : %s, function_var : %s\n", static::class, static::$class_var, $function_var);
    }

    public static function test()
    {
        static $function_var = 0;

        static::$class_var++;
        $function_var++;

        echo sprintf("class_name : %s, class_var : %s, function_var : %s\n", static::class, static::$class_var, $function_var);
    }
}

class A extends Super {}
class B extends Super {}

echo "Object calls\n";
new A();
new A();
new B();
echo "Class calls\n";
A::test();
A::test();
B::test();
PHP 7.2.7输出:

Object calls
class_name : A, class_var : 1, function_var : 1
class_name : A, class_var : 2, function_var : 2
class_name : B, class_var : 3, function_var : 3
Class calls
class_name : A, class_var : 4, function_var : 1
class_name : A, class_var : 5, function_var : 2
class_name : B, class_var : 6, function_var : 1

为什么在类上调用时,A和B都有自己的静态函数var。而A和B在实例上调用时共享静态函数var。或者更一般地说,它们是如何在内部工作的?

一般行为可以这样解释(下面有一条关于构造函数的但书):静态类属性的作用域是针对定义它们的类,静态方法变量的作用域是针对调用它们的类

您的
test
方法声明为静态的事实在这里并不重要,因此我将其简化为以下测试脚本:

class Super
{
    static protected $class_var = 0;

    public function test()
    {
        static $function_var = 0;

        static::$class_var++;
        $function_var++;

        echo sprintf("class_name : %s, class_var : %s, function_var : %s", static::class, static::$class_var, $function_var), PHP_EOL;
    }
}

class A extends Super {}
class B extends Super {}
因为它是在类上定义的,
$class\u var
将始终链接到该范围。不管有多少类扩展了
Super
,它们都会引用相同的变量(除非它们重写它)

另一方面,
$function\u var
的作用域是调用
test
方法的类。调用
A
的所有实例将共享一个,调用
B
的所有实例将共享一个

$a = new A;
$b = new B;

$a->test(); // class_name : A, class_var : 1, function_var : 1
$a->test(); // class_name : A, class_var : 2, function_var : 2
$b->test(); // class_name : B, class_var : 3, function_var : 1
构造函数(但书): 您问题中的另一个问题是,构造函数的行为与任何其他类方法不同,因为尽管在语法上类似,但它根本不是一个方法。与类属性类似,构造函数中声明为静态的任何变量的作用域都是定义它的类:

如果我们加上:

public function __construct()
{
    static $constructor_var = 0;
    $constructor_var++;

    echo sprintf("class_name : %s, constructor_var : %s", static::class, $constructor_var), PHP_EOL;
}
然后我们可以演示如下:

$a = new A; // class_name : A, constructor_var : 1
$b = new B; // class_name : B, constructor_var : 2
除非任何子类重写构造函数,否则它们都将共享相同的
$constructor\u var
实例


不幸的是,我在文档中找不到这方面的简单摘要,我也不确定其中有多少是设计的。特别是构造函数中的静态变量,我想我从来没有遇到过,静态函数变量本身也越来越少。但知道事情是如何运作的很有趣,这是个好问题。

你不使用全局变量怎么样?@tereško这就是我所希望的程序员精神我是认真的。如果你使用一个“静态类”,它实际上只是一个名称空间的全局函数列表(因为在5.3之前没有名称空间),而静态变量本质上只是全局状态的一种替代形式。嘿@iainn,答案是thx!我对单例使用静态方法var:对于这种行为,静态方法var似乎是唯一的解决方案。不要使用静态,不要使用单例。停止这种疯狂。接受依赖注入。@emix Singleton vs DI Apple vs pearsSorry,但不是。编写正确的OOP、可靠的、可测试的、可维护的代码。