PHP 属性拦截器与方法拦截器
PHP 属性拦截器
当从类的外部,访问类中不存在或无权限访问的属性的时候 会自动调用它
__get()
读取一个不可访问的属性/不存在的属性时会自动调用__set()
设置一个不可访问的属性/不存在的属性时会自动调用__isset()
对一个不可访问的属性进行调用isset()
时自动调用__unset()
对一个不可访问的属性进行调用unset()
时自动调用实例演示方法拦截器的
__isset()
与__unset()
<?php
class Test{
private $val = 'private';
public function __get($value){
$method = 'get'.ucfirst($value);
return method_exists($this, $method)?$this->$method():"{$value}属性不存在";
}
public function __set($value, $setValue){
$method = 'set'.ucfirst($value);
echo method_exists($this, $method)?$this->$method($setValue):"{$value}属性不存在";
}
public function __isset($value){
return isset($this->$value);
}
public function __unset($value){
unset($this->$value);
}
//为私有成员提供访问接口 来过滤访问请求
private function getVal(){
return "不可访问的属性值:{$this->val}";
}
private function setVal($setValue){
$this->val = $setValue;
return "设置了不可访问的属性值:{$this->val}";
}
}
$test = new Test();
//读取一个不可访问的属性/不存在的属性
echo $test->val;
echo '<br>';
echo $test->aa;
echo '<hr>';
//设置一个不可访问的属性/不存在的属性
$test->val = 'public';
echo '<br>';
$test->aa = 'xxx';
echo '<hr>';
echo 'isset()调用__isset():';
var_dump(isset($test->val));
echo '<hr>';
echo 'unset()调用__unset():';
unset($test->val);
echo $test->val;
PHP 方法拦截器
- 当从类的外部,访问类中不存在或无权限访问的方法的时候 会自动调用它
__call()
拦截一般方法__callStatic()
拦截静态方法
<?php
class Test{
//私有方法 类外不可访问
private function getClassInfo(){
return __CLASS__;
}
//私有静态方法
private static function getMethodInfo(){
return __METHOD__;
}
//方法拦截器 访问类中的方法
public function __call($method, $args){
return (method_exists($this, $method))?$this->$method():'此方法不存在';
}
//静态方法拦截器 访问类中的静态方法
public static function __callStaic($method, $args){
return (method_exists(self, $method))?self::$method():'此方法不存在';
}
}
$test = new Test();
echo $test->getClassInfo();
echo '<hr>';
echo $test->getMethodInfo();
PHP 方法委托—跨类访问
- 使用方法拦截器将不在当前类中存在的方法重定向到另一个类中
- 使用回调方式调用另一个类中的方法
<?php
class ATest{
//私有方法 类外不可访问
private function getClassInfo(){
return __CLASS__;
}
//私有静态方法
private static function getMethodInfo(){
return __METHOD__;
}
//方法拦截器 访问类中的方法
public function __call($method, $args){
return (method_exists($this, $method))?$this->$method():'此方法不存在';
}
//静态方法拦截器 访问类中的静态方法
public static function __callStaic($method, $args){
return (method_exists(self, $method))?self::$method():'此方法不存在';
}
}
class BTest{
//事件委托时 重定向到其它类
private $test;
public function __construct(ATest $Atest){
$this->test = $Atest;
}
//方法拦截器 访问类中的方法 重定向到其他类中访问方法
public function __call($method, $args){
//使用回调方式调用方法
return call_user_func([$this->test, $method], $args);
}
//静态方法拦截器 访问类中的静态方法 重定向到其他类中访问方法
public static function __callStaic($method, $args){
//使用回调方式调用方法
return call_user_func(['Atest', $method], $args);
}
}
$atest = new ATest();
$btest = new BTest($atest);
echo $btest->getClassInfo();
echo '<hr>';
echo $btest->getMethodInfo();
PHP 方法委托/方法拦截器实战
- 实例演示查询构造器中的
inset()
、update()
、delete()
方法
<?php
class query{
//连接对象
protected $bd;
//数据表
protected $table;
//字段列表
protected $field;
//记录数量
protected $limit;
//条件
protected $condition;
//构造方法:连接数据库
public function __construct($dsn, $username, $password){
$this->connect($dsn, $username, $password);
}
//连接数据库
private function connect($dsn, $username, $password){
$this->bd = 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 condition($condition){
$this->condition = $condition;
return $this;
}
//生成数据库操作语句
protected function getSql($operation){
switch(strtolower($operation)){
case 'select':
$sql = sprintf('SELECT %s FROM %s LIMIT %s', $this->field, $this->table, $this->limit);
break;
case 'insert':
$sql = sprintf('INSERT %s SET %s', $this->table, $this->field);
break;
case 'update':
$sql = sprintf('UPDATE %s SET %s WHERE %s', $this->table, $this->field, $this->condition);
break;
case 'delete':
$sql = sprintf('DELETE FROM %s WHERE %s', $this->table, $this->condition);
break;
}
return $sql;
}
//执行
public function execute($operation){
switch(strtolower($operation)){
case 'select':
$result = $this->bd->query($this->getSql($operation))->fetchAll(PDO::FETCH_ASSOC);
break;
case 'insert':
case 'update':
case 'delete':
$result = $this->bd->exec($this->getSql($operation));
break;
}
return $result;
}
}
//数据库操作类
class DB{
//静态方法委托
public static function __callStatic($name, $args){
//获取到查询类的对象
$dsn = 'mysql:host=localhost;dbname=db_users';
$username = 'root';
$password = 'root';
$query = new query($dsn, $username, $password);
//直接跳转到query类中的具体方法来调用
return call_user_func([$query, $name], ...$args);
}
}
//查询
$result = DB::table('user')->field('id,username,age')->limit(3)->execute('select');
print_r($result);
echo '<hr>';
//插入
$username = 'pdo';
$password = md5('pdo');
$age = 10;
$insertInfo = sprintf("username='%s', password='%s', age='%d'", $username, $password, $age);
$result = DB::table('user')->field($insertInfo)->execute('insert');
echo "新增了{$result}条数据<br>";
$updateInfo = sprintf("username='%s', password='%s', age='%d'", $username, $password, $age);
$condition = 'id=61';
$result = DB::table('user')->field($updateInfo)->condition($condition)->execute('update');
echo "更新了{$result}条数据<br>";
$condition = 'id=61';
$result = DB::table('user')->condition($condition)->execute('delete');
echo "删除了{$result}条数据<br>";