Type casting for user defined objects

前端 未结 11 1574
没有蜡笔的小新
没有蜡笔的小新 2020-11-29 01:35

Just like we do with __ToString, is there a way to define a method for casting?

$obj = (MyClass) $another_class_obj;
11条回答
  •  陌清茗
    陌清茗 (楼主)
    2020-11-29 01:51

    Even on PHP 7.2 if you try simple type casting, like so

    class One
    {
        protected $one = 'one';
    }
    
    class Two extends One
    {
        public function funcOne()
        {
            echo $this->one;
        }
    }
    
    
        $foo = new One();
        $foo = (Two) $foo;
        $foo->funcOne();
    

    You'll get error like this

    PHP Parse error: syntax error, unexpected '$foo' (T_VARIABLE) in xxx.php on line xxx

    So you basically cannot do that, but think again, maybe you wanted only a new function on top of other public functionality of the class?

    You can do that using Wrapper

    class One
    {
        protected $one;
        public function __construct(string $one)
        {
            $this->one = $one;
        }
        public function pub(string $par){
            echo (__CLASS__ . ' - ' . __FUNCTION__ . ' - ' . $this->one . '-' .$par);
        }
    }
    
    class Wrapper
    {
        private $obj;
    
        public function __construct(One $obj)
        {
            $this->obj = $obj;
        }
        public function newFunction()
        {
            echo (__CLASS__ . ' - ' . __FUNCTION__);
        }
        public function __call($name, $arguments)
        {
            return call_user_func_array([$this->obj, $name], $arguments);
        }
    }
    
        $foo = new One('one');
        $foo->pub('par1');
        $foo = new Wrapper($foo);
        $foo->pub('par2');
        $foo->newFunction();
    

    One - pub - one-par1

    One - pub - one-par2

    Wrapper - newFunction

    What if you want to get a protected property out?

    You can do that too

    class One
    {
        protected $one;
    
        public function __construct(string $one)
        {
            $this->one = $one;
        }
    }
    
    
        $foo = new One('one');
        $tmp = (new class ($foo) extends One {
                protected $obj;
                public function __construct(One $obj)
                {
                    $this->obj = $obj;
                    parent::__construct('two');
                }
                public function getProtectedOut()
                {
                    return $this->obj->one;
                }
            } )->getProtectedOut();
    
        echo ($tmp);
    

    You'll get

    one

    And you can get_protected_in the same way

提交回复
热议问题