Blogger Information
Blog 28
fans 0
comment 0
visits 19714
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template
1008 类的属性重载,call_user_func_ayyay函数的应用,类的方法重载的应用,链式调用数据库的应用 20191008 2000-2200
没有人的夏天的博客
Original
641 people have browsed it
  • 类的属性重载

// 类的属性重载的魔术方法  __get  __set  __isset __unset 四个方法

// 属性重载相当于对非公共类属性的可控制强制访问,可用于简单的权限控制

定义一个类的,给三个私有属性,外部无法访问,通过  __get  __set  __isset __unset 四个方法可以进行强制访问

实例

class Class1
{
    private $name;
    private $age;
    private $postion;
    public function __construct($name, $age, $postion)
    {
        $this->name = $name;
        $this->age = $age;
        $this->postion = $postion;
    }

运行实例 »

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


__get($name) 方法 重载

// __get($name)读操作,  $name为属性名,根据参数比对确认是否强制返回

    public function __get($name)
    {
        // 根据打开类的实例 提供的参数,判断是否强制返回对应属性
        // 提示欢迎admin用户回来
        if ($this->name == 'admin') { //admin用户提示相关信息
            if ($name == 'name') { //访问的是name属性,提示欢迎
                return '欢迎回来' . $this->name; //强制访问name属性
            } elseif (isset($this->$name)) { //其它属性返回相关的属性值
                return $name . '属性为:' . $this->$name; //强制访问name属性
            } else { //没有的属性返回属性不存在
                return $name . '属性不存在';
            }
        } else { // 其它用户提示用户无权限访问
            return '无权限访问';
        }
    }
    
    
$a = new Class1('admin', 20, '讲师');
$b = new Class1('user', 20, '讲师');

// 对$a 和$b 两个对象的访问 分别返回不同的内容
echo $a->name;
echo '<hr>';
echo $b->name;
echo '<hr>';

//以上内容$a返回  //欢迎回来admin  //$b返回 //无权限访问

运行实例 »

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


__set($name, $value) 重载方法

// __set($name, $value)写操作,$name为属性名, $value为属性值,根据参数比对确认是否可能强制写入新的属性值

实例

    public function __set($name, $value)
    {
        // admin实例可以修改
        if ($this->name == 'admin') {
            //    访问职位属性修改职位值
            $this->$name = $value;
            // __set无返回值,需要可用echo输出
            // echo $name . '值已修改为' . $this->postion;
        }else{
            echo '非法用户,';
        }
    }
    
$a->postion = '高级讲师'; // 进入__set方法 提示修改成功
echo $a->postion; //进入__get方法,查询修改后的值
echo '<hr>';
$b->postion = '高级讲师'; // 进入__set方法  提示非法用户
echo $b->psotion;    //进入__get方法 提示无权限


//输出效果: 
//postion属性为:高级讲师 , 
//非法用户,user无权限

运行实例 »

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

// 设置 __isset 和 __unset后,在类内类外使用 isset empty unset时都会被调用

// __isset($name)判断操作,$name为属性名,配合外部 inset及emtpy函数使用,确认返回的属性值

// __unset($name)删除操作$name为属性名,配合外部的unset函数使用,确认是否删除相关属性值

实例

 public function __isset($name)
    { //__isset返回bool值,
        //访问对象为admin用户,输出访问值信息,并返回结果;其它对象输出非法用户不返回信息,即返回假;
        if ($this->name == 'admin') {
            echo (isset($this->$name)) ? $name . '1已存在' : $name . '1不存在';
            return isset($this->$name);
        } else {
            echo '非法用户,';
        }
    }

    public function __unset($name)
    {
        // __unset无返回值,需要单独输出值;如不在类内输出 需要在客户端增加判断语句

        if ($this->name == 'admin') {
            // 在__unset内使用empty或isset时 会调用类内的__isset
            if (empty($this->$name)) {
                // 此处会输出__isset内的结果
            } else {
                // 先输出后重置,否则没有输出内容
                echo $this->name . '已重置';
                unset($this->$name);
            }
        } else {
            echo '非法用户,';
        }
        
       
// 判断返回值是否为假,为假输出非法访问,为真输出方法内的结果
// 这里有三个种结果, 非法用户,输出非法用户 非法访问,  合法用户,有值输出访问值已存在,没有值输出访问值不存在,非法访问
echo isset($a->kname) === false ? '非法访问' : '';

echo '<hr>';

unset($a->name);


//输出结果
//kname1不存在非法访问
//admin已重置

运行实例 »

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


  • call_user_func_ayyay函数的应用,类的方法重载的应用

//call_user_func_array([ ],[ ])函数,

//第一个参数为调用内容的路径及名称,
//路径以绝对路径给出,//名称以字符串格式给出,
//可以用 __namespace__ 指定 调用内容的 空间名称 路径
//第二个参数为数组,可以是数组变量也可以数组内容


实例

//call_user_func_array函数的使用
//定义一个拼接用户卡信息的字符串函数
function user_card_id($user_id, $user_source)
{
    return "user_card_id = " . $user_id . $user_source;
}

// 定义一个用户信息类
class userinfo
{
    // 定义一个动态方法
    public function user_card_id($user_id, $user_source)
    {
        return "user_card_id = " . $user_id . $user_source;
    }
    //定义一个静态方法
    public static function user_card_id_two($user_id, $user_source)
    {
        return "user_card_id = " . $user_id . $user_source;
    }
}

//创建一个对象
$use_cid = new userinfo();


//例 调用函数名及给定参数
echo call_user_func_array(__NAMESPACE__.'\user_card_id', ['函数方式', 'app.io']);
echo '<hr>';
//第一个参数写为数组时,数组内第一个为路径值,第二个方法名称 为字符串格式
//例,通过 对象 指定方法路径,
echo call_user_func_array([$use_cid,'user_card_id'], ['对象方式', 'app.io']);
echo '<hr>';
// 如果需要指定其它命名空间内的对象,就需要通过类名指定方法路径
echo call_user_func_array([new namespace\userinfo, 'user_card_id'], ['动态类名方式', 'app.io']);
echo '<hr>';

//以通过静态类名指定静态方法路径
echo call_user_func_array([userinfo::class, 'user_card_id_two'], ['静态类名方式', 'app.io']);
echo '<hr>';

//以上输出结果
//user_card_id = 函数方式app.io
//user_card_id = 对象方式app.io
//user_card_id = 动态类名方式app.io
//user_card_id = 静态类名方式app.io

运行实例 »

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


  • 类的方法重载的应用


实例

//类的方法重载
//动态类重载 __call  静态类重载__callstatic
//定义一个用于外部访问的类
class userinfo2
{
    private $name;
    public function __construct($name)
    {
       $this->name = $name;
    }
    // 动态方法重载
    // __call 第一个参数为方法名称,第二个参数为第一个方法的参数
    //在方法中可以指定其它类的方法,实现对象及方法转换
    public function __call($name, $arguments)
    {
        //如果 是 admin 对象用户  访问userinfo类里的相关方法
        //目前版本下,可以用动态访问符->访问静态方法
        if ($this->name == 'admin') {
            //new 一个访问方法类的对象
            $n = new \userinfo();
            //返回$name方法内容,参数用数组$arguments[0], $arguments[1]传值
            //包括动态方法和静态方法
            return $n->$name($arguments[0], $arguments[1]);
        } else { //其它 对象用户返回 非法访问
            return '非法访问1';
        }
    }
    //静态方法重载, 
    //如何给静态方法加判断?
    // __callStatic 第一个参数为方法名称,第二个参数为第一个方法的参数
    public static function __callStatic($name, $arguments)
    {
        //返回$name方法内容,参数用数组$arguments[0], $arguments[1]传值
        return userinfo::$name($arguments[0], $arguments[1]);
    }
}

//定义一个保存方法的类
class userinfo
{
    // 动态方法
    public function user_card_id($user_id, $user_source)
    {
        return "user_card_id = " . $user_id . $user_source;
    }
    //静态方法
    public static function user_card_id_two($user_id, $user_source)
    {
        return "user_card_id_two = " . $user_id . $user_source;
    }
}

//admin用户对象访问
$use_cid = new userinfo2('admin');
echo $use_cid->user_card_id('动态方法重载', 'app.io');
echo '<hr>';
// ->访问静态方法
echo $use_cid->user_card_id_two('静态方法重载', 'app.io');
echo '<hr>';
// 非admin用户对象访问
$use_cid2 = new userinfo2('user');
echo $use_cid2->user_card_id('动态方法重载', 'app.io');
echo '<hr>';
// ->访问静态方法
echo $use_cid2->user_card_id_two('静态方法重载', 'app.io');
echo '<hr>';
// 静态方法直接访问,无用户限制
echo userinfo2::user_card_id_two('静态方法重载', 'app.io');



以上输出结果:
user_card_id = 动态方法重载app.io
user_card_id_two = 静态方法重载app.io
非法访问1
非法访问1
user_card_id_two = 静态方法重载app.io

运行实例 »

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


  • 链式调用数据库的应用


案例及说明 


实例

<?php

namespace _100801;

//链式调用的应用
//链式调用是指将通过一个参数把相关参数打包进行传递,收到参数的方法进行赋值操作或其它操作,但方法本身返回$this对象,向下层传递参数,最终返回一个获得所有参数的内容;
//链式调用,程序的执行是由外层向内层进行,并最终返回最内层的返回值;

//链式调用的样例,数据库访问

//注意最终生成的sql语句格式错误

// 关于数据绑定, 在sql语句中,指定了字段名和字段值,没有使用变量,所以没有进行变量绑定

// 数据库类
class Dbinfo
{
    //定义属性
    // 关闭pdo连接
    public $pdo = null;
    // 表名
    public $table;
    // 字段名
    public $field;
    // 条件
    public $where;
    // 数量
    public $limit;
    // 排序
    public $orderby;

    //定义方法
    //定义构造方法,接收参数,连接数据库
    public function __construct($name)
    {
        $this->pdo = $name;
    }
    //设置表名方法
    public function table($tablename)
    {
        // 给table属性赋值
        $this->table = $tablename;
        // 返回对象
        return $this;
    }
    //设置字段名方法
    public function field($fieldname)
    {
        // 给fielde属性赋值,没有传值为所有字段,有传值进行赋值
        $this->field = empty($fieldname) ? '*' : $fieldname;
        // 返回对象
        return $this;
    }
    //设置条件方法
    public function where($wherename)
    {
        // 给where属性赋值,没有传值为空,有传值进行赋值
        $this->where = $wherename == '' ? '' : ' WHERE ' . $wherename;
        // 返回对象
        return $this;
    }
    //设置数量方法
    public function limit($limitname)
    {
        // 给limit属性赋值,没有传值为空,有传值进行赋值
        $this->limit = $limitname == '' ? '' : ' LIMIT ' . $limitname;
        // 返回对象
        return $this;
    }
    //设置排序方法
    public function orderby($orderbyname)
    {
        // 给orderby属性赋值,没有传值为空,有传值进行赋值
        $this->orderby = $orderbyname == '' ? '' : ' ORDER BY ' . $orderbyname;
        // 返回对象
        return $this;
    }

    //设置mysql语句拼接
    public function select()
    {
        $sql = 'SELECT '
            . $this->field
            . ' FROM '
            . $this->table
            . $this->where
            . $this->orderby
            . $this->limit;
        var_dump($sql);
        $stmt = $this->pdo->prepare($sql);
        // var_dump ($stmt);
        echo '<hr>';
        $stmt->execute();
        // 向外返回结果
        return $stmt->fetchAll(\PDO::FETCH_ASSOC);
    }

    public function insert($name)
    {
        //组装一条查询语句,判断记录是否存在,$this-field 与select()冲突,
        //所以单独创建了一条查询 $sqlsel
        $this->where = ' WHERE name= "' . $name . '"';
        $sqlsel = 'SELECT * FROM '
            . $this->table
            . ' WHERE name= "'
            . $name
            . '"';
        $stmt = $this->pdo->prepare($sqlsel);
        $stmt->execute();
        // 判断查询结果是否为null,为null执行新增语句,不为null 有对应数据则输出数据已存在
        if ($stmt->fetchAll(\PDO::FETCH_ASSOC) == null) {
            $sql = 'INSERT INTO '
                . $this->table
                . ' SET '
                . $this->field;
            // var_dump($sql);
            $stmt = $this->pdo->prepare($sql);
            $stmt->execute();
            //返回影响的记录行数,  返回pdo影响的记录行号
            echo $stmt->rowCount() . $this->pdo->lastInsertId();
        } else {
            echo '数据已存在';
        }
    }
    //更新语句
    public function update()
    {
        $sql = 'UPDATE '
            . $this->table
            . ' SET '
            . $this->field
            . $this->where;
        $stmt = $this->pdo->prepare($sql);
        $stmt->execute();
        //返回影响的记录行数, 
        return $stmt->rowCount();
    }
    //删除语句
    public function delete()
    {
        $sql = 'DELETE FROM '
            . $this->table
            . $this->where;
        var_dump($sql);
        $stmt = $this->pdo->prepare($sql);
        $stmt->execute();
        //返回影响的记录行数,  返回pdo影响的记录行号
        echo $stmt->rowCount() . $this->pdo->lastInsertId();
    }
}

// 数据库调用类
class DB
{
    // 静态属性初始化
    protected static $pdo = '';

    // 连接数据库函数
    public static function linkdb()
    {
        // 类中的静态属性赋值 为 pod 对象,同时给定默认连接参数,并返回
        return self::$pdo = new \PDO('mysql:host=127.0.0.1;dbname=app.io', 'root', 'root123456');
    }

    public static function __callStatic($name, $arguments)
    {
        // 把pdo信息传到dbinfo类中,开启一个连接对象
        $dboper = new Dbinfo(self::linkdb());
        // 调用查询对象$query中的对应的方法
        return call_user_func_array([$dboper, $name], $arguments);
    }
}

// 客户端操作
// 链式调用 查询
$data = DB::table('movies')
    ->field('mov_id,name,cate_id')
    ->where('cate_id=1')
    ->limit(2)
    ->orderby('mov_id', 'ASC')
    ->select();
echo '<hr>';
// 遍历输出
foreach ($data as $value) {
    print_r($value);
    echo '<br>';
}

echo '<hr>';
// 链式调用 添加
$data = DB::table('movies')
    ->field('name="中国机长",cate_id=1,image="11.jpg",detail="四川航空"')
    ->insert('中国机长');

//链式调用删除
// $data=DB::table('movies')
// ->where('name="中国机长"')
// ->delete();

//链式调用更新
// $data=DB::table('movies')
// ->field('detail="根据四川航空真实事件改编"')
// ->where('name="中国机长"')
// ->update();

运行实例 »

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



Correction status:qualified

Teacher's comments:其实这四个属性重载的方法, 就是访问接口
Statement of this Website
The copyright of this blog article belongs to the blogger. Please specify the address when reprinting! If there is any infringement or violation of the law, please contact admin@php.cn Report processing!
All comments Speak rationally on civilized internet, please comply with News Comment Service Agreement
0 comments
Author's latest blog post