1.静态继承上下文
//静态继承上下文
class A
{
public function demo()
{
//.....
}
}
class B extends A{
public function demo()
{
parent::demo();
}
}
## 上面便是一个继承上下文环境,若要改为静态继承上下文,直接在function前面加static 即可
2.后期静态绑定
//后期静态绑定:也叫延迟静态绑定
## 后期静态绑定工作在静态继承上下文环境中
//创建一个抽象类
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) { }
3.魔术方法
<?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);
4. 属性拦截器
名称 | 描述 |
---|---|
__get |
属性查询拦截器 |
__set |
属性设置拦截器 |
__isset |
属性检测拦截器 |
__unset |
属性销毁拦截器 |
注意:
__get
可以单独使用,但是__set
要同__get
一起使用方能生效
4.1 属性查询拦截器
<?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);
}
}
//传参
$user = new User('联想笔记本电脑Y7000p',7999);
echo $user->name;
//输出 联想笔记本
//访问原理,这里访问的不是name的值,而是被属性拦截器拦截下来经过处理转发到getName方法返回的数据
4.2 属性设置拦截器
<?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;//输出 7999
echo '<hr>';
//更新name值
$user->name = ' macbook ';
//更新price值
$user->price = 121121;
echo $user->name; //输出 macbo 因为__get拦截器只返回五个字符
echo $user->price;//输出 24224.2
4.3 属性检测/销毁拦截器
<?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
//检测price
var_dump(isset($user->price)); //输出 false
echo $user->price;
echo $user->name;
echo '<hr>';
//删除name值
unset($user->name);
echo $user->name; //成功
//删除price值
unset($user->price);
echo $user->price; //正常输出 删除失败
5. 方法拦截器
<?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,4
echo '<hr>';
//静态访问
User::demo(1,2,3,3) // 输出 方法名:demo --- 参数:1,2,3,3
6. 小案例:利用构造器和拦截器实现链接数据库并查询
<?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
// )
//
//)
7. 总结
方法拦截器中 若使用
__set
必须先创建__get
;
数据库案例 学了数据库后终于可以看明白了~~