博主信息
JiaJieChen
博文
65
粉丝
3
评论
5
访问量
46341
积分:0
P豆:132

PHP:oop->重载之set/get/call/callStatic,oop事件委托,数据库查询构造器

2021年05月10日 23:22:13阅读数:566博客 / JiaJieChen/ PHP

PHP:oop->重载之set/get/call/callStatic,oop事件委托,数据库查询构造器

魔术方法含义
__set()__set(name,value),第一个值是成员属性名称,第二个值是成员属性值
__get()__get(name),第一个值是成员名称或者成员属性值
  • php重载 PHP所提供的重载(overloading)是指动态地创建类属性和方法。我们是通过魔术方法(magic methods)来实现的。

  • 当调用当前环境下未定义或不可见的类属性或方法时,重载方法会被调用。

①重载之__set()

在类中,如果实列未创建的成员属性会自动访问__set方法__set(name,value),第一个值是成员属性名称,第二个值是成员属性值

②重载之__get()

在类中,如果输出未创建的成员属性会自动访问__get()方法__get(name),第一个值是成员名称或者成员属性值

③属性拦截

以上我们得知,如果我们随意创建一个类中没有的成员属性,会自动调用set/get方法,这样的话就无法保护到私有成员或者受保护的成员,因此一般我们会在set/get里面建立一个中转站把获取到的数据传入到一个私有的方法中,来进行内容过滤,以下我们来过滤身份证信息。

判断身份证信息超过18位输出不合法

身份证信息判断未18位后,输出前5位,后4位

代码块

<?php//php重载 之 属性重载  属性拦截器use Credit as GlobalCredit;class Credit {       //私有成员属性    private $idNum;    private $age;    //构造器    public function __construct($idNum,$age)    {        $this->idNum = $idNum;        $this->age = $age;    }    //建立 set / get 中转站 把获取到的数据转入一个私有的方法中过滤    public function __set($name, $value)    {        //根据属性名称$name 生成对应的属性访问私有接口的名称        // ucfirst — 将字符串的首字母转换为大写         $method = "set" . ucfirst($name) ;        //method_exists — 检查类的方法是否存在 第一个值传递对象 第二个值传递对象中的方法         return  method_exists($this,$method) ? $this->$method($name,$value) : null;    }    //设置set 私立方法进行内容过滤    private function setIdNum($name,$value)    {        //property_exists — 检查对象或类是否具有该属性 第一个值是类,第二个值是属性名称        if (property_exists($this,$name)) {            //判断属性值是否等于18位,不等于的话返回null            return $this->$name = strlen($value) == 18 ? $value : null;        }    }    public function __get($name)    {        $method = "get" . ucfirst($name);        return method_exists($this,$method) ? $this->$method($name) : null;    }    private function getIdNum($name)    {        //empty — 检查一个变量是否为空         if (property_exists($this,$name) && !empty($this->$name)) {            //返回前面5位数字 和 后4位数字            return mb_substr($this->$name,0,5) . "......" . mb_substr($this->$name,-4,4);        }else {            return "身份证信息不合法";        }    }}//在外部实例化Credit类$User = new Credit("360723198905010042",32);$User->idNum = "360723199905050012";echo $User->idNum;// echo $User->idNums;

二.方法重载

魔术方法之call()和callStatic()
__call()方法:当对象访问不存在的方法名称时,此方法自动调用。

  • 调用示例:public function __call($name,$argument){}
    注意:访问控制关键字必须为public;必须有两个参数:对象访问的方法名称($name)、方法包含的参数($argument ==> 自动转换成数组)。

__callStatic()方法:当对象访问不存在的静态方法名称时,此方法自动调用。

  • 调用示例:public static function callStatic($name,$argument){}
    注意:同
    call();此方法为静态方法(static)。

魔术方法含义
__call($name,$argument)第一个参数是对象访问的方法名称,第二个参数是方法包含的参数自动转换成数组
__callstatic()同__call();此方法为静态方法(static)

①__call()

当我们调用没有创建的方法的时候 会自动调用__call方法 和属性调用__set一样

②__callstatic()

__callStatic 调用未定义静态方法的时候触发,参数和__call一样

代码块

<?php/**方法重载(方法拦截器)*|__call($name,$argument)|*第一个参数是对象访问的方法名称,*第二个参数是方法包含的参数自动转换成数组*/class User {    public  function __call($name, $arguments)    {        return "方法名称是:$name,方法属性是:".implode(",",$arguments);    }    public static function __callStatic($name, $arguments)    {        return "静态方法名称是:$name,静态方法属性是:".implode(",",$arguments);    }}//当我们调用没有创建的方法的时候 会自动调用__call方法 和属性调用__set一样echo (new User)->list("admin@qq.com","13456");echo "<hr>";echo  User::demo("徐峥","泰囧","港囧");

三.事件委托

  • 事件委托 : 访问类中不存在的成员方法时, 会被魔术方法拦截, 把请求重定向到别的类的成员方法来处理

代码块

<?php// 事件委托 : 访问类中不存在的成员方法时, 会被魔术方法拦截, 把请求重定向到别的类的成员方法来处理//被委托的类class User{    //CALL 普通未定义方法    public function write(...$arr)    {        printf("调用方法%s(),参数有:[%s]<br>",__METHOD__,implode(",",$arr));    }    //CALLSTATIC 普通未定义静态方法    public static function fetch(...$arr)    {        printf("调用静态方法%s(),参数有:[%s]<br>",__METHOD__,implode(",",$arr));    }}//工作类class work{    //如果希望一个属性可以在多个类中共享, 可以将该属性放到某个类中的构造函数中    private $user;    public function __construct( $User)    {        $this->user = $User;    }    //创建未定义方法的时候委托到User类里面的方法来处理    public function __call($method,$arr)    {        //用异步请求的方式进行委托,这样可以优化性能        call_user_func([$this->user,"write"],...$arr);    }    public static function __callStatic($method, $arr)    {        call_user_func(["user","fetch"],...$arr);    }}//把委托类传递到工作类的成员属性$User中$user = new User();$Work = new work($user);$Work->list(50,60,70);work::list(1,2,3);

三.数据库查询构造器

代码块

<?php/** * 事件委托 : 数据库查询构造器 * Db::table()->field()->where()->limit()->select()->toArray(); *  *///被委托的类class Query{    protected $db;//pdo连接对象    protected $table;    protected $field;    protected $limit;    //连接数据库    private function connect($dns,$username,$password)    {        $this->db = new PDO($dns,$username,$password);    }    //构造器 传递参值    public function __construct($dns,$username,$password)    {        $this->connect($dns,$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;    }    //sql访问语句    public function getSQL()    {        return sprintf("SELECT %s FROM %s LIMIT %d",$this->field,$this->table,$this->limit);    }    //执行查询    public function select()    {        return $this->db->query($this->getSQL())->fetchAll(PDO::FETCH_ASSOC);    }}//工作类class Db{    static function __callStatic($method,$args)    {        $dns = "mysql:host=localhost;dbname=zwz";        $username = "root";        $password = "a123456";        $query = new Query($dns,$username,$password);        //直接委托给Query        return call_user_func([$query,$method],...$args);    }}$user = Db::table()->field()->limit()->select();echo '<pre>';print_r($res);
批改状态:未批改

老师批语:

版权申明:本博文版权归博主所有,转载请注明地址!如有侵权、违法,请联系admin@php.cn举报处理!

全部评论

文明上网理性发言,请遵守新闻评论服务协议

条评论