PHP 各种范围内的魔术方法
PHP magic methods in various scopes
我一直在阅读 PHP magic methods 并试图更好地理解它们。 PHP 手册中指出:
The overloading methods are invoked when interacting with properties or methods that have not been declared or are not visible in the current scope.
我已经阅读了 "not visible" 的含义:
The visibility of a property, a method or (as of PHP 7.1.0) a constant can be defined by prefixing the declaration with the keywords public, protected or private.
所以请考虑下面的 class:
<?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;
}
}
?>
考虑到上面关于 "visible" 和 "scope" 的片段,__get
魔法方法将在什么情况下被调用,什么时候不会被调用?
如果我实例化一个新对象:$myclass = new MyClass()
,会 $myclass->sum()
return 6
或 15
还是其他什么?
如果我调用 $myclass->x
、$myclass->y
、$myclass->z
,结果会是 4
、5
和 3
,因为x
和 y
在技术上不是 "visible"?
我假设调用 $myclass->w
将 return 0
无论范围如何,因为它从未被定义为 class 的 属性 开始是吗?
So considering the snippets above regarding "visible" and "scope", under what context will the __get
magic method get invoked and when will it not?
当访问对象上不存在的 属性 时,或从不存在的范围访问 属性 时,将调用 __get
方法无障碍。例如,$obj->foo
将始终触发 __get
,而当从 class.
外部调用时,$obj->x
将触发 __get
If I instantiate a new object: $myclass = new MyClass()
, will $myclass->sum()
return 6 or 15 or something else?
它将 return 6 (1 + 2 + 3
)。 $this->x
、->y
和 ->z
都可以从 class 中访问,因此这里不会触发 __get
方法。
What if I call the $myclass->x
, $myclass->y
, $myclass->z
, will the results be 4, 5 and 3 since x and y are technically not "visible"?
正确。
I assume calling $myclass->w
will return 0 regardless of scope since it wasn't ever defined as a property of the class to begin with, is that right?
正确,只要您没有明确地为 $myclass->w
赋值。
class MyClass {
private $x = 1;
protected $y = 2;
public $z = 3;
// ...
}
在 MyClass
class 的代码中,所有实例属性($x
、$y
和 $z
)都是可见的。 sum()
函数会看到它们,并且在使用它们时无需调用 __get()
.
如果代码试图访问同一 class 的另一个对象的 protected
或 private
属性,也会发生这种情况。例如:
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()
方法可以访问 $that
对象的所有属性(因为它与 $this
具有相同的 class)和 __get()
未被调用。
但是对于这段代码:
$a = new MyClass();
echo($a->x + $a->y + $a->z);
魔术方法 __get()
被调用两次,分别是 $a->x
和 $a->y
因为这些属性在 MyClass
class 之外的代码中不可见.
一般来说,如果class没有定义__get()
方法,当访问一个不可见的属性进行读取时,解释器会触发致命错误:
PHP Fatal error: Uncaught Error: Cannot access private property MyClass::$x
__get()
的存在抑制了错误。而是调用 __get()
并使用 returns 的值。如果 __get()
没有 return 值(不管为什么),将使用 NULL
代替(这是函数的标准 PHP 行为)。
我一直在阅读 PHP magic methods 并试图更好地理解它们。 PHP 手册中指出:
The overloading methods are invoked when interacting with properties or methods that have not been declared or are not visible in the current scope.
我已经阅读了 "not visible" 的含义:
The visibility of a property, a method or (as of PHP 7.1.0) a constant can be defined by prefixing the declaration with the keywords public, protected or private.
所以请考虑下面的 class:
<?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;
}
}
?>
考虑到上面关于 "visible" 和 "scope" 的片段,__get
魔法方法将在什么情况下被调用,什么时候不会被调用?
如果我实例化一个新对象:$myclass = new MyClass()
,会 $myclass->sum()
return 6
或 15
还是其他什么?
如果我调用 $myclass->x
、$myclass->y
、$myclass->z
,结果会是 4
、5
和 3
,因为x
和 y
在技术上不是 "visible"?
我假设调用 $myclass->w
将 return 0
无论范围如何,因为它从未被定义为 class 的 属性 开始是吗?
So considering the snippets above regarding "visible" and "scope", under what context will the
__get
magic method get invoked and when will it not?
当访问对象上不存在的 属性 时,或从不存在的范围访问 属性 时,将调用 __get
方法无障碍。例如,$obj->foo
将始终触发 __get
,而当从 class.
$obj->x
将触发 __get
If I instantiate a new object:
$myclass = new MyClass()
, will$myclass->sum()
return 6 or 15 or something else?
它将 return 6 (1 + 2 + 3
)。 $this->x
、->y
和 ->z
都可以从 class 中访问,因此这里不会触发 __get
方法。
What if I call the
$myclass->x
,$myclass->y
,$myclass->z
, will the results be 4, 5 and 3 since x and y are technically not "visible"?
正确。
I assume calling
$myclass->w
will return 0 regardless of scope since it wasn't ever defined as a property of the class to begin with, is that right?
正确,只要您没有明确地为 $myclass->w
赋值。
class MyClass {
private $x = 1;
protected $y = 2;
public $z = 3;
// ...
}
在 MyClass
class 的代码中,所有实例属性($x
、$y
和 $z
)都是可见的。 sum()
函数会看到它们,并且在使用它们时无需调用 __get()
.
如果代码试图访问同一 class 的另一个对象的 protected
或 private
属性,也会发生这种情况。例如:
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()
方法可以访问 $that
对象的所有属性(因为它与 $this
具有相同的 class)和 __get()
未被调用。
但是对于这段代码:
$a = new MyClass();
echo($a->x + $a->y + $a->z);
魔术方法 __get()
被调用两次,分别是 $a->x
和 $a->y
因为这些属性在 MyClass
class 之外的代码中不可见.
一般来说,如果class没有定义__get()
方法,当访问一个不可见的属性进行读取时,解释器会触发致命错误:
PHP Fatal error: Uncaught Error: Cannot access private property MyClass::$x
__get()
的存在抑制了错误。而是调用 __get()
并使用 returns 的值。如果 __get()
没有 return 值(不管为什么),将使用 NULL
代替(这是函数的标准 PHP 行为)。