Blogger Information
Blog 9
fans 0
comment 0
visits 5845
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template
魔术方法,回调函数,与链式调用 2019年10月8日
错过博客
Original
427 people have browsed it

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进行数据库查询,并返回查询结果


Correction status:qualified

Teacher's comments:不管如何访问其它类中的方法, 最终只是执行一个脚本的, 这个要注意
Statement of this Website
The copyright of this blog article belongs to the blogger. Please specify the address when reprinting! If there is any infringement or violation of the law, please contact admin@php.cn Report processing!
All comments Speak rationally on civilized internet, please comply with News Comment Service Agreement
0 comments
Author's latest blog post