Correcting teacher:天蓬老师
Correction status:qualified
Teacher's comments:拦截器, 静态绑定, 都是开发中最常用的功能, 一定要深刻理解并掌握
应用场景:在继承范围内引用静态调用的类
原理 :
当进行静态方法调用时,该类名就是明确指定的那个(通常在::运算符左侧部分);当进行非静态方法调用时,即为该对象所属的类。
实例:
class A {
public static function who(){
echo __CLASS__;
}
public static function test(){
// self::who()
// 如果是用self的话,就会调用父类的方法
static::who();
}
}
class B extends A {
public static function who(){
echo __CLASS__;
}
}
B::test();
输出:B
通过结果我们可以看到,是调用B类里面的方法,这都是因为采用了static
后期静态绑定,可以将类的的绑定延迟。
当用户访问一个不存在或无权限的属性时,拦截器会拦截下来,进行处理。
序列 | 名称 | 作用 |
---|---|---|
1 | _set() |
属性设置拦截器 |
2 | _get() |
属性查询拦截器 |
3 | __isset() |
属性检测拦截器 |
4 | _unset() |
属性销毁拦截器 |
示例:
class Fruit
{
private $name;
private $price;
private $taxRate = 0.8;
public function __construct($name,$price)
{
$this->name = $name;
$this->price = $price;
}
// 拦截器
// 注意__get名称
public function __get($property)
{
// return $this->$property;
// return $property === 'name' ? $this->name : '无权访问';
// 拦截转发器
$method = 'get' . ucfirst($property);
return method_exists($this,$method) ? $this-> $method() : null;
}
public function getName()
{
// substr字符串截断
return mb_substr($this->name,0,10).'...';
}
public function getPrice()
{
return $this->price + $this * $this->taxRate;
}
// 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 setPrice($value)
{
if($value === null)unset($this->price);
else $this->price = $value * (1-$this->taxRate);
}
// 3.属性检测拦截器
public function __isset($property)
{
return $property == 'name' ? isset($this->name):false;
}
// 属性拦截器
public function __unset($property)
{
return $property == 'price' ? isset($this->price):false;
}
}
$product = new Fruit('苹果',12);
echo $product->name;
echo $product->price;
echo '<hr>';
$product->name = '亿辆 车 发的';
$product->price = 20000;
echo $product->name;
echo $product->price;
echo '<hr>';
echo isset($product->name) ? '存在' : '不存在';
echo isset($product->price) ? '存在' : '不存在';
echo '<hr>';
unset($product->name);
echo $product->price;
输出
苹果...12.8
亿辆 车 发的...4000.8
存在不存在
4000.8
通过属性拦截器我们可以看到,当用户对一些敏感属性进行设置,查询,销毁时,我们可以拦截下来,进行处理。
static
的static
的示例:
class User
{
// 方法拦截器
public static function __call($name, $arguments)
{
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);
User::demo(5,234,4);
输出:
方法名:demo,参数:[1,2,3,4]
静态方法名:demo,参数:[5,234,4]
今天的学习后期静态绑定与拦截器,后期静态绑定可以理解为,将方法的类名进行后期绑定,就可以绑定到继承的类当中。拦截器可以对用户的一些非法设置进行处理,防止用户篡改数据,带来不必要的麻烦。在项目当中一定很有用。