博客列表 >魔术方法__isset()、__unset()、__sleep()、__wakeup()与__call()、__callStatic()的实例使用

魔术方法__isset()、__unset()、__sleep()、__wakeup()与__call()、__callStatic()的实例使用

Tlilam的PHP之路
Tlilam的PHP之路原创
2020年09月10日 20:55:24799浏览

实现__isset()和__unset()访问拦截操作

  1. isset()和unset()访问非公开成员就会调用类中的__isset()和__unset()
  1. <?php
  2. class Demo{
  3. public $name = 'tlilam';
  4. protected $password = '123';
  5. private $email = 'tlilam@php.cn';
  6. // 当外部使用isset函数,检测类中非公开成员就会调用这个方法,在类内部检测成员是否存在,返回值
  7. public function __isset($n){
  8. return isset($this->$n);
  9. }
  10. public function __unset($n){
  11. unset($this->$n);
  12. }
  13. }
  14. $demo = new Demo();
  15. // 公开成员可以直接使用isset函数
  16. var_dump( isset($demo->name));
  17. // isset()函数检测非公开成员,调用类中的__isset()方法
  18. var_dump( isset($demo->password) );
  19. var_dump( isset($demo->email) );
  20. echo '<hr/>';
  21. // 打印类的属性
  22. print_r( $demo );
  23. // 公开成员可以直接被删除
  24. unset($demo->name);
  25. print_r( $demo );
  26. // unset()函数删除非公开成员,调用类中的__unset方法
  27. unset($demo->email);
  28. print_r( $demo );

__callStatic()事件委托,实现简单的数据表操作器

  1. __call()、__callStatic()没有差别,只是一个是拦截普通方法,一个拦截静态方法
  1. <?php
  2. // 实际操作类
  3. class Query{
  4. protected $db;
  5. protected $table;
  6. protected $field = '*';
  7. protected $limit;
  8. protected $where;
  9. // 构造方法: 调用connect方法连接数据库
  10. public function __construct($dsn, $username, $password)
  11. {
  12. $this->connect($dsn, $username, $password);
  13. }
  14. // 使用PDO连接后赋值给属性db
  15. protected function connect($dsn,$username,$password){
  16. $this->db = new PDO($dsn,$username,$password);
  17. // var_dump($this->db);
  18. }
  19. // 属性赋值并返回赋值后的实例
  20. public function table($table){
  21. $this->table = $table;
  22. return $this;
  23. }
  24. public function field($field){
  25. $this->field = $field;
  26. return $this;
  27. }
  28. public function limit($limit){
  29. $this->limit = $limit;
  30. return $this;
  31. }
  32. public function where($id='id',$key=0,$operator='='){
  33. $this->where = $id.$operator.'\''.$key.'\'';;
  34. return $this;
  35. }
  36. // 得到SQL语句
  37. public function getsql($v,$v1='',$v2=''){
  38. switch($v){
  39. case 'insert':
  40. $string = sprintf('INSERT %s ( %s ) VALUES ( %s );', $this->table, $v1,$v2);
  41. break;
  42. case 'update':
  43. $string = sprintf('UPDATE %s SET %s WHERE %s ;', $this->table, $v1,$this->where);
  44. break;
  45. case 'delete':
  46. $string = sprintf('DELETE FROM %s WHERE %s;', $this->table, $this->where);
  47. break;
  48. case 'select':
  49. $string = sprintf('SELECT %s FROM %s %s %s',$this->field, $this->table,
  50. $this->where?"WHERE $this->where":null,
  51. $this->limit?"LIMIT $this->limit ":'');
  52. break;
  53. }
  54. return $string;
  55. }
  56. // 下面是真正的执行操作
  57. // 查询操作
  58. public function select(){
  59. // return $this->getsql('select');
  60. return $this->db->query( $this->getsql('select') )->fetchAll(PDO::FETCH_ASSOC);
  61. }
  62. // 插入操作
  63. public function insert($inserts = []){
  64. // 将键值取出拼接成SQL的字段名
  65. $i1 = '`'. implode('`,`',array_keys($inserts)) . '`';
  66. // 将值拼接成SQL的字段值
  67. $i2 = '\''. implode('\',\'',$inserts) . '\'';
  68. // 执行SQL插入
  69. return $this->db->exec($this->getsql('insert',$i1,$i2));
  70. }
  71. // 更新操作
  72. public function update($args=[]){
  73. $string ='';
  74. foreach($args as $key=>$value){
  75. $string.= $key.'=\''.$value.'\',';
  76. }
  77. // return rtrim($string,',');
  78. // return $this->getsql('update',rtrim($string,','));
  79. return $this->db->exec( $this->getsql('update',rtrim($string,',')) );
  80. }
  81. // 删除操作,可以使用where,也可以在delete()放入ID值
  82. public function delete( $id=null,$pk='id' ){
  83. if( !$this->where ){
  84. $this->where = $pk.'=\''.$id.'\'';
  85. }
  86. // return $this->getsql('delete');
  87. return $this->db->exec( $this->getsql('delete') );
  88. }
  89. }
  90. // 数据库类,方法委托
  91. class DB{
  92. // 进行静态方法拦截,进行事件委托给Query类
  93. public static function __callStatic($name,$args=[]){
  94. $dsn = 'mysql:host=localhost;dbname=phpedu';
  95. $username='root';
  96. $password='root';
  97. $query = new Query($dsn,$username,$password);
  98. // 使用回调方式,调用Query类
  99. return call_user_func_array([$query,$name],$args);
  100. }
  101. }
  102. // 实际使用
  103. // 查询操作 返回关联数组结果集
  104. $users = DB::table('users')->where('id','3','>')->select();
  105. // $users = DB::table('users')->field('id,name,email')->where('id','3','>')->select();
  106. // $users = DB::table('users')->field('id,name,email')->where('id','3','>')->limit(2)->select();
  107. // 插入操作 返回插入记录条数
  108. // $users = DB::table('users')->insert( ['name'=> '小燕子','email'=>'xyz@php.cn', 'password'=>sha1('123456')] );
  109. // 删除操作 返回受影响行数
  110. // $users = DB::table('users')->where('id',2)->delete( );
  111. // $users = DB::table('users')->delete( 14 );
  112. // 更新操作 返回受影响行数
  113. // $users = DB::table('users')->where('id','10')->update(['name'=> '金锁3','email'=>'js3@php.cn', 'password'=>sha1('333')]);
  114. // 打印执行结果
  115. print_r($users);

__sleep()与__wakeup()实例使用

  1. __sleep()是被序列化时调用,__wakeup()被反序列化时调用
  1. <?php
  2. // 自定义实例实现序列化时的__sleep()与__wakeup()功能
  3. class DbConnection
  4. {
  5. // 连接参数
  6. private $params = [];
  7. // 连接对象
  8. private $link = null;
  9. // 初始化操作
  10. public function __construct($dsn, $username, $password)
  11. {
  12. $this->params['dsn'] = $dsn;
  13. $this->params['username'] = $username;
  14. $this->params['password'] = $password;
  15. $this->connect();
  16. }
  17. // 连接数据库赋值给属性link
  18. public function connect()
  19. {
  20. // 实例化到属性link 后续操作在link操作
  21. $this->link = new PDO(...array_values($this->params));
  22. }
  23. // 对象被序列化时调用,返回数组
  24. public function __sleep():array
  25. {
  26. // 序列化前将密码进行字符混合加密
  27. $this->params['password'] = base64_encode($this->params['password'].'tlilam');
  28. // 必须返回数组,里面的元素是返回的属性名称
  29. return ['params'];
  30. }
  31. // 对象被反序列化时调用,不需要返回值
  32. public function __wakeUp()
  33. {
  34. // 进行解码,然后去除掉混入字符
  35. $this->params['password'] = str_replace('tlilam','',base64_decode($this->params['password']));
  36. $this->connect();
  37. // 不需要返回值,进行操作即可
  38. }
  39. // 查询操作
  40. public function select($sql)
  41. {
  42. return $this->link->query($sql)->fetchAll(PDO::FETCH_ASSOC);
  43. }
  44. }
  45. // 参数赋值并且进行实例化
  46. $dsn = 'mysql:host=localhost;dbname=phpedu';
  47. $username='root';
  48. $password='root';
  49. $db = new DbConnection($dsn, $username, $password);
  50. // 序列化实例$db
  51. $str = serialize($db);
  52. // 打印序列化后的字符串
  53. echo $str;
  54. // 反序列化对象字符串
  55. $ss = unserialize($str);
  56. // 打印反序列化后的ss是一个对象
  57. print_r($ss);
  58. // 测试反序列化后的SS执行select方法
  59. print_r($ss->select('select * from users limit 3'));
声明:本文内容转载自脚本之家,由网友自发贡献,版权归原作者所有,如您发现涉嫌抄袭侵权,请联系admin@php.cn 核实处理。
全部评论
文明上网理性发言,请遵守新闻评论服务协议