php之魔术方法 __set() __get() __isset() __unset() __call() __callStatic() __invoke() __toString()
__set()与__get()
当一个类里面,属性被设置为私有属性时,这个属性是不能在外部被访问的。那么当我们又想在外部访问时该怎么办呢,我们可以用方法来实现。举例如下:
1 class Test 2 { 3 private $abc; 4 5 public function setAbc($val) 6 { 7 $this->abc=$val; 8 } 9 10 public function getAbc() 11 { 12 return $this->abc; 13 } 14 } 15 16 $test=new Test(); 17 $test->setAbc("this is abc!"); 18 var_dump($test->getAbc());
以上这个代码就可以实现在外部访问私有属性,但是如果我们的私有属性不只一个时,假如还有一个ABD,那么我们要外部访问的话,还需要再写一个专门针对ABD的方法,这样就显得很麻烦了。如何实现多个私有属性访问,而又不用一个个去写方法呢?这时候 __set跟__get就派上用场了。上面的代码就可以这样写了,举例如下:
1 class Test 2 { 3 private $abc; 4 private $abd; 5 6 public function __set($var, $val) 7 { 8 $this->$var=$val; 9 } 10 11 public function __get($var) 12 { 13 return $this->$var; 14 } 15 } 16 17 $test=new Test(); 18 $test->abc="this is private abc"; 19 echo $test->abc;
__set($var,$val):有两个参数,第一个是属性名,第二个是属性值。
__get($var):只有一个参数,属性名。
以上这段代码中,当我们给私有属性赋值时,它就会自动去执行__set()这个方法,同样的,当我们要获取属性值时,它也会自动去执__get()这个方法。访问的语法跟访问公有属性语法一样。
__isset()
__isset($var):是用来检测私有属性是否存在。只有一个参数,属性名。我们用代码来举例说明,如下:
1 class Test 2 { 3 private $abc='abc'; 4 } 5 $test=new Test(); 6 var_dump(isset($test->abc));
上面这段代执行的结果是返回布尔FALSE,虽然类里面有abc这个属性,但是它是私有属性,是不能被外部所访问的,所以返回布尔FALSE。如果要测试,我们可以在类里面加上__isset()方法,举例如下:
1 class Test 2 { 3 private $abc='abc'; 4 5 public function __isset($var) 6 { 7 return isset($this->$var)?true:false; 8 } 9 } 10 $test=new Test(); 11 var_dump(isset($test->abc));
上面这段代码执行的结果是返回布尔TRUE,当外部的isset($test->abc) 检测不到abc时,它就会自动去执行类里面的__isset()这个方法,然后返回结果。
__unset()
__unset($var):用来删除私有属性,只有一个参数,属性名。举例如下:
1 class Test 2 { 3 private $abc='abc'; 4 5 public function __unset($var) 6 { 7 echo "__unset:".$var; 8 unset($this->$var); 9 } 10 } 11 $test=new Test(); 12 unset($test->abc);
上面这段代码中,当外部的unset($test->abc)检测不到abc时,就会去执行类里面的__unset()这个方法,然后删除属性。
__call() __callstatic()
__call($func,$arguments):为了避免调用的方法不存在而出错,我们可以用这个魔术方法__call()来实现。这个魔术方法有两个参数,一个是你调用的方法名:func,一个是你调用的方法里面的参数:arguments。
__callstatic($func,$arguments):为了避免调用的静态方法不存上而出错,我们就可以用这个魔术方法来实现,跟__call()是一样的,只不过一个是公有方法,一个有私有方法。现用代码举例如下:
1 class Test 2 { 3 public function __call($func,$arguments) 4 { 5 echo "$func"; 6 print_r($arguments); 7 } 8 } 9 10 $test= new Test(); 11 $test->go(1,2);
这段代码返回的结果是,调用的方法名:go。go方法所带的参数:1跟2,不过这个是以数组的形式存储的,不管所带的参数是一个还是两个都是以数组存储的。我们在类里面是没有定义go这个方法的,所以当我们在外部调用时,发现没有go这个方法时,就会自动去执行类里面的__call()。
1 class Test 2 { 3 public static function __callStatic($func,$arguments) 4 { 5 echo "$func"; 6 print_r($arguments); 7 } 8 } 9 10 Test::go(1,2);
上面这段代码返回的结果跟__call()的示例代码是一样的,只不过代码不一样,一个不是static方法,一个是static方法,外部调用的语法也不一样。static过之后,就表示这个方法是属于类的,而不是属于对像的。
__invoke()
__invoke($arg):当一个对象以函数的形式被调用时,就用自动去执行__invoke()这个方法。举例代码如下:
class Test { public function __invoke($arg) { echo "$arg"; } } $test= new Test(); $test("this is class,but as method!");
__toString()
__toString():当一个对像被打印时,就会去调用这个魔术方法。这个魔术方法是没有参数的。方法内要返回一个结果。举例代码如下:
class Test { public function __toString() { return "echo class"; } } $test= new Test(); echo $test;

浙公网安备 33010602011771号