批改状态:合格
老师批语:不管如何访问其它类中的方法, 最终只是执行一个脚本的, 这个要注意
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进行数据库查询,并返回查询结果
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号