类的属性和方法重载以及使用静态重载方法连接数据库--2019-10-08
程序员文章站
2022-03-20 22:37:28
...
1、实例演示四个属性重载的魔术方法
<?php namespace _1008task1; class staff { // 属性 public $name; public $age; private $gender; private $salary; protected $position; protected $department; // 构造方法 public function __construct($staff) { $this->name=$staff['name']; $this->age=$staff['age']; $this->gender=$staff['gender']; $this->salary=$staff['salary']; $this->position=$staff['position']; $this->department=$staff['department']; } // __get()属性重载方法一:获取不能访问的属性 public function __get($salary) { return $this->$salary; } // __set()属性重载方法二:修改或者设置不能访问的属性值 public function __set($name,$value) { if ($name === 'salary') { return $this->name === 'admin' ? $this->$name = $value : '无权更新工资'; } return $this->$name = $value; } // __$isset()属性重载方法三:判断外部不能直接访问的属性是否存在 public function __isset($salary) { return isset($this->$salary) ; } // __unset()属性重载方法四:删除某种外部不能访问的属性 public function __unset($private) { unset($this->$private); } // 普通方法 public function setInfo($salary,$value) { return $this->$salary=$value; } } $staff=[ 'name'=>'Rid', 'age'=>15, 'gender'=>'男', 'salary'=>'20939', 'position'=>'饮水机管理员', 'department'=>'研发' ]; $obj = new staff($staff); echo $obj->department; echo '<hr>'; echo $obj->department='财务','<hr>'; echo $obj->department,'<hr>'; echo isset($obj->salary) ? '存在' : '不存在','<hr>'; unset($obj->age); echo $obj->age,'<hr>'; echo $obj->setInfo('depertment','项目'),'<hr>'; // echo $obj->name; echo $obj->salary=231414,'<hr>'; echo $obj->salary; ?>
结果:
2、实例演示call_user_func_array()回调执行函数/对象/类的方法的流程与方式
<?php namespace _1008task2; function sum($a,$b) { return "$a*$b=" . $a * $b; } echo sum(2,4),'<hr>'; echo call_user_func( __NAMESPACE__.'\sum',3,5),'<hr>'; echo call_user_func_array(__NAMESPACE__.'\sum',[28,89]),'<hr>'; class test { public function sum($a,$b){ return "$a*$b=" . $a * $b; } public static function calculate($a,$b){ return "$a*$b=" . $a * $b; } } // echo test::class; echo '普通方法(创建对象): '.call_user_func_array([new test,'sum'],[2,3]),'<hr>'; echo '静态方法(直接调用): '.call_user_func_array([test::class,'calculate'],[4,5]); ?>
结果:
3、实例演示方法重载的实现原理与参数获取方式
<?php namespace _1008task3; class test { // __call关键字:用来点访问一个没有权限访问或者没有创建的普通方法 public function __call($name,$args){ return '函数名称:' . $name . '<br>函数参数:<pre>' . print_r($args,true) ; } // __callstatic关键字:用来访问一个没有权限访问或者没有创建的静态方法 public static function __callstatic($name,$args){ return '函数名称:' . $name . '<br>函数参数:<pre>' . print_r($args,true) ; } } echo (new test)->sum(2,3),'<hr>'; echo test::calculate(2,4),'<hr>'; ?>
结果:
4、实例演示数据库链接调用的实现原理与过程(静态方法重载__callStatic实现)
// <?php namespace _1008task4; require 'db.php'; class test { protected static $pdo=null; //设置连接对象 public static function connection() //数据库连接方法 { self::$pdo = new \PDO('mysql:host=127.0.0.1;dbname=video', 'root', 'root'); } public static function __callStatic($name,$args) { // 连接数据库 self::connection(); // 实例化查询类,将连接对象最为参数 $query=new \_1008db\db(self::$pdo); // 调用$query对象中的方法 return \call_user_func_array([$query,$name],$args); } } $results= test::table('movies') ->field('mov_id,name,image,cate_id') ->limit(5) ->select(); foreach ($results as $v) { print_r($v); echo '<br>'; }; echo '<hr>'; ?> // <?php namespace _1008db; class db //查询类 { // 属性; public $pdo=null; // 数据库连接对象; public $table; // 表名; public $field; // 字段; public $where; // 条件; public $limit; // 数量限制; public $sequence; // 排序方式; // 构造方法,连接数据库; public function __construct($pdo){ $this->pdo=$pdo; //创建实例是自动连接数据库 } // 设置操作的表名 public function table($tableName){ $this ->table= $tableName ; return $this; //返回当前对象,用于链式调用 } // 设置查询数据操作字段 public function field($field= '*'){ $this ->field= empty($field) ? ' * ' : ' '.$field ; return $this; //返回当前对象,用于链式调用 } // 设置操作范围 public function where($where=''){ $this ->where = empty($where) ? '' : ' WHERE '. $where ; return $this; //返回当前对象,用于链式调用 } // 设置显示数量 public function limit($limit=''){ $this ->limit= empty($limit) ? '' : ' LIMIT ' . $limit ; return $this; //返回当前对象,用于链式调用 } // 设置排序方式 public function sequence($sequence=''){ $this->sequence = empty($sequence) ? '' : ' ORDER BY '. $sequence ; return $this; //返回当前对象,用于链式调用 } // 创建查询(SELECT)SQL方法 public function select() { //拼接SELECT查询语句 $sql= ' SELECT ' . $this->field . ' FROM ' . $this->table . $this->where . $this->limit; // . $this->squence; // 预处理 $stmt=$this->pdo->prepare($sql); // 执行sql语句 $stmt->execute(); // die($stmt->debugDumpParams()); // 查看生成的sql // 返回执行结果 return $stmt->fetchAll(\PDO::FETCH_ASSOC); } // 创建新增数据(insert)SQL方法 public function insert() { // 拼接inert SQL语句 $sql='INSERT INTO' . $this->table . $this->field; // 执行sql语句 $stmt->execute(); // 判断并输出数据是否插入成功 if($stmt->execute()){ if($stmt->rowcount()>0){ echo '成功添加'.$stmt->rowcount().'条数据,该数据的主键是:'.$pdo->lastUpdateId(); }else{ die('<pre>'. print_r($stmt->errorInfo(), true)); } } } // 创建更新(update)SQL方法 public function update() { // 拼接update SQL语句 $sql = ' UPDATE ' . $this->table . $this->field . $this->where; // 预处理 $stmt = $this->pdo->prepare($sql); die($stmt->debugDumpParams()); // 执行sql语句 $stmt->execute(); if($stmt->execute()){ if($stmt->rowcount()>0){ echo '成功添加'.$stmt->rowcount().'条数据,该数据的主键是:'.$pdo->lastUpdateId(); }else{ die('<pre>'. print_r($stmt->errorInfo(), true)); } } } } ?>
结果:
小结:
1、属性重载:是让原本在类的外部没有权限进行访问的属性即protected和private两个关键字声明属性通过__get()/__set()/__isset()/__unset()
四种魔术方法可以在类外直接调用。这四种魔术方法和自己定义的用来访问受保护的或者私有的属性的普通方法再功能是其实没有什么区别,只是
魔术方法是php内置的方法,使用更加简洁可以直接对该属性进行操作,而自定义的普通方法则需要调用方法才能操作属性。
2、方法重载:也是通过使用PHP内置的魔术方法__call()和__callStatic()来在类的外边访问无权限的方法并且可以创建类中原本不存在的方法。