博客列表 >第14章 成员重载与实战-2019年10月08日20时00分

第14章 成员重载与实战-2019年10月08日20时00分

Tommy-黄天浩的博客
Tommy-黄天浩的博客原创
2019年10月11日 11:33:03658浏览

1、实例演示四个属性重载的魔术方法的使用方式。

__get(), __set(), __isset(), __unset()

实例

<?php
namespace _001;

class Demo1{
    private $name;
    private $salary;
    protected $secret='这是一条秘密消息';

    public function __construct($name,$salary){
        $this->name=$name;
        $this->salary=$salary;
    }

    public function __get($name){
        if($name === 'secret'){
            return ($this->name === 'admin')?$this->$name:'无权查看';
        }
        
        return $this->$name;
    }
}

$obj = new Demo1('admin',8888);
echo $obj->secret;

运行实例 »

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

如果不是admin没有权限去查看secret.

 魔术方法: 不需要或不允许用户调用,由系统来调用
__get(): 重载了用户对属性的访问
 __get()是读操作

 

实例

<?php
namespace _001;

class Demo1{
    private $name;
    private $salary;
    protected $secret='这是一条秘密消息';

    public function __construct($name,$salary){
        $this->name=$name;
        $this->salary=$salary;
    }

    public function __get($name){
        if($name === 'secret'){
            return ($this->name === 'admin')?$this->$name:'无权查看';
        }

        return $this->$name;
    }

    public function __set($name,$value)
    {
        if ($name === 'salary') {
            return $this->name === 'admin' ? $this->$name = $value : '无权更新工资';
        }
        return $this->$name = $value;
    }
}

$obj = new Demo1('amin',8888);
$obj->salary=9999;
echo $obj->salary;

运行实例 »

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

__set($name, $value): 写操作

实例

<?php
namespace _001;

class Demo1{
    private $name;
    private $salary;
    protected $secret='这是一条秘密消息';

    public function __construct($name,$salary){
        $this->name=$name;
        $this->salary=$salary;
    }

    public function __isset($name){
        return isset($this->$name);
    }
}

$obj = new Demo1('amin',8888);

echo isset($obj->name);
//当在类外部使用isset()函数来测定对象里面的私有成员是否被设定时,就会自动调用类里面的__isset()方法了帮我们完成这样的操作。

运行实例 »

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

__unset() 方法用于删除私有属性。

同 isset() 函数一样,unset() 函数只能删除对象的公有成员属性,当要删除对象内部的私有成员属性时,需要使用__unset() 方法:

实例

<?php
namespace _001;

class Demo1{
    private $name;
    private $salary;
    protected $secret='这是一条秘密消息';

    public function __construct($name,$salary){
        $this->name=$name;
        $this->salary=$salary;
    }

    public function __unset($name){
        unset($this->$name);
    }
}

$obj = new Demo1('amin',8888);

unset($obj->secret);

运行实例 »

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


2、实例演示call_user_func_array()回调执行函数/对象/类的方法和流程

实例

<?php

namespace _001;
//call_user_func_array对方法的回调
function sum($a,$b){
    return "{$a}+{$b}=".($a+$b);
}

echo call_user_func_array(__NAMESPACE__.'\sum',[13,65]);
echo '<br>';

//call_user_func_array对对象的回调
class Demo1{
    public function sum($a,$b){
        return "{$a}+{$b}=".($a+$b);
    }
}

echo call_user_func_array([new Demo1(),'sum'],[15,67]);
echo '<br>';

//call_user_func_array对类的回调
class Demo2{
    public static function sum($a,$b){
        return "{$a}+{$b}=".($a+$b);
    }
}

$obj=new Demo2();
echo call_user_func_array(__NAMESPACE__.'\Demo2::sum',[56,98]);
echo '<br>';
echo call_user_func_array([Demo2::class,'sum'],[76,90]);

运行实例 »

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

运行效果如下图所示:

360截图20191010162727086.jpg


3、实例演示方法重载的实现原理与参数的获取方式。

实例

<?php

namespace _001;

class Demo3
{
    // __call(): 访问一个不存在或无权限访问的方法的时候会自动调用
    public function __call($name,$arrays){
        return '方法是:'.$name.'<br>'.'参数是:'.'<pre>'.print_r($arrays,true);
    }

    // __callStatic(): 访问一个不存在或无权限访问的静态方法的时候会自动调用
    public static function __callstatic($name,$arrays){
        return '方法是:'.$name.'<br>'.'参数是:'.'<pre>'.print_r($arrays,true);  
    }
}

$obj=new Demo3();
echo $obj->sum(1,2,3,4,5);
echo '<br>';
echo Demo3::add(1,2,5,6,8);

运行实例 »

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

运行效果如图所示:

360截图20191010162727086.jpg


4、实例演示数据库链接调用的实现原理与过程(静态方法重载__callstatic实现)。

 先新建一个Query.php文件,代码如下:

实例

<?php

namespace _001;

class Query{
    //连接对象
    public $pdo=null;

    //表名
    public $table;

    //字段
    public $field='*';

    //条件
    public $where;

    //数量
    public $limit;

    //构造方法
    public function __construct($pdo){
        // 实例时自动连接数据库
        $this->pdo=$pdo;
    }

    //设置数据表名称
    public function table($tablename){
        $this->table=$tablename;
        return $this;
        //返回的是一个对象
    }

    //设置数据表字段
    public function field($fileds='*'){
        $this->filed =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;
    }

    //生成SQL查询语句
    public function select(){
        $sql='SELECT '
            .$this->field
            .' FROM '
            .$this->table
            .$this->where
            .$this->limit;

        //预处理
        $stmt=$this->pdo->prepare($sql);
        $stmt->execute();
        
        // die($stmt->debugDumpParams());  // 查看生成的sql

        return $stmt->fetchAll(\PDO::FETCH_ASSOC);
    }
}

运行实例 »

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

新建index.php文件,代码如下:

实例

<?php

namespace _001;

require 'Query.php';

class DB{
    //连接对象
    protected static $pdo=null;

    //数据库连接方法
    public static function connection(){
        self::$pdo=new \PDO('mysql:host=127.0.0.1;dbname=php','root','root');
    }

    public static function __callstatic($name,$array){
        //连接数据库
        self::connection();
        //实例化查询类,将连接参数作为对象
        $query=new Query(self::$pdo);
        //调用查询对象query中的方法
        return call_user_func_array([$query,$name],$array);
    }
}

$staffs = DB::table('staff')
    ->field()
    ->where()
    ->limit(6)
    ->select();
// print_r($staffs);

// 遍历
foreach ($staffs as $staff) {
    print_r($staff); echo '<br>';
}

运行实例 »

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

运行后效果如下图所示:

360截图20191010162727086.jpg

声明:本文内容转载自脚本之家,由网友自发贡献,版权归原作者所有,如您发现涉嫌抄袭侵权,请联系admin@php.cn 核实处理。
全部评论
文明上网理性发言,请遵守新闻评论服务协议