批改状态:合格
老师批语:能看明白就好, 知识学得越多就越有感觉了
//静态继承上下文class A{public function demo(){//.....}}class B extends A{public function demo(){parent::demo();}}## 上面便是一个继承上下文环境,若要改为静态继承上下文,直接在function前面加static 即可
//后期静态绑定:也叫延迟静态绑定## 后期静态绑定工作在静态继承上下文环境中//创建一个抽象类abstract class Creat{}//创建实现类class User extends Creat{public static function create(){return new static();}}class Product extends User{}var_dump(User::create());//输出 object(User)#1 (0) { }echo '<hr>';var_dump(Product::create());//输出 object(Product)#1 (0) { }## 方法里面如果用new self() 他返回的是实现该方法的类的类名 、 使用 new static() 他返回的是调用该方法的类的类名
<?php//我们可以把它上移到抽象类中## 注意:抽象类不能实例化,所以使用new self() 是错误的//解决方案:将类的定义与类的调用完全分离开。使用后期静态绑定方案 static 关键字将self替换掉//创建一个抽象类abstract class Creat{public static function create(){// return new self();return new static();// self 始终与定义该方法(属性)的类进行绑定// static 始终与调用该方法(属性)的类进行绑定}}//创建实现类class User extends Creat{}class Product extends User{}var_dump(User::create());//输出 object(User)#1 (0) { }echo '<hr>';var_dump(Product::create());//输出 object(Product)#1 (0) { }
<?php//魔术方法//语法:类中有一些方法总是使用双下划线开头,这就叫魔术方法// 调用者:由系统根据一定的条件或用户行为,自动调用/触发,禁止用户主动调用//构造方法:__construct(),是类的实例化过程中被自动调用,new的时候class Product{private $name;private $price;// 创建构造器:生成一个新对象public function __construct($name,$price){## $this是由PHP接管的对象,不能用户设置// $this = new self(); 此段省略即可## 初始化这个新对象:给这个新对象添加属性并赋值,或自动执行某些操作方法$this->name = $name;$this->price = $price;$this->white();## 返回这个刚创建并初始化的对象// return $this;## 隐式返回当前新生的类实例,不用显示返回,自动完成}public function white(){echo $this->name.':'.$this->price;}}//只需将参数传入到类中即可$product = new Product('上衣',500);
| 名称 | 描述 |
|---|---|
__get |
属性查询拦截器 |
__set |
属性设置拦截器 |
__isset |
属性检测拦截器 |
__unset |
属性销毁拦截器 |
注意:
__get可以单独使用,但是__set要同__get一起使用方能生效
<?phpclass User{private $name;private $price;public function __construct($name,$price){$this->name = $name;$this->price = $price;}// 属性查询拦截器:拦截转发器:将拦截下来的值根据设置转发出去或拦截下来public function __get($property){// return ($private === 'name') ? mb_substr($this->name,0,5) :'禁止访问';// 将传进来的参数前面加get 首字母大写 转发给对应的方法,专用于处理属性访问$method = 'get'.ucfirst($property);// 如果有该方法则转到,若没有返回没有该方法return method_exists($this,$method) ? $this->$method() : '没有该方法';}// 创建方法,返回name值private function getName(){// 只返回前五个字符return mb_substr($this->name,0,5);}}//传参$user = new User('联想笔记本电脑Y7000p',7999);echo $user->name;//输出 联想笔记本//访问原理,这里访问的不是name的值,而是被属性拦截器拦截下来经过处理转发到getName方法返回的数据
<?php//属性设置拦截器class User{private $name;private $price;// 创建构造器public function __construct($name, $price){$this->name = $name;$this->price = $price;}// 属性查询拦截器:拦截转发器:将拦截下来的值根据设置转发出去或拦截下来public function __get($property){// return ($private === 'name') ? mb_substr($this->name,0,5) :'禁止访问';// 将传进来的参数前面加get 首字母大写 转发给对应的方法,专用于处理属性访问$method = 'get'.ucfirst($property);// 如果有该方法则转到,若没有返回没有该方法return method_exists($this,$method) ? $this->$method() : '没有该方法';}// 创建方法,返回name值private function getName(){// 只返回前五个字符return mb_substr($this->name,0,5);}private function getPrice(){return $this->price;}//////////////////////////////////// 创建属性设置拦截器 set给两个值,第一个 属性名 第二个 新属性值public function __set($property,$value){$method = 'Set'.ucfirst($property);// 转发设置请求return method_exists($this,$method) ? $this->$method($value) : null;}// 创建属性设置方法public function setName($value){// 清一下空白字符$this->name = trim($value);}public function setPrice($value){$this->price = $value * 0.2;}}$user = new User('联想笔记本电脑', 7999);echo $user->name; //输出联想笔记本echo $user->price;//输出 7999echo '<hr>';//更新name值$user->name = ' macbook ';//更新price值$user->price = 121121;echo $user->name; //输出 macbo 因为__get拦截器只返回五个字符echo $user->price;//输出 24224.2
<?php//属性设置拦截器class User{private $name;private $price;// 创建构造器public function __construct($name, $price){$this->name = $name;$this->price = $price;}/* * * * * * * * * * * * */// 给一个属性查询拦截器 供销毁测试public function __get($property){$method = 'get' . ucfirst($property);// 先检测有没有该方法return method_exists($this, $method) ? $this->$method() : 'djdsdhjkds';}private function getName(){return $this->name;}private function getPrice(){return $this->price;}/* * * * * * * * * * * * */// 属性检测拦截器public function __isset($property){// 只让检测name值return $property === 'name' ? isset($this->name) : false;}//属性销毁拦截器public function __unset($property){// 只让删除name值$property === 'name' ? $this->name = null : null;}}$user = new User('联想笔记本电脑', 7999);//检测一下是否存在var_dump(isset($user->name)); //输出 true//检测pricevar_dump(isset($user->price)); //输出 falseecho $user->price;echo $user->name;echo '<hr>';//删除name值unset($user->name);echo $user->name; //成功//删除price值unset($user->price);echo $user->price; //正常输出 删除失败
<?php// 方法拦截器// __call(), __callSTatic()// 就是创建一个方法class User{//创建方法拦截器public function __call($name, $arguments){// implode 将数组转为字符串printf('方法名:%s --- 参数:%s ', $name, implode(',', $arguments));}// 创建静态方法拦截器public static function __callStatic($name,$arguments){printf('方法名:%s --- 参数:%s ', $name, implode(',', $arguments));}}$user = new User();$user->demo(1, 2, 3, 4); // 输出 方法名:demo --- 参数:1,2,3,4echo '<hr>';//静态访问User::demo(1,2,3,3) // 输出 方法名:demo --- 参数:1,2,3,3
<?php//利用构造器 方法拦截器实现数据库查询class Datebase{// 数据库链接protected $db;//表名protected $table;//字段列表protected $field;//查询条数protected $limit;//构造方法实现数据库链接public function __construct($dsn, $username, $password){// 转发给connect$this->connect($dsn, $username, $password);}//创建PDO链接private function connect($dsn, $username, $password){// 用PDO方式链接$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 getSql(){return sprintf('SELECT %s FROM %s LIMIT %s', $this->field, $this->table, $this->limit);}// 创建查询public function select(){return $this->db->query($this->getSql())->fetchAll(PDO::FETCH_ASSOC);}}class DB{// 传参 静态方法拦截器public static function __callStatic($name, $arguments){// TODO: Implement __callStatic() method.$dsn = 'mysql:host=localhost;dbname=php11.edu';$datebase = new Datebase($dsn,'php11.edu','php11.edu');return call_user_func([$datebase,$name],...$arguments);}}$res = DB::table('staffs')->field('id,name,age')->limit(5)->select();print_r($res);//输出Array//(// [0] => Array// (// [id] => 1// [name] => 侯亮平// [age] => 40// )//// [1] => Array// (// [id] => 2// [name] => 祁同伟// [age] => 46// )//// [2] => Array// (// [id] => 3// [name] => 高育良// [age] => 57// )//// [3] => Array// (// [id] => 4// [name] => 李达康// [age] => 51// )//// [4] => Array// (// [id] => 5// [name] => 沙瑞金// [age] => 56// )////)
方法拦截器中 若使用
__set必须先创建__get;
数据库案例 学了数据库后终于可以看明白了~~
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号