PHP:oop->重载之set/get/call/callStatic,oop事件委托,数据库查询构造器
魔术方法 | 含义 |
---|
__set() | __set(name,value) ,第一个值是成员属性名称,第二个值是成员属性值 | __get() | __get(name) ,第一个值是成员名称或者成员属性值 |
①重载之__set()
在类中,如果实列未创建的成员属性会自动访问__set方法 ,__set(name,value) ,第一个值是成员属性名称,第二个值是成员属性值
②重载之__get()
在类中,如果输出未创建的成员属性会自动访问__get()方法 ,__get(name) ,第一个值是成员名称或者成员属性值
③属性拦截
以上我们得知,如果我们随意创建一个类中没有的成员属性,会自动调用set/get方法,这样的话就无法保护到私有成员或者受保护的成员,因此一般我们会在set/get里面建立一个中转站把获取到的数据传入到一个私有的方法中,来进行内容过滤,以下我们来过滤身份证信息。
判断身份证信息超过18位输出不合法
身份证信息判断未18位后,输出前5位,后4位
代码块
<?php
use Credit as GlobalCredit;
class Credit
{
private $idNum;
private $age;
public function __construct($idNum,$age)
{
$this->idNum = $idNum;
$this->age = $age;
}
public function __set($name, $value)
{
$method = "set" . ucfirst($name) ;
return method_exists($this,$method) ? $this->$method($name,$value) : null;
}
private function setIdNum($name,$value)
{
if (property_exists($this,$name)) {
return $this->$name = strlen($value) == 18 ? $value : null;
}
}
public function __get($name)
{
$method = "get" . ucfirst($name);
return method_exists($this,$method) ? $this->$method($name) : null;
}
private function getIdNum($name)
{
if (property_exists($this,$name) && !empty($this->$name)) {
return mb_substr($this->$name,0,5) . "......" . mb_substr($this->$name,-4,4);
}else {
return "身份证信息不合法";
}
}
}
$User = new Credit("360723198905010042",32);
$User->idNum = "360723199905050012";
echo $User->idNum;
二.方法重载 魔术方法之__call()和__callStatic() __call()方法:当对象访问不存在的方法名称时,此方法自动调用。
- 调用示例:public function __call(
n
a
m
e
,
name,
name,argument){}
注意:访问控制关键字必须为public;必须有两个参数:对象访问的方法名称(
n
a
m
e
)
、
方
法
包
含
的
参
数
(
name)、方法包含的参数(
name)、方法包含的参数(argument ==> 自动转换成数组)。
__callStatic()方法:当对象访问不存在的静态方法名称时,此方法自动调用。
- 调用示例:public static function __callStatic(
n
a
m
e
,
name,
name,argument){}
注意:同__call();此方法为静态方法(static)。
魔术方法 | 含义 |
---|
__call(
n
a
m
e
,
name,
name,argument) | 第一个参数是对象访问的方法名称,第二个参数是方法包含的参数自动转换成数组 | __callstatic() | 同__call();此方法为静态方法(static) |
①__call()
当我们调用没有创建的方法的时候 会自动调用__call方法 和属性调用__set 一样
②__callstatic()
__callStatic 调用未定义静态方法的时候触发,参数和__call 一样
代码块
<?php
/*
*方法重载(方法拦截器)
*|__call($name,$argument)|
*第一个参数是对象访问的方法名称,
*第二个参数是方法包含的参数自动转换成数组
*/
class User {
public function __call($name, $arguments)
{
return "方法名称是:$name,方法属性是:".implode(",",$arguments);
}
public static function __callStatic($name, $arguments)
{
return "静态方法名称是:$name,静态方法属性是:".implode(",",$arguments);
}
}
//当我们调用没有创建的方法的时候 会自动调用__call方法 和属性调用__set一样
echo (new User)->list("admin@qq.com","13456");
echo "<hr>";
echo User::demo("徐峥","泰囧","港囧");
三.事件委托
- 事件委托 : 访问类中不存在的成员方法时, 会被魔术方法拦截, 把请求重定向到别的类的成员方法来处理
代码块
<?php
class User
{
public function write(...$arr)
{
printf("调用方法%s(),参数有:[%s]<br>",__METHOD__,implode(",",$arr));
}
public static function fetch(...$arr)
{
printf("调用静态方法%s(),参数有:[%s]<br>",__METHOD__,implode(",",$arr));
}
}
class work
{
private $user;
public function __construct( $User)
{
$this->user = $User;
}
public function __call($method,$arr)
{
call_user_func([$this->user,"write"],...$arr);
}
public static function __callStatic($method, $arr)
{
call_user_func(["user","fetch"],...$arr);
}
}
$user = new User();
$Work = new work($user);
$Work->list(50,60,70);
work::list(1,2,3);
三.数据库查询构造器 代码块
<?php
class Query
{
protected $db;
protected $table;
protected $field;
protected $limit;
private function connect($dns,$username,$password)
{
$this->db = new PDO($dns,$username,$password);
}
public function __construct($dns,$username,$password)
{
$this->connect($dns,$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 getSQL()
{
return sprintf("SELECT %s FROM %s LIMIT %d",$this->field,$this->table,$this->limit);
}
public function select()
{
return $this->db->query($this->getSQL())->fetchAll(PDO::FETCH_ASSOC);
}
}
class Db
{
static function __callStatic($method,$args)
{
$dns = "mysql:host=localhost;dbname=zwz";
$username = "root";
$password = "a123456";
$query = new Query($dns,$username,$password);
return call_user_func([$query,$method],...$args);
}
}
$user = Db::table()
->field()
->limit()
->select();
echo '<pre>';
print_r($res);
|