博客列表 >四种魔术方法,属性重载的使用以及方法重载和call_user_func_array()回调的实例使用-------2019.10.08

四种魔术方法,属性重载的使用以及方法重载和call_user_func_array()回调的实例使用-------2019.10.08

刂艹亻的博客
刂艹亻的博客原创
2019年10月11日 18:25:38810浏览

静态与普通方法的相互调用

/**
* *在类的里面
*** 静态属性和静态方法
*** 在静态方法里面可以使用 self 或 类名 加上 :: $属性名 或方法名的格式来调用静态成员
*** 在静态方法里面只能通过实例话类的对象来调用普通成员
*
*** 在普通方法里面可以使用$this->getSex(),self::方法名,类名::方法名  的格式调用静态方法
 *******      
*
*
* *在类的外面
*** 在类的外面可以直接通过  类名::方法名;来调用,不需要实例化.
**但是访问静态成员员属性的时候要带上  $  符号
**常量也是如此
*/

实例

<?php

namespace _1008;
// 由于静态方法不需要通过对象即可调用,所以伪变量 $this 在静态方法中不可用。
// 静态属性不可以由对象通过 -> 操作符来访问。
class Demo1
{
    //类常量
    const AGE=25;
    //普通成员属性:必须将类实例化后获取的对象才能访问它
    public $name;

    //静态属性
    public static $sex;
    
    //构造方法--初始化赋值
    public function __construct($name,$sex)
    {
        //普通属性的调用
         // 当前对象的引用: $this
        $this->name = $name;

        //静态属性的调用
        // 当前类的引用: self
        self::$sex = $sex;
    }

    //静态方法中,一般只能调用静态的属性和方法
    public static function getSex()
    {

        // return self::$sex;
        // 静态方法里面先要调用普通方法或属性,只能通过实例化类来调用
        return (new Demo1('熊大','雄'))->name;
        
    }

    public function getName(){
        $this->name;
        //普通方法里面调用静态方法
    //    return $this->getSex();
       return self::$sex;
    }
}

$obj = new Demo1('大熊','雄');
//静态的方法在内网的外部调用.可以不用实例化,直接以类名::来调用
echo Demo1::getSex();
echo '<br>';
//通过普通方法调用静态方法
echo $obj->getName();

// 调用类常量
echo Demo1::AGE;
/**
 * *在类的里面
 *** 静态属性和静态方法
 *** 在静态方法里面可以使用 self 或 类名 加上 :: $属性名 或方法名的格式来调用静态成员
 *** 在静态方法里面只能通过实例话类的对象来调用普通成员
 * 
 *** 在普通方法里面可以使用$this->getSex(),self::方法名,类名::方法名  的格式调用静态方法
  *******      
 * 
 * 
 * *在类的外面
 *** 在类的外面可以直接通过  类名::方法名;来调用,不需要实例化.
 **但是访问静态成员员属性的时候要带上  $  符号
 **常量也是如此
 */

运行实例 »

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

属性重载以及方法重载的使用

重载:在访问不存在或无权限的,属性或方法的时候会自动触发

实例

<?php
namespace _1008;
//属性重载(魔术方法)---在访问不存在或受保护的对象的时候,会自动触发

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

class Demo2
{
    private $name;
    private $username;
    protected $password=89757;

    //构造方法
    public function __construct($name,$username)
    {
        $this->name = $name;
        $this->username = $username;
    }

    public function __get($name)
    {
        // var_dump($name);die;//这里返回的是你所访问的程思远的属性的名字
        if($name === 'username'){
            return  $this->name == '熊二' ? '请输入密码' : '不可访问' ;
        }
    }

    public function __set($name,$value)
    {
        if($name === 'password'){
            echo ($this->password === $value) ? '密码输入正确' : '密码错误' ;
        }

        //添加方法
        if($name == 'getFunc'){
            $this->$name = is_callable($value)? $value->bindTo($this, $this): $value;
        }
    }
    public function __isset($name)
    {
        return isset($this->$name);
    }

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

    // __call(): 访问一个不存在或无权限访问的方法的时候会自动调用
    public function __call($name,$array)
    {//$name 方法名  $array 参数列表
        if(is_callable($this->$name)){
            return call_user_func_array($this->$name, $array);
        }else{
            throw new \RuntimeException("Method {$name} does not exist");
        }
    }
    //方法重载:访问一个无权限或不存在静态的方法时调用
    public static function __callStatic($name, $args)
    {
        return '方法是: '. $name. '<br>参数列表: <pre>'. print_r($args, true);
    }

}
$obj = new Demo2('熊二',9527);
//当访问私有或不存在的属性的时候,就会自动触发__get()
echo $obj->username;//请输入密码
echo'<hr>';

//当设置私有或不存在的属性的时候,就会自动触发__set()
$obj->password = 89757;//密码输入正确
echo'<hr>';

var_dump(isset($obj->salary));//bool(false)

// __unset():当删除一个不存在或者权限不够的属性的时候会自动触发
unset($obj->name);
var_dump($obj);


// __call __callStatic 方法重载:访问一个无权限或不存在的方法时调用

//利用__set()的特性,向类中添加一个按值调用的匿名函数
$obj->getFunc = function($a){
    return array_product($a);  
};
echo'<hr>';
// 利用__call的特性 将不存在的函数名和参数利用 call_user_func_array 去将匿名函数当作回调来执行
echo $obj->getFunc([1,2,3]);//6
echo'<hr>';

echo Demo2::getIo('小','中','大');

运行实例 »

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

call_user_func_array() 的应用

实例

<?php

namespace _1008;

function sum($a, $b)
{
    return "{$a} + {$b} = " . ($a + $b);
}
// call_user_func 把第一个参数作为回调函数调用,后面是传入回调的参数,
// 如果有命名空间,要带上命名空间
echo sum(13, 56); //13 + 56 = 69
echo '<hr>';
echo call_user_func('\_1008\sum', 50, 50); //50 + 50 = 100
echo '<hr>';
echo call_user_func(__NAMESPACE__ . '\sum', 30, 30); //30 + 30 = 60 (效果同上)
echo '<hr>';
// call_user_func_array  调用回调函数,并把一个数组参数作为回调函数的参数
// 如果有命名空间,要带上命名空间
echo call_user_func_array(__NAMESPACE__ . '\sum', [55, 55]); //55 + 55 = 110

echo '<hr>';
echo '<hr>';

//在类中的使用
class Text
{
    public function sum($a, $b)
    {
        return "{$a} + {$b} = " . ($a + $b);
    }

    public static function product($a, $b)
    {
        return "{$a} * {$b} = " . ($a * $b);
    }
}

$obj = new Text();

echo call_user_func_array([$obj, 'sum'], [33, 33]);
echo '<br>';
echo call_user_func_array([new Text(), 'sum'], [33, 33]);
echo '<hr>';

echo '<br>';
echo '<hr>';

//静态方法的调用
echo call_user_func_array([$obj, 'product'], [2, 2]);
echo '<hr>';
echo call_user_func_array(__NAMESPACE__.'\Text::product', [4, 2]);
echo '<hr>';
echo call_user_func_array([Text::class,'product'], [4, 4]);
echo Text::class;//_1008\Text 返回一个带有命名空间的类名字符串

运行实例 »

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

数据库连接,增,删,改,查的基本操作案例

实例

<?php
namespace _1008;
//引入根空间PDO类
use PDO;
//require 'Qdb.php';

//数据库连接查询
class Qdber
{
    use Select;
    use Update;
    use Insert;
    use Delete;
    //连接对象
    public $pdo = null;

    // 表明
    public $table = null;

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

    // /条件
    public $where = null;

    // 数量
    public $limit = null;

    //修改的数据
    public $value = null;

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

    //设置数据表名称

    public function table($tableName)
    {
        $this->table = $tableName;
        //返回当前类实例, 用来链式调用后面的其它方法
        return $this;
    }

    public function field($fields = '*')
    {
        //如果没传字段名,就默认查所有的
        $this->field = 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;
    }

    public function value($data)
    {
        //如果没传要修改的条件,就默认为空
        $this->value = empty($data) ? die('请输入要修改的参数') : $data ;
        //返回当前类实例, 用来链式调用后面的其它方法
        return $this;
    }
}

//查询组件
trait Select
{
    //查询方法
    public function select()
    {
        //拼装SQL
        $sql = 'SELECT '
            . $this->field // 字段列表
            . ' FROM '
            . $this->table  // 数据表
            . $this->where  // 条件
            . $this->limit;  // 显示数量
        //预处理
        $stmt = $this->pdo->prepare($sql);
//        var_dump($stmt);die;
        $stmt->execute();
        //返回查询结果
        return $stmt->fetchAll(PDO::FETCH_ASSOC);
    }
}

//修改数据
trait Update
{
    public function update()
    {
//        UPDATE 表名 set 要修改的参数 where 条件
        //取出要修改的数据(数组)中的下标,然后组成数组
        $keyArr = array_keys($this->value);
        //循环遍历数组
        $set = '';
        foreach ($keyArr as $value) {
            $set .= $value . ' = :' . $value. ', ';
        }
        //去掉最后一个逗号
        $set = rtrim($set, ', ');
        //组装sql语句
        $sql ='UPDATE ' .$this->table . ' SET '. $set .$this->where;

        //预处语句
        $stmt = $this->pdo->prepare($sql);
//                var_dump($stmt);die;

        //执行
        $stmt->execute($this->value);
        //返回受影响的那一行
        return $stmt->rowCount();
    }
}

//添加数据
trait Insert
{
    public function insert()
    {
        //取出要添加的数据(数组)中的下标,然后组成数组
        $keyArr = array_keys($this->value);
        //循环遍历数组
        $fields = '';
        foreach ($keyArr as $value) {
            $fields .= $value . ', ';
        }
        //去掉最后一个逗号
        $fields = rtrim($fields, ', ');

        $value = '';
        foreach ($keyArr as $v) {
            $value .= ':'.$v . ', ';
        }
        //去掉最后一个逗号
        $value = rtrim($value, ', ');
        //组装sql语句
        $sql ='INSERT INTO ' .$this->table .' ('.$fields .')'. ' VALUES '.'('. $value .')'.$this->where;

        //预处语句
        $stmt = $this->pdo->prepare($sql);
//                var_dump($stmt);die;

        //执行
        $stmt->execute($this->value);
        //返回受影响的那一行
        return [
            'count' => $stmt->rowCount(),
            'id' => $this->pdo->lastInsertId()
        ];
    }
}

//删除
trait Delete
{
    // 删除数据
    public function delete()
    {
        $sql = 'DELETE FROM ' .$this->table .$this->where;
        $stmt = $this->pdo->prepare($sql);
//        var_dump($stmt);die;
        $stmt->execute();

        return $stmt->rowCount();
    }
}
//连接数据库
trait DBname
{
    //连接数据库的参数,独立出来便于更改
    public static $dsn = 'mysql:host=127.0.0.1;dbname=chen';
    public static $usernam = 'root';
    public static $password = 'root';
    //数据库的连接方式
    public static function connection()
    {
        // 连接数据库
        self::$pdo= new PDO(self::$dsn,self::$usernam,self::$password);
        // 实例化sql参数类,将连接对象做为参数
        self::$query = new Qdber(self::$pdo);
//        var_dump(self::$query);die;
    }
}

//执行类
class Execute
{
    use DBname;
    //连接对象
    protected static $pdo = null;
    protected static $query = null;

    public static function __callStatic($name, $arguments)
    {
        // TODO: Implement __callStatic() method.
        self::connection();
        // 调用查询对象$query中的对应的方法
        return call_user_func_array([self::$query,$name],$arguments);
    }


}
//$staffs = Execute::table('staff');

//查询
$staffs = Execute::table('staff')
    ->field('staff_id,name,position,mobile')
    ->where('staff_id > 2')
    ->limit(5)
    ->select();
//var_dump($staffs);die;
// 遍历
foreach ($staffs as $staff) {
    print_r($staff); echo '<br>';
}
echo'<hr>';
$data = [
    'name' => '作者',
    'position' => '作死的存在'
];
//修改
//$staffs2 = Execute::table('staff')
//    ->value($data)
//    ->where('staff_id = 11')
//    ->update();
//print_r($staffs2);
echo'<hr>';

//添加
$data2 = [
    'name' => '郭靖',
    'age' => 29,
    'sex' => 1,
    'position' => '金刀驸马',
    'mobile' => '1389998899',
    'hiredate' => time()
];
//$staffs3 = Execute::table('staff')
//    ->value($data2)
//    ->insert();
//print_r($staffs3);

//删除
//$staffs4 = Execute::table('staff')
//    ->where('staff_id >10')
//    ->delete();
//print_r($staffs4);

//trait 类,是特殊类,类似与接口。不能实例化,可以直接在调用的类中通过 use 引用

运行实例 »

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


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