Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/264.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
不同范围内的PHP魔术方法_Php_Oop_Scope_Magic Methods - Fatal编程技术网

不同范围内的PHP魔术方法

不同范围内的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手册中指出:

当与尚未声明或在当前范围内不可见的属性或方法交互时,将调用重载方法

我读过“不”的含义:

属性、方法或常量(从PHP7.1.0开始)的可见性可以通过在声明前面加上关键字public、protected或private来定义

请考虑下面的类:

<?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()
方法可以访问该对象的
$的所有属性(因为它属于同一类)