博客列表 >后期静态绑定与拦截器

后期静态绑定与拦截器

我是郭富城
我是郭富城原创
2020年05月04日 16:50:26557浏览

后期静态绑定与拦截器

1. 实例演示后期静态绑定的原理与实现

1.1 原理

  • 后期静态绑定的别名:延迟静态绑定
  • 工作在静态继承上下文的环境中
  • static 不应该是用来定义静态变量方法和属性的么?学习完了后期静态绑定,可以说了刷新了我的钛合金的火眼金睛,原来 static 还可以这样子用!static:: 不再被解析为定义当前方法所在的类,而是在实际运行时计算的。也可以称之为“静态绑定”,因为它可以用于(但不限于)静态方法的调用。

    使用 self:: 或者 __CLASS__ 对当前类的静态引用,取决于定义当前方法所在的类:
    在这里 static 相当于 selfparent 一样的关键字,用来调用方法,不过与 self 不同,static 调用的类并不一定是静态属性和静态方法,这点上看更接近于parent这个关键字的用法。

1.2 用法

  1. <?php
  2. class A {
  3. public static function who() {
  4. echo __CLASS__;
  5. }
  6. public static function test() {
  7. static::who(); // 后期静态绑定从这里开始
  8. }
  9. }
  10. class B extends A {
  11. public static function who() {
  12. echo __CLASS__;
  13. }
  14. }
  15. B::test();

2.实例演示属性重载/拦截器

  • 属性重载:如果使用一个不存在的(无权访问)属性,就会去自动调用类中预先定义好的某个方法以处理数据;

  • 取值:\$v1 = 对象->属性;

  • 赋值:对象->属性 = XX 值;

  • 判断是否存在:isset(对象->属性;)

  • 销毁:unset(对象->属性;)

    以上四种方法称之为魔术方法,__GET(),_SET(),isset(),unset()

  1. <?php
  2. class Person{
  3. public $name;
  4. public $sex;
  5. private $age; //年龄私有化,类外不能直接访问这个属性
  6. function __construct($name='', $sex='', $age){
  7. $this->name = $name;
  8. $this->sex = $sex;
  9. $this->age = $age;
  10. }
  11. private function __get($propertyName){ //这里要用private修饰,防止类外部调用
  12. if($propertyName == 'age'){
  13. return $this->age;
  14. }
  15. }
  16. }
  17. $p = new Person('朱老师', '男',43);
  18. $v1 = $p->name;
  19. $v2 = $p->sex;
  20. $v3 = $p->age; //自动调用了__get()方法获取私有属性age(函数定义里面返回)
  21. echo "name=$v1, sex=$v2, age=$v3";
  22. ?>

也就是说,拦截器实质上就是拦截报错,优先处理这些未定义或者不存在或者无法访问的属性`

3.实例演示方法重载/拦截器

  • 当对一个对象不存在的实例方法进行“调用”时,会自动调用类中的__call()这个魔术方法;

  • 当对一个类不存在的静态方法进行“调用”时,会自动调用类中的__callstatic()这个魔术方法。

  1. <?php
  2. class A{
  3. //当对这个类的对象不存在的实例方法进行调用时,会自动调用本方法
  4. //这个方法必须带2个形参:
  5. //$methodName:表示要调用的不存在的方法名;
  6. //$argument:表示要调用该不存在的方法时,所使用的实参数据,是一个数组。
  7. function __call($methodName, $argument){
  8. //echo "__call被调用了!";
  9. echo $methodName . "()方法不存在!";
  10. }
  11. }
  12. $a = new A();
  13. $a->f1(); //不存在的方法,但经过处理
  14. ?>

当对一个类不存在的静态方法进行“调用”时,会自动调用类中的__callstatic()这个魔术方法。和上面的处理类似。

4.总结

在 laravel 的源码,还依稀记得很多static 关键字的用法,static 不应该是用来定义静态变量方法和属性的么?学习完这节课的知识发现有点任督二脉被打通的感觉了。

PHP 中的”重载”与其它绝大多数面向对象语言不同,只是他们都是用的相同的名词而已。传统的”重载”是用于提供多个同名的 类方法,但各方法的参数类型和个数不同。 PHP 所提供的”重载”(overloading)是指动态地”创建”类属性和方法。当调用当前环境下未定义或不可见的类属性或方法时,重载方法会被调用。是通过魔术方法(magic methods)来实现的。通俗一点来说,重载在 php 中的含义是指,当一个对象或类使用其未定义或不可见的属性和方法时,其中的一些“处理机制”。

声明:本文内容转载自脚本之家,由网友自发贡献,版权归原作者所有,如您发现涉嫌抄袭侵权,请联系admin@php.cn 核实处理。
全部评论
文明上网理性发言,请遵守新闻评论服务协议