不同范围内的PHP魔术方法
我一直在阅读并试图更好地理解它们。PHP手册中指出: 当与尚未声明或在当前范围内不可见的属性或方法交互时,将调用重载方法 我读过“不”的含义: 属性、方法或常量(从PHP7.1.0开始)的可见性可以通过在声明前面加上关键字public、protected或private来定义 请考虑下面的类:不同范围内的PHP魔术方法,php,oop,scope,magic-methods,Php,Oop,Scope,Magic Methods,我一直在阅读并试图更好地理解它们。PHP手册中指出: 当与尚未声明或在当前范围内不可见的属性或方法交互时,将调用重载方法 我读过“不”的含义: 属性、方法或常量(从PHP7.1.0开始)的可见性可以通过在声明前面加上关键字public、protected或private来定义 请考虑下面的类: <?php class MyClass{ private $x = 1; protected $y = 2; public $z = 3;
<?php
class MyClass{
private $x = 1;
protected $y = 2;
public $z = 3;
public __construct(){}
function __get($name){
switch(true){
case ($name == 'x'):
return 4;
case ($name == 'y'):
return 5;
case ($name == 'z'):
return 6;
case ($name == 'w'):
return 0;
}
}
function sum(){
return $this->x + $this->y + $this->z;
}
}
?>
因此,考虑到上面关于“可见”和“范围”的代码片段,在什么上下文下会调用\u get
magic方法,什么时候不会调用
如果我实例化一个新对象:$myclass=newmyclass()
,将$myclass->sum()
返回6
或15
或其他什么
如果我调用$myclass->x
,$myclass->y
,$myclass->z
,结果会是4
,5
和3
,因为x
和y
在技术上是不可见的吗
我假设调用$myclass->w
将返回0
,而不考虑作用域,因为它从来没有定义为类的属性,对吗
因此,考虑到上面关于“可见”和“范围”的代码片段,在什么上下文下会调用\u get
magic方法,什么时候不会调用
当访问对象上不存在的属性时,或者从无法访问的范围访问属性时,将调用\uu get
方法。例如,$obj->foo
将始终触发\uu-get
,从类外调用时,$obj->x
将触发\uu-get
如果我实例化一个新对象:$myclass=newmyclass()
,那么$myclass->sum()
是否会返回6或15或其他值
它将返回6(1+2+3
)$this->x
、->y
和->z
都可以从类中访问,因此这里不会触发\u get
方法
如果我调用$myclass->x
,$myclass->y
,$myclass->z
,结果会是4、5和3吗?因为x和y在技术上是不可见的
对
我假设调用$myclass->w
将返回0,无论其作用域如何,因为它从未定义为类的属性,对吗
正确,只要您没有显式地为$myclass->w
赋值
class MyClass {
private $x = 1;
protected $y = 2;
public $z = 3;
// ...
}
因此,考虑到上面关于“可见”和“范围”的代码片段,在什么上下文下会调用\u get
magic方法,什么时候不会调用
当访问对象上不存在的属性时,或者从无法访问的范围访问属性时,将调用\uu get
方法。例如,$obj->foo
将始终触发\uu-get
,从类外调用时,$obj->x
将触发\uu-get
如果我实例化一个新对象:$myclass=newmyclass()
,那么$myclass->sum()
是否会返回6或15或其他值
它将返回6(1+2+3
)$this->x
、->y
和->z
都可以从类中访问,因此这里不会触发\u get
方法
如果我调用$myclass->x
,$myclass->y
,$myclass->z
,结果会是4、5和3吗?因为x和y在技术上是不可见的
对
我假设调用$myclass->w
将返回0,无论其作用域如何,因为它从未定义为类的属性,对吗
正确,只要您没有显式地为$myclass->w
赋值
class MyClass {
private $x = 1;
protected $y = 2;
public $z = 3;
// ...
}
在MyClass
类的代码中,所有实例属性($x
、$y
和$z
)都是可见的。sum()
函数可以看到它们,使用它们时无需调用\uu get()
如果代码试图访问同一类的另一个对象的受保护
或私有
属性,也会发生这种情况。例如:
class MyClass {
private $x = 1;
protected $y = 2;
public $z = 3;
public function copyFrom(MyClass $that) {
$this->x = $that->x;
$this->y = $that->y;
$this->z = $that->z;
}
}
$a = new MyClass();
$b = new MyClass();
$b->copyFrom($a);
copyFrom()
方法可以访问$对象的所有属性(因为它与$this
属于同一类),并且不会调用\u get()
但对于此代码:
$a = new MyClass();
echo($a->x + $a->y + $a->z);
对于$a->x
和$a->y
调用了两次神奇的方法\uu get()
,因为这些属性在MyClass
类之外的代码中不可见
一般来说,如果类没有定义\uu get()
方法,当访问不可见的属性进行读取时,解释器会触发致命错误:
PHP致命错误:未捕获错误:无法访问私有属性MyClass::$x
出现\uu get()
会抑制错误<改为调用code>\uu get()
,并使用它返回的值。如果\uuu get()
不返回值(无论为什么),则使用它(这是函数的标准PHP行为)
在MyClass
类的代码中,所有实例属性($x
、$y
和$z
)都是可见的。sum()
函数可以看到它们,使用它们时无需调用\uu get()
如果代码试图访问同一类的另一个对象的受保护
或私有
属性,也会发生这种情况。例如:
class MyClass {
private $x = 1;
protected $y = 2;
public $z = 3;
public function copyFrom(MyClass $that) {
$this->x = $that->x;
$this->y = $that->y;
$this->z = $that->z;
}
}
$a = new MyClass();
$b = new MyClass();
$b->copyFrom($a);
copyFrom()
方法可以访问该对象的$的所有属性(因为它属于同一类)