Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/254.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_Static_Traits - Fatal编程技术网

性状中的静态变量如何不';在PHP中,当在类内部使用时,它不会失去价值吗?

性状中的静态变量如何不';在PHP中,当在类内部使用时,它不会失去价值吗?,php,oop,static,traits,Php,Oop,Static,Traits,虽然traits是语言辅助的复制/粘贴,但是traits中的静态属性在被类使用时如何不失去价值? 让我们考虑下面的例子, trait Test{ public static $var = 1; public static function increment(){ self::$var ++; var_dump(self::$var); } } Test::increment();//2 class Test2{

虽然traits是语言辅助的复制/粘贴,但是traits中的静态属性在被类使用时如何不失去价值? 让我们考虑下面的例子,

     trait Test{
    public static $var = 1;

   public static  function increment(){
        self::$var ++;
        var_dump(self::$var);
    }
}


Test::increment();//2



class Test2{

    use Test;

}

var_dump(Test2::$var);//2
Test2::increment();//3
这种行为在继承中是正确的,在继承中,子对象扩展父对象,因此子对象使用父对象静态变量,但是根据复制和粘贴应用的特性,这种行为如何工作和纠正


这是一个更新,为我的困惑添加了另一个原因, 如果静态值保留给特定的上下文,比如特定的类或函数,那么如何使用来自不同上下文(新类)的静态属性的更新值呢。 我的意思是,如果trait测试的上下文被称为例如Context1,而类Test2上下文被称为Context2,那么我如何在另一个上下文中访问第一个上下文的保留值?这与我们理解的方法背道而驰


更新3: 所有这些混淆都取决于use关键字是在类中导入trait成员还是从中复制/粘贴?

一种特质类似于一个类,但只用于分组 以细粒度和一致的方式提供功能。这是不可能的 单独实例化一个特征。这是对传统文化的补充 继承并支持行为的横向组合;就是, 类成员的应用程序,无需继承

您不能单独实例化一个Trait,也不能定义Trait使用的属性,因为它们会发生冲突,这是因为Trait将此功能“添加”到您要将其附加到的类中

虽然traits是语言辅助的复制/粘贴,但是traits中的静态属性在被类使用时如何不失去价值

trait有自己的上下文,与使用trait的类无关,至少对于静态属性是这样。如果类使用具有静态属性的trait,则该类将获得自己的上下文,即“自己的”静态属性,初始值从trait复制:

trait T {
    // '$staticProp' exists in the context of T
    public static $staticProp = "in T\n";
}

// Without the need of a class that implements the trait, you can already access its value explicitly:
echo T::$staticProp; // in T

class A {
    // Now 'A' gets its own '$staticProp', the initial value is copied from the context of the trait 'T'
    use T;
}

// Now you can access 'A's '$staticProp' explicitly:
echo A::$staticProp; // in T

// Now we can explicitly change the value of 'A's '$staticProp'. Because 'A' has its own context, 'T::$staticProp' stays untouched:
A::$staticProp = "in A\n";

echo A::$staticProp; // in A
echo T::$staticProp; // in T

这是一个更新,以增加另一个原因的困惑,我有。。。我的意思是,如果trait测试的上下文被称为例如Context1,而类Test2上下文被称为Context2,那么我如何在另一个上下文中访问第一个上下文的保留值

如我所示,您始终可以使用类/特征名称和范围解析运算符(
)访问特定上下文的静态属性:


所有这些混淆都取决于use关键字是在类中导入trait成员还是在复制/粘贴

我认为理解这种行为的最佳方式如下:

  • 一个特征本身总是有它自己的背景和它自己的当前值状态
  • 当一个类使用trait时,所有成员都将与其当前值一起复制。现在,类和trait有两个独立的上下文,每个上下文都有自己的状态
  • 更改一个上下文的值不会影响另一个上下文

  • 让我们考虑下面的例子,

         trait Test{
        public static $var = 1;
    
       public static  function increment(){
            self::$var ++;
            var_dump(self::$var);
        }
    }
    
    
    Test::increment();//2
    
    
    
    class Test2{
    
        use Test;
    
    }
    
    var_dump(Test2::$var);//2
    Test2::increment();//3
    
    以下是您的示例中发生的情况:

    trait Test {
        public static $var = 1;
    
        public static function increment() {
            self::$var++;
            var_dump(self::$var);
        }
    }
    
    // This will increment '$var' in the context of trait 'Test'
    Test::increment(); // 2
    
    // Access '$var' of trait context 'Test':
    var_dump(Test::$var); // 2
    
    class Test2 {
        // Members of 'Test' are copied with current values (2) in the context of class 'Test2'
        use Test;
    }
    
    // Access '$var' of class context 'Test2':
    var_dump(Test2::$var); // 2
    
    // This will increment '$var' in the context of class 'Test2'
    Test2::increment(); // 3
    
    // '$var' of trait context 'Test' has not changed:
    var_dump(Test::$var); // 2
    
    对于类,子类包括其父类的上下文:

    class A {
        public static $staticProp = "I am in debt\n";
    }
    
    class B extends A {}
    
    echo A::$staticProp; // I am in debt
    echo B::$staticProp; // I am in debt
    
    A::$staticProp = "Even more debts\n";
    
    echo A::$staticProp; // Even more debts
    echo B::$staticProp; // Even more debts
    
    B::$staticProp = "Paid debts, now debt-free\n";
    
    echo A::$staticProp; // Paid debts, now debt-free
    echo B::$staticProp; // Paid debts, now debt-free   
    
    self
    如果我们试图访问继承的成员,则通常引用它所使用的类或其父类:

    class A {
        public static $aProp = 0;
    }
    
    class B extends A {
        public static $bProp = 0;
    
        public static function setProps() {
            // Because B has a non inherited property '$bProp' 'self' will reference the context of class 'B':
            self::$bProp = 12;
    
            // Because B inherits a property '$aProp' 'self' will reference the inherited context of class 'A':
            self::$aProp = 23;
        }
    
        public static function printProps() {
            echo 'self::$bProp: ' . self::$bProp . "\n";
            echo 'self::$aProp: ' . self::$aProp . "\n";
        }
    }
    
    B::setProps();
    B::printProps();
        // self::$bProp: 12
        // self::$aProp: 23
    
    A::$aProp; // 23
    B::$aProp; // 23
    
    // Again 'A' and 'B' share the same context:
    A::$aProp = 0;
    echo B::$aProp; // 0
    
    当使用traits
    self
    时,引用traits上下文或复制的类的独立上下文。这就是您的示例中发生的情况:

    trait Test {
        public static $var = 1;
    
        public static function increment() {
            self::$var++;
            var_dump(self::$var);
        }
    }
    
    // This will increment '$var' in the context of trait 'Test'
    Test::increment(); // 2
    
    // Access '$var' of trait context 'Test':
    var_dump(Test::$var); // 2
    
    class Test2 {
        // Members of 'Test' are copied with current values (2) in the context of class 'Test2'
        use Test;
    }
    
    // Access '$var' of class context 'Test2':
    var_dump(Test2::$var); // 2
    
    // This will increment '$var' in the context of class 'Test2'
    Test2::increment(); // 3
    
    // '$var' of trait context 'Test' has not changed:
    var_dump(Test::$var); // 2
    

    我不理解你回答的所有方面,但根据我所理解的,问题不在于trait是一个具有附加或更少特性的类,问题在于我们没有使用继承来避免丢失静态属性的上下文值,我们只是在trait之间复制/粘贴属性和方法,那么,这种行为是如何复制旧的静态值的呢?我将对我的问题进行编辑,为我的困惑添加另一个证据。当一个特征具有静态属性时,这个答案根本不能回答关于不同背景的问题。。。