欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

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

程序员文章站 2022-03-24 21:20:52
...

实现__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'));