php魔术方法 重载方法,PHP类之魔术方法和类方法重载

魔术方法:

* 1.类中以双下划线开头的方法,这是由系统内置的,用户方法不要用双下划线开头;

* 2.魔术方法由系统在一定条件下自动触发调用,用户不能直接调用;

* 注意:将类中的私有成员前面添加单下划线是一个好习惯;

* 例如:private $_salary;    private function _listUsers(){...}

* 使用魔术方法实现几个对象访问拦截器

* 所谓拦截器:就是对用户的一些错误或非法访问进行检测和控制。

* 之前我们学过__get($fieldName)和__set()这是二个最常用的拦截器

* 现在我们再学习一组: __isset($fieldName)和__unset($fieldName)

1. __isset():当在类外检测一个类属性是否存在时会自动调用

2. __unset():当在类外销毁一个类属性时会自动调用

实例

class Demo

{

private $name = 'peter';

private $email = 'peter@php.cn';

//当在类外使用isset()检测某个属性是否存在时自动调用

public function __isset($name)

{

//对访问进行过滤:如果属性名是'name',返回false,否则允许访问

//即除了'name'属性外的其它属性允许外部进行isset()检测

return ($name=='name') ? false : true;

}

}

//实例化 Demo 类

$obj = new Demo;

//检测$obj中是否有name属性,返回

echo isset($obj->name)?'存在':'不存在';

echo '


';

//检测$obj中是否存在email属性,返回存在,因为类中__isset()返回true

echo isset($obj->email)?'存在':'不存在';

//在外部使用unset()来销毁类属性

运行实例 »

点击 "运行实例" 按钮查看在线实例

类方法重载: __call()和__callStatic()

1.call($name,$array): 当类外访问一个不存在的方法时自动调用

2.callStatic($name,$array):当类外访问一个不在静态上下文中的方法时自动调用

用途:

1.防止访问不存在的方法时报错;

2.其实最有用的应用场景是动态生成一个可访问的方法,实现方法的跨类调用

先创建一个数据库查询类: Query.php

实例

//数据库查询类

class Query

{

private $pdo = null;  //数据库连接对象

private $stmt = null; //预处理语句对象

private $table = '';  //数据表名

private $field = '';  //字段列表

private $where = '';  //查询条件

private $order = '';  //排序规则

//构造方法: 初始化连接对象

public function __construct($pdo)

{

$this->pdo = $pdo;

}

//设置数据表名

public function table($table)

{

$this->table = $table;

//***返回当前对象,便于链式调用后面的方法

return $this;

}

//设置字段列表

public function field($field)

{

$this->field = $field;

//***返回当前对象,便于链式调用后面的方法

return $this;

}

//设置查询条件

public function where($where)

{

$this->where = $where;

//***返回当前对象,便于链式调用后面的方法

return $this;

}

//设置排序规则

public function order($order)

{

$this->order = $order;

//***返回当前对象,便于链式调用后面的方法

return $this;

}

//单条查询语句: 仅返回符合条件结果集中的第一条记录

public function find()

{

//简化查询参数

$table = $this->table;

$field = $this->field;

$where = $this->where;

//设置SQL语句

$sql = "SELECT {$field} FROM {$table} {$where} LIMIT 1;";

//        die($sql);

//创建预处理语句对象

$this->stmt = $this->pdo->prepare($sql);

//执行预处理查询

$this->stmt->execute();

//返回预处理查询的结果集(单条查询返回一维数组)

return $this->stmt->fetch(PDO::FETCH_ASSOC);

//***注: find是最终方法,负责执行SQL查询,不用返回当前对象$this

}

//多条查询语句

public static function select($db,$table,$field,$where,$order)

{

//设置SQL语句

$sql = "SELECT {$field} FROM {$table} {$where} {$order};";

//        die($sql);

//为了简化代码,这里不再使用PDO来处理,直接使用原生的MySQLi来完成查询

$res = mysqli_query($db, $sql);

return mysqli_fetch_all($res);

//***注: select是最终方法,负责执行SQL查询,不用返回当前对象$this

}

}

运行实例 »

点击 "运行实例" 按钮查看在线实例

调用测试源码

实例

//导入数据库查询类

spl_autoload_register(function($className){

require './class/'.$className.'.php';

});

class Db

{

public $pdo = null;

public function __construct($host='localhost',$user='root',$pass='root',$dbname='php')

{

try {

$this->pdo = new PDO("mysql:host={$host};dbname={$dbname}",$user,$pass);

} catch (PDOException $e) {

echo 'Connection failed: ' . $e->getMessage();

}

}

//当访问一个不存在的动态方法时会自动触发

public function __call($name,$args)

{

$query = new Query($this->pdo);

return call_user_func_array([$query,$name], $args);

}

//当访问一个不存在的静态方法时会自动触发,注意这个方法必须声明为public static

public static function __callStatic($name,$args)

{

return call_user_func_array(['Query',$name], $args);

}

}

//实例化Db

$db = new Db('localhost','root','root','php');

运行实例 »

点击 "运行实例" 按钮查看在线实例

任务一: 使用__call()实现动态方法的跨类调用

* 1. 从Db类中去动态的执行Query类中的方法

* 2. 返回符合条件的单条记录

* 3. 使用PDO预处理对象完成

实例

/**接上**/

//实例化Db

$db = new Db('localhost','root','root','php');

//设置查询参数,因为是单条查询,无须设置排序规则$order

$table = 'staff';  //表名

$field = 'name,age,salary '; //字段列表

$where = 'WHERE age 

//链式调用Query查询类中的find()方法来完成查询

$row = $db->table($table)->field($field)->where($where)->find();

//查看单条查询结果

echo '

'.print_r($row,true).'
';

运行实例 »

点击 "运行实例" 按钮查看在线实例

任务二: 使用__callStatic()实现静态方法的跨类调用

* 1. 从Db类静态调用Query中的静态方法

* 2. 返回符合条件的多条记录

* 3. 使用PDO预处理对象完成

实例

/**同上接上**/

//设置查询参数,增加一个排序规则$order

$table = 'staff';  //表名

$field = 'name,age,salary '; //字段列表

$where = 'WHERE age 

$order = 'ORDER BY age DESC';

//链式调用Query查询类中的select()方法来完成查询

//为简化代码,使用原生MySQLi来完成查询

$db = mysqli_connect('localhost', 'root', 'root', 'php');

$rows = Db::select($db,$table,$field,$where,$order);

//查看单条查询结果

echo '

'.print_r($rows,true).'
';

运行实例 »

点击 "运行实例" 按钮查看在线实例

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值