魔术方法(__get,__ set)在扩展类中不起作用?

Ric*_*nop 4 php

<?php 

abstract class AbstractClass
{
    public function __get($theName)
    {
        return (isset($this->$theName)) ? $this->$theName : NULL;
    }

    public function __set($theName, $theValue)
    {
        if (false === property_exists(get_class(), $theName)) {
            throw new Exception(get_class()." does not have '".$theName."' property.");
        } else {
            $this->$theName = $theValue;
        }
    }
}

class ConcreteClass extends AbstractClass
{
        private $x;
        private $y;

        public function __construct($theX, $theY)
        {
            $this->x = $theX;
            $this->y = $theY;
        }
}

$concreteClass = new ConcreteClass(10, 20);

var_dump( $concreteClass->x );
Run Code Online (Sandbox Code Playgroud)

有没有办法让这项工作或我必须将这些魔术方法添加到扩展类?

Gor*_*don 8

这可行:

public function __get($theName)
{
    if(property_exists($this, $theName)) {
        $reflection = new ReflectionProperty($this, $theName);
        $reflection->setAccessible($theName);
        return $reflection->getValue($this);
    }
}
Run Code Online (Sandbox Code Playgroud)

IMO,你不应该使用__get__set作为getter和setter的替代品.由于它们在尝试访问不可访问的属性时被触发,因此它们与错误处理更相关.而且它们也比普通的吸气剂或定位器慢得多.


Rii*_*imu 5

你的问题是在这里设置的$ x和$ y成员ConcreteClass是私有的.由于该__get()方法是在父类中定义的,因此它无权访问子类的私有成员(因为私有成员只能由类本身访问,而不能由任何子类或父类访问).要让它们对父类可见,它们必须是protected或者public.对于你的情况,你必须使用protected来维护课外的神奇功能.

然而,这是一个非常奇怪的做法.如果可以通过魔术方法访问变量,那么首先将它们设为私有是没有多大意义的.