批改状态:合格
老师批语:不错
后期静态绑定工作在: 静态继承上下文的环境中
new self替换为new staticself: 与定义类绑定static: 与调用类绑定
不要再使用parent
演示:
<?php// 动态绑定静态成员的调用上下文class Ba{// 静态方法: 允许重写public static function getpp(){return '当前调用方法: ' . __METHOD__;}public static function dupp(){// 后期静态绑定, 使用关键字: static, 将self 替换掉// return new self();// self: 与定义类绑定// static: 与调用类绑定return static::getpp();}}class Con extends Ba{// 重写父类中的静态方法: index()public static function getpp(){return '当前调用方法: ' . __METHOD__;}}// 客户端echo Ba::dupp();echo '<hr>';echo Con::dupp();
效果图:

演示:
<?php// 拦截器: 属性拦截器, 方法拦截器// 使用场景: 当用户访问一个不存在的或无权限访问属性/方法时, 自动调用(属性拦截器实质也是一个方法)// 访问: 包括二个操作:就是读和写, 或者称为: 查询和设置// 属性拦截器: __set(), __get(), __isset(), __unset()class Staffs{private $name;private $salary;public function __construct($name, $salary){$this->name = $name;$this->salary = $salary;}// 1. 属性查询拦截器// $property 参数,要获取的属性名称public function __get($property){// return $property === 'name' ? $this->name : '无权访问';// 拦截转发器// 1. 先事先约定一些方法专用于处理属性访问$method = 'get' . ucfirst($property);// 2. 转发访问请求return method_exists($this, $method) ? $this->$method() : null;}private function getName(){return $this->name;}private function getSalary(){return $this->salary;}// 2. 属性设置拦截器public function __set($property, $value){$method = 'set' . ucfirst($property);// 转发访问请求return method_exists($this, $method) ? $this->$method($value) : null;}private function setName($value){$this->name = trim($value);}private function setSalary($value){if ($value === null) unset($this->salary);else $this->salary = $value;}// 3. 属性检测拦截器public function __isset($property){return $property === 'name' ? isset($this->name) : false;}// 4. 属性销毁拦截器public function __unset($property){if ($property === 'salary') {$method = 'set' . ucfirst($property);// 转发访问请求if (method_exists($this, $method)) return $this->$method(null) ;}}}// 客户端$staffs = new Staffs('阮总', 98000);// 访问了一个无访问权限的类属性echo '姓名: ' .$staffs->name .'<br>';echo '工资: ' .$staffs->salary;echo '<hr>';$staffs->name = '冯总';$staffs->salary = 96000;echo '姓名: ' .$staffs->name .'<br>';echo '工资: ' .$staffs->salary;echo '<hr>';echo isset($staffs->name) ? '存在 <br>' : '不存在';echo isset($staffs->salary) ? '存在 <br>' : '不存在';echo '<hr>';unset($staffs->name);echo $staffs->name;unset($staffs->salary);echo $staffs->salary;
效果图:

演示:
<?php// 方法拦截器, 其实比属性拦截器更有用// __call(), __callStatic()class User{// 方法拦截器public function __call($name, $arr){printf('方法名: %s , 参数: [%s]', $name, implode(', ', $arr));}// 静态方法拦截器public static function __callStatic($name, $arr){printf('静态方法名: %s , 参数: [%s]', $name, implode(', ', $arr));}}$user = new User();$user->khong(8, 9, 7, 8);echo '<br>';User::no(8,8,8,8);
效果图:

<?php// 方法拦截器实战:数据库查询构造器的实现class Query{// 数据库连接protected $db;// 表名protected $table;// 字段列表protected $field;// 查询数量protected $limit;// 查询条件protected $where;// 构造方法完成数据库的连接public function __construct($dsn, $username, $password){$this->connect($dsn, $username, $password);}// PDO连接数据库的方法private function connect($dsn, $username, $password){$this->db = new PDO($dsn, $username, $password);}public function table($table){$this->table = $table;return $this;}public function field($field){$this->field = $field;return $this;}public function limit($limit){$this->limit = $limit;return $this;}public function id($id){$this->id = $id;return $this;}public function getSql(){return sprintf('SELECT %s FROM %s WHERE id > %u LIMIT %s', $this->field, $this->table, $this->id, $this->limit);}public function select(){return $this->db->query($this->getSql())->fetchAll(PDO::FETCH_ASSOC);}}class DB{// 这里使用的静态方法拦截器public static function __callStatic($name, $arguments){$dsn = 'mysql:host=localhost;dbname=phpedu';$query = new Query($dsn, 'root', 'root');// return call_user_func(函数/方法, 函数参数列表)// return call_user_func_array(函数/方法, 函数参数数组)return call_user_func([$query, $name], ...$arguments);}}$res=DB::table('staffs')->field('id, name, position')->id(3)->limit(5)->select();print_r($res);
效果图:

总结:这个拦截器、拦截器是第一次接触,挺蒙的,刷了3-4遍视频才看明白——只是看明白,要撑握只能后面慢慢练习了。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号