phpoopmodelyii2virtual-attribute

Yii2 call method/function of a different model


I have a method/function of a virtual attribute in Model1:

class Model1 {
    public $virtattr;
    public $_virtattr;

    public function getVirtattr () {
        if (isset($this->_virtattr)) {
            return $this->_virtattr;
        }

        return $this->_virtattr = str_ireplace('x1', 'x2', $this->virtattr);
    }
}

How can I call this method in Model2 to get the same result? I was trying it this way but unfortunately it's not working, 'cause I'm getting empty results:

use Model1;

class Model2 {
    public $virtattr;
    public $_virtattr;

    public function getVirtattr () {
        return (new Model1)->getVirtattr();
    }
}

Can you please point me to the right direction?


Solution

  • The point of object programming is encapsulation - Model1 will not magically use properties from Model2 just because you instantiated Model1 inside of Model2. Model1 will use its own properties so (new Model1())->getVirtattr() will not touch properties from Model2.

    If you want to share the same logic between two classes, you may use inheritance:

    class Model1 {
    
        public $virtattr;
        public $_virtattr;
    
        public function getVirtattr() {
            if ($this->_virtattr !== null) {
                return $this->_virtattr;
            }
    
            return $this->_virtattr = str_ireplace('x1', 'x2', $this->virtattr);
        }
    }
    
    class Model2 extends Model1 {
    
    }
    

    Then Model1::getVirtattr() and Model2::getVirtattr() will use the same implementation.

    If inheritance is not possible/preferred, you may use traits to share the same implementation between two separate classes:

    trait VirtattrTrait {
    
        public $virtattr;
        public $_virtattr;
    
        public function getVirtattr() {
            if ($this->_virtattr !== null) {
                return $this->_virtattr;
            }
    
            return $this->_virtattr = str_ireplace('x1', 'x2', $this->virtattr);
        }
    }
    
    class Model1 {
    
        use VirtattrTrait;
    }
    
    class Model2 {
    
        use VirtattrTrait;
    }