浅谈PHP中的面向对象OOP中的魔术方法


Posted in PHP onJune 12, 2017

一、什么是魔术方法:

PHP为我们提供了一系列用__开头的函数,这些函数无需自己手动调用,会在合适的时机自动调用,这类函数称为魔术函数。
例如:

function __construct(){} 在new一个新对象时自动调用此函数

二、PHP中都有那些魔术方法,以及它们的作用:

1.__construct():构造函数,new对象时自动调用

eg:

class Person{
    public $name;
    public $age;
    
    function __construct($name,$age){
      $this->name=$name;
      $this->age=$age;
    }
}

 在new新的Person对象时会自动调用__construct()函数,将传入的参数分别赋给$name,$age。

2.__destruct():析构函数,当一个对象被销毁前自动调用

class Person{
    public $name;
    public $age;
    
    function __destruct(){
    echo "这个对象被销毁了";
  }
}

同上所述,对象被销毁时执行此魔术方法

3.__get():访问类中私有属性时自动调用,传递读取属性名,返回$this->属性名

class Person{
    private $name;
    public $age;
    
    function __get($name){
     return $this->$name;
    }
}

如上代码,$name被设为私有属性后不能直接通过$this->name;的方式读取,因此需要设置__get()魔术方法来读取。

4.__set():给类的私有属性赋值时自动调用,传递需设置的属性名,属性值

class Person{
    private $name;
    public $age;
    
    function __set($key,$value){
      $this->$key=$value;
    }
}

同__get()方法,私有属性不能通过$this->name="aaa";的方式直接设置,需要设置__set()方法,传入的参数分别是属性名和属性值。

5.__isset():使用isset检测对象私有属性时调用,传递检测的属性名,返回isset($this->属性名)

class Person{
    private $name;
    public $age;
    
    function __isset($name){
    return isset($this->$name);
  }
}

使用isset检测对象私有属性时调用,其他同上。

6.__unset():使用unset()函数删除对象私有属性时调用,传递删除的属性名,方法中执行unset($this->属性名)

class Person{
    private $name;
    public $age;
    
    function __unset($name){
      unset($this->$name);
    }
}

同上,在用unset()函数删除私有属性时调用。

7.__toString():使用echo打印对象时调用,返回打印对象时想要显示的内容,返回必须是字符串

class Person{
    public $name;
    public $age;
    
    function __toString(){
      $str = <<<str
      您要打印的内容是:<br>
      \$name=>{$this->name};<br>
      \$age=>{$this->age};<br>
str;
      return $str;
    }
}

使用echo打印对象时调用,返回打印对象时想要显示的内容。

8.__call():调用一个类中未定义的或未公开的方法时自动调用,传递被调用的函数名及参数列表

class Person{
    public $name;
    public $age;
    
    function __call($funcName,$funcParams){
      echo "您调用的函数{$funcName},参数列表";
      print_r($funcParams);
      echo "不存在/未公开";
    }
}
$zhangsan=new Person();
$zhangsan->say(1,2,3);

如代码所示,调用不存在的say(1,2,3);时,会打印

您调用的函数way,参数列表Array ( [0] => 123 ) 不存在

9.__clone():当使用clone关键字,克隆一个对象时自动调用,作用是为新克隆的对象初始化赋值

class Person{
    public $name;
    public $age;
    
    function __clone(){
    $this->name="lisi";
    }
}  
$zhangsan=new Person("zhangsan",24);
$lisi=clone $zhangsan;
echo $lisi->name;

打印出的结果是"lisi",而不是"zhangsan"。

10.__sleep():对象序列化时自动调用,返回一个数组,数组中的值就是可以序列化的属性

class Person{
    public $name;
    public $age;
    
   function __sleep(){
    return array("name","age");
  }
}

如上述代码,在用serialize()序列化对象时只有"name","age"属性会被序列化。

11.__wakeup():对象反序列化时自动调用,为反序列化新产生的对象进行初始化赋值

class Person{
    public $name;
    public $age;
    
   function __wakeup(){
    $this -> name = "lisi";
  }
}

将对象序列化后再反序列化,同时给对象的name属性赋初值为"lisi"。

12.__autolode():需要在类外部声明函数,当实例化一个未声明的类时自动调用,传递实例化的类名,可以使用类名自动加载对应的类文件。

function __autoload($className){
  include "class/".strtolower($className).".class.php";
}
  
$zhangsan=new Person();
$zhangsan->say();

如上述代码,Person类不存在时调用__autolode()方法,载入写在文件外的类,"class/".strtolower($className).".class.php";就是类文件的相对路径,$className就是

不在本文件中的类的类名,因此在创建外部类文件时命名方式必须是小写的类名.class.php。__autolode()方法也是惟一一个不用写在类中的魔术方法。

以上就是PHP中的魔术方法,合理利用这些方法可以轻松实现对象的各种操作。希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

PHP 相关文章推荐
PHP 字符串正则替换函数preg_replace使用说明
Jul 15 PHP
PHP实现异步调用方法研究与分享
Oct 27 PHP
CI框架入门示例之数据库取数据完整实现方法
Nov 05 PHP
php5.3提示Function ereg() is deprecated Error问题解决方法
Nov 12 PHP
php使用wordwrap格式化文本段落的方法
Mar 17 PHP
PHP合并数组+号和array_merge的区别
Jun 25 PHP
php创建无限级树型菜单
Nov 05 PHP
PHP 中提示undefined index如何解决(多种方法)
Mar 16 PHP
PHP编辑器PhpStrom运行缓慢问题
Feb 21 PHP
浅谈PHP中new self()和new static()的区别
Aug 11 PHP
Yii2语言国际化自动配置详解
Aug 22 PHP
swoole锁的机制代码实例讲解
Mar 04 PHP
用php+ajax新建流程(请假、进货、出货等)
Jun 11 #PHP
详解PHP函数 strip_tags 处理字符串缺陷bug
Jun 11 #PHP
php模仿qq空间或朋友圈发布动态、评论动态、回复评论、删除动态或评论的功能(中)
Jun 11 #PHP
PHP中error_reporting函数用法详细介绍
Jun 11 #PHP
详解PHP处理字符串类似indexof的方法函数
Jun 11 #PHP
PHP获取文件扩展名的方法实例总结
Jun 10 #PHP
PHP获取数组中单列值的方法
Jun 10 #PHP
You might like
MySql 按时间段查询数据方法(实例说明)
2008/11/02 PHP
php代码收集表单内容并写入文件的代码
2012/01/29 PHP
Codeigniter的dom类用法实例
2015/06/26 PHP
thinkphp微信开之安全模式消息加密解密不成功的解决办法
2015/12/02 PHP
[原创]PHP字符串中插入子字符串方法总结
2016/05/06 PHP
Js event事件在IE、FF兼容性问题
2011/01/01 Javascript
iphone safari不支持position fixed的解决方法
2012/05/04 Javascript
appendChild() 或 insertBefore()使用与区别介绍
2013/10/11 Javascript
为jQuery添加Webkit的触摸的方法分享
2014/02/02 Javascript
jQuery抛物线运动实现方法(附完整demo源码下载)
2016/01/08 Javascript
Bootstrap 附加导航(Affix)插件实例详解
2016/06/01 Javascript
终于实现了!精彩的jquery弹幕效果
2016/07/18 Javascript
AngularJS入门教程之MVC架构实例分析
2016/11/01 Javascript
Bootstrap 下拉多选框插件Bootstrap Multiselect
2017/01/22 Javascript
javascript中神奇的 Date对象小结
2017/10/12 Javascript
vue配置请求本地json数据的方法
2018/04/11 Javascript
layui radio性别单选框赋值方法
2018/08/15 Javascript
vue 自定义组件的写法与用法详解
2020/03/04 Javascript
微信小程序的引导页实现代码
2020/06/24 Javascript
Python浅拷贝与深拷贝用法实例
2015/05/09 Python
python的dataframe转换为多维矩阵的方法
2018/04/11 Python
PyQT实现多窗口切换
2018/04/20 Python
Python函数参数操作详解
2018/08/03 Python
Python之循环结构
2019/01/15 Python
浅谈keras中自定义二分类任务评价指标metrics的方法以及代码
2020/06/11 Python
Python命名空间及作用域原理实例解析
2020/08/12 Python
Html5大文件断点续传实现方法
2015/12/05 HTML / CSS
南京软件公司的.net程序员笔试题
2014/08/31 面试题
工会主席岗位责任制
2014/02/11 职场文书
新学期决心书
2014/03/11 职场文书
公司外出活动方案
2014/08/14 职场文书
大学奖学金获奖感言
2014/08/15 职场文书
解放思想演讲稿
2014/09/11 职场文书
个人房屋买卖协议书(范本)
2014/10/04 职场文书
导游词之上海东方明珠塔
2019/09/25 职场文书
Spring Boot 底层原理基础深度解析
2022/04/03 Java/Android