博客列表 >魔术方法,回调函数,与链式调用 2019年10月8日

魔术方法,回调函数,与链式调用 2019年10月8日

错过博客
错过博客原创
2019年10月11日 16:00:58433浏览

1.__get(),__set(),__isset(),__unset(),__call()等魔术方法详解

<?php
/**
 * Created by PhpStorm.
 * User: Administrator
 * Date: 2019/10/10
 * Time: 15:18
 */
namespace _1008;
class Demo
{
    private $name;
    private $sex;
    protected $age;
    public function __construct($name,$sex,$age)
    {
        $this->name=$name;
        $this->sex=$sex;
        $this->age=$age;
    }
    /**
     * 访问类中的属性时,不存在,或者说无权,自动调用展示
     * @param $name
     * @return mixed
     */
    public function __get($name)
    {
        return $this->name;
    }
    /**
     * 对类中的私有属性或者受保护的属性进行设置的时候,自动进行调用
     * @param $name    属性名
     * @param $value    属性值
     * @return mixed
     */
    public function __set($name, $value)
    {
        return $this->$name=$value;
    }
    /**当对不可访问属性调用 isset() 或 empty() 时,__isset() 会被调用。
     * @param $name
     * @return bool
     */
    public function __isset($name)
    {
        return isset($this->$name);
    }
    public function __unset($name)
    {
        unset($this->$name);
        echo '删除成功!';
    }
    public function __call($name, $arguments)
    {
        echo '方法:'.$name.'在类中不存在'.'<br>'.'参数为:'.'<pre/>'.print_r($arguments,true);
    }
}
$obj=new Demo('小明','男','20');
echo '__get()魔术方法结果:'.'<br>';
echo $obj->name;        //结果  小明
echo '<hr>';
echo '__set()魔术方法结果:'.'<br>';
echo $obj->name='小花';   //结果  小花
echo '<hr>';
echo '__isset()魔术方法结果:'.'<br>';
var_dump(isset($obj->name));   //结果  bool(false)
echo '<hr>';
echo '__unset()魔术方法结果:'.'<br>';
unset($obj->name);          //结果  删除成功
echo '<hr>';
echo '__call()魔术方法结果:'.'<br>';
echo ($obj->add('666'));    //结果  方法:add在类中不存在,参数为666
echo '<hr>';

总结:

  • __set:    类的外部对类的内部的成员进行写操作,类的成员无权限的情况下自动调用

  • __get:    当在类的外部访问类的属性,该属性不存在,或者无权限的情况下,自动进行调用

  • __isset:  判断类的类部,有无某个成员的存在.自动调用

  • __unset:  删除类的类部中的成员,自动调用

  • __call:   访问类中不存在或者无权限的方法.自动调用

  • __callStatic:  访问类中不存在或者无权限的静态方法,自动调用    

方法重载,与链式调用实例

代码如下

Query类

<?php
namespace Query;
class Query
{
    public $pdo = null;
    public $table;
    public $fields = '*';
    public $where;
    public $limit;
    public function __construct($pdo)
    {
        $this->pdo = $pdo;
    }
    public function table($table)
    {
        $this->table = $table;
        return $this;
    }
    public function fields($fields)
    {
        $this->fields = empty($fields) ? '*' : $fields;
        return $this;
    }
    public function where($where = '')
    {
        $this->where = empty($where) ? $where : 'WHERE'.$where;
        return $this;
    }
    public function limit($limit)
    {
        $this->limit = empty($limit) ? $limit : ' LIMIT '. $limit;
        return $this;
    }
    public function select($debug='')
    {
        $sql = 'SELECT '
            . $this->fields
            . ' FROM '
            . $this->table
            . $this->where
            . $this->limit;

        $stmt = $this->pdo->prepare($sql);
        $stmt->execute();
     
        if($debug===1)$stmt->debugDumpParams();
        return $stmt->fetchAll(\PDO::FETCH_ASSOC);
    }
}

 DB类

<?php
namespace Db;
require './Query.php';
class DB
{
    protected static $pdo = null;
    public static function connect()
    {
        $dsn='mysql:host=127.0.0.1;dbname=test';
        self::$pdo = new \PDO($dsn, 'root', 'root');
    }
    public static function __callStatic($name, $arguments)
    {
        self::connect();
        $query = new \Query\Query(self::$pdo);
        return call_user_func_array([$query, $name],$arguments);
    }
}
//示例
$info = DB::table('test')
    ->fields('username')
    ->where('')
    ->limit(5)
    ->select();
echo '<pre/>';
var_dump($info);

实现原理总结:

__callStatic 魔术方法 可以使得在调用内中不存在的静态方法的时候,自动调用该静态方法
call_user_func_array 调用回调函数,并把一个数组参数作为回调函数的参数

1.DB::table('test')时, DB类中无table静态方法,调用__callStatic方法,
2.将pdo连接对象传入Query类中,实例化Query类,
3.通过call_user_func_array 回调 Query类中的table方法,传入对应参数
4.Query类通过传递的参数不断的给Query类的属性赋值,最终通过select方法构建SQL进行数据库查询,并返回查询结果


声明:本文内容转载自脚本之家,由网友自发贡献,版权归原作者所有,如您发现涉嫌抄袭侵权,请联系admin@php.cn 核实处理。
全部评论
文明上网理性发言,请遵守新闻评论服务协议