Blogger Information
Blog 21
fans 0
comment 0
visits 23973
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template
四种魔术方法,属性重载的使用以及方法重载和call_user_func_array()回调的实例使用-------2019.10.08
刂艹亻的博客
Original
805 people have browsed it

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

/**
* *在类的里面
*** 静态属性和静态方法
*** 在静态方法里面可以使用 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 引用

运行实例 »

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


Correction status:qualified

Teacher's comments:写得不错, trait 的理解也正确
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