/** * @return mixed property value * @throws MemberAccessException if the property is not defined. */ public function &__get($name) { $class = get_class($this); $uname = ucfirst($name); if ($prop = ObjectMixin::getMagicProperty($class, $name)) { // property getter if (!($prop & 0b1)) { throw new MemberAccessException("Cannot read a write-only property {$class}::\${$name}."); } $m = ($prop & 0b10 ? 'get' : 'is') . $uname; if ($prop & 0b100) { // return by reference return $this->{$m}(); } else { $val = $this->{$m}(); return $val; } } elseif ($name === '') { throw new MemberAccessException("Cannot read a class '{$class}' property without name."); } elseif (($methods =& ObjectMixin::getMethods($class)) && isset($methods[$m = 'get' . $uname]) || isset($methods[$m = 'is' . $uname])) { // old property getter trigger_error("Add annotation @property for {$class}::\${$name} or use {$m}()" . ObjectMixin::getSource(), E_USER_DEPRECATED); if ($methods[$m] === 0) { $methods[$m] = (new \ReflectionMethod($class, $m))->returnsReference(); } if ($methods[$m] === TRUE) { return $this->{$m}(); } else { $val = $this->{$m}(); return $val; } } elseif (isset($methods[$name])) { // public method as closure getter trigger_error("Accessing methods as properties via \$obj->{$name} is deprecated" . ObjectMixin::getSource(), E_USER_DEPRECATED); $val = Callback::closure($this, $name); return $val; } elseif (isset($methods['set' . $uname])) { // property getter throw new MemberAccessException("Cannot read a write-only property {$class}::\${$name}."); } else { ObjectMixin::strictGet($class, $name); } }