1、构造方法(魔术方法,公共方法)
__construct()
构造方法是类中的一个特殊方法。当使用new
操作符创建一个类的实例时,构造方法将会自动调用,其名称必须是 __construct() 。
2、重载(访问拦截器)
- 2.1 魔术方法:
__get
(访问未定义或无权限访问的属性时被调用)
Demo类中两个属性均为私有属性,访问时自动跳到
__get
魔术方法拦截进行访问。
- 2.2 魔术方法:
__set
(给未定义的属性赋值时被调用)
Demo类中两个属性均为私有属性,赋值时自动跳到
__set
魔术方法拦截进行赋值。
- 2.3 魔术方法:
__isset
(对未定义的属性、不可访问或空isset()
时被调用)
Demo类中属性
$name
为私有属性,isset()
时自动跳到__isset
魔术方法拦截进行检查。
- 2.3 魔术方法:
__unset
(销毁无法访问属性unset()
时被调用)
Demo类中属性
$name
为私有属性,unset()
时自动跳到__unset
魔术方法拦截进行销毁。
- 2.3 魔术方法:
__call
方法拦截器与__callStatic
静态方法拦截器
3、小案例:查询构造器实现DB类
// 方法委托/方法拦截器 实战: 数据库查询构造器(链式查询)
// 查询类
class Query
{
// 连接对象
protected $db;
// 数据表
protected $table;
// 字段列表
protected $field;
// 记录数量
protected $limit;
protected $values;
protected $where;
// 构造方法: 连接数据库
public function __construct($dsn, $username, $password)
{
$this->connect($dsn, $username, $password);
}
// 连接数据库
private function connect($dsn, $username, $password)
{
$this->db = 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 values($values)
{
$this->values = $values;
return $this;
}
public function where($where)
{
$this->where = $where;
return $this;
}
// 生成查询语句
protected function getSql($type)
{
switch($type){
case 'i':
return sprintf('INSERT INTO %s (%s) VALUES(%s)', $this->table, $this->field, $this->values);
break;
case 'u':
return sprintf('UPDATE %s SET %s = "%s" WHERE %s', $this->table, $this->field, $this->values, $this->where);
break;
case 'd':
return sprintf('DELETE FROM %s WHERE %s = %s', $this->table, $this->field, $this->values);
break;
case 's':
return sprintf('SELECT %s FROM %s LIMIT %s', $this->field, $this->table, $this->limit);
break;
default:
return 'SQL语句错误!';
}
}
// 执行查询
public function select()
{
return $this->db->query($this->getSql('s'))->fetchAll(PDO::FETCH_ASSOC);
}
// 执行插入
public function insert()
{
return $this->db->query($this->getSql('i'));
}
// 执行删除
public function delete()
{
return $this->db->query($this->getSql('d'));
}
// 执行更新
public function update()
{
return $this->db->query($this->getSql('u'));
}
}
// 数据据操作类
class DB
{
// 静态方法委托
public static function __callStatic($name, $args)
{
// 获取到查询类的对象: new Query()
$dsn = 'mysql:host=localhost;dbname=php_pro';
$username = 'root';
$password = 'root';
$query = new Query($dsn, $username, $password);
// 直接跳到Query类中的具体方法来调用
return call_user_func([$query, $name], ...$args);
}
}
//查询
$result = DB::table('users')
->field('id,username,email')
->limit(5)
->select();
print_r($result);
//添加
$result = DB::table('users')
->field('username,age,email,password')
->values("'arwang',33,'arwang@php.cn', md5('123456php.pro')")
->insert();
echo $result ? '添加成功' :'添加失败';
//删除
$result = DB::table('users')
->field('id')
->values(12)
->delete();
echo $result ? '删除成功' :'删除失败';
//更新
$result = DB::table('users')
->field('username')
->values('arwang888')
->where('id = 32')
->update();
echo $result ? '更新成功' :'更新失败';
总结:
- 查询构造器实现DB类还不是很明白,链式方法是怎么定义的?
- 如果要使用问号占位符,使用
execute()
方法执行,试了好久没成功; - update()操作不知道字段如何批量操作,作业只实现了修改单个字段。