魔术方法 - 我可以使用它们来捕获无法访问的静态属性吗?

时间:2014-11-22 09:01:38

标签: magic-methods php-5.5

我可以使用魔术方法来捕捉Access to undeclared static property无法访问的静态属性吗?

例如,

class greeting 
{
    static public function init()
    {
        static::$message = 'Hello World!';
    }

    /*
     *  Set the inaccessible property magically.
     */
    public function __set($name, $value)
    {
        var_dump($name); // set the property here?
    }

    /*
     *  Get the inaccessible $class magically.
     */
    public function __get($name)
    {
        var_dump($name); // set the property here?
    }
}

greeting::init();
var_dump(greeting::$message);

我明白了,

  

致命错误:访问未声明的静态属性:greeting :: $ messsage   在C:......

1 个答案:

答案 0 :(得分:1)

不要这么认为。没有像__getStatic或__setStatic这样的神奇方法。至于您的问题涉及注册表模式,您可以这样做:

使用标准注册表模式:

class Reg {

    private $register = array();

    private static $instance = null;

    public static function getInstance()
    {
        if ( self::$instance === null)
        {
            self::$instance = new Registry;
        }

        return self::$instance;
    }

    public function __set($key, $val)
    {
        $this->register[$key] = $val;
    }

    public function __get($key)
    {
        if (isset($this->register[$key]))
        {
            return $this->register[$key];
        }
        else
        {
            return null;
        }
    }
}

呼叫:

$reg = Reg::getInstance();
$reg->foo = 'bar';
echo $reg->foo;

或者使用带有(非魔法)getter和setter的抽象注册表类:

abstract class Reg {

    private static $register = array();

    public static function set($key, $val)
    {
        self::$register[$key] = $val;
    }

    public static function get($key)
    {
        if (isset(self::$register[$key]))
        {
            return self::$register[$key];
        }
        else
        {
            return null;
        }
    }
}

呼叫:

Reg::set('foo','bar');
echo Reg::get('foo');

优点:无需实例化Registry类

或者使用带有magic callStatic方法的抽象注册表类:

abstract class Reg {

    private static $register = array();

    public static function __callStatic($key, $val)
    {
        if(count($val))
        {
            self::$register[$key] = $val[0]; // $val is passed as array, so take first item
        }
        else
        {
            if (isset(self::$register[$key]))
            {
                return self::$register[$key];
            }
            else
            {
                return null;
            }           
        }
    }
}

呼叫:

Reg::foo('bar');
echo Reg::foo();

优点:设置和获取变量所需的字符更少。

缺点:表现不佳。

在一个1.000.000循环的小测试中,我得到了以下内容:

方法1)2,319s

方法2)1,416s

方法3)3,708s

因此,使用非魔法(但至少是静态的)getter和setter的抽象注册表似乎是最佳解决方案。