位置: 编程技术 - 正文

PHP之十六个魔术方法详细介绍(php5魔术方法)

编辑:rootadmin

推荐整理分享PHP之十六个魔术方法详细介绍(php5魔术方法),希望有所帮助,仅作参考,欢迎阅读内容。

文章相关热门搜索词:php5魔术方法,简述php中常用魔术方法及其各自的作用,php常用的魔术方法有哪些,php魔术方法autoload,php常用的魔术方法有哪些,php常用的魔术方法有哪些,php魔术方法的讲解与使用,php 魔术方法 get,内容如对您有帮助,希望把文章链接给更多的朋友!

PHP中把以两个下划线__开头的方法称为魔术方法(Magic methods),这些方法在PHP中充当了举足轻重的作用。 魔术方法包括:

__construct(),类的构造函数 __destruct(),类的析构函数 __call(),在对象中调用一个不可访问方法时调用 __callStatic(),用静态方式中调用一个不可访问方法时调用 __get(),获得一个类的成员变量时调用 __set(),设置一个类的成员变量时调用 __isset(),当对不可访问属性调用isset()或empty()时调用 __unset(),当对不可访问属性调用unset()时被调用。 __sleep(),执行serialize()时,先会调用这个函数 __wakeup(),执行unserialize()时,先会调用这个函数 __toString(),类被当成字符串时的回应方法 __invoke(),调用函数的方式调用一个对象时的回应方法 __set_state(),调用var_export()导出类时,此静态方法会被调用。 __clone(),当对象复制完成时调用 __autoload(),尝试加载未定义的类 __debugInfo(),打印所需调试信息

范例

下面让我们以实例的形式向大家讲解下这几个魔术方法时如何使用的。

一、 __construct(),类的构造函数

php中构造方法是对象创建完成后第一个被对象自动调用的方法。在每个类中都有一个构造方法,如果没有显示地声明它,那么类中都会默认存在一个没有参数且内容为空的构造方法。

1、 构造方法的作用

通常构造方法被用来执行一些有用的初始化任务,如对成员属性在创建对象时赋予初始值。

2、 构造方法的在类中的声明格式

3、 在类中声明构造方法需要注意的事项

1、在同一个类中只能声明一个构造方法,原因是,PHP不支持构造函数重载。

2、构造方法名称是以两个下画线开始的__construct()

下面是它的例子:

创建对象$Person1且不带任参数

创建对象$Person2且带参数“小明”

创建对象$Person3且带三个参数

二、__destruct(),类的析构函数

通过上面的讲解,现在我们已经知道了什么叫构造方法。那么与构造方法对应的就是析构方法。

析构方法允许在销毁一个类之前执行的一些操作或完成一些功能,比如说关闭文件、释放结果集等。

析构方法是PHP5才引进的新内容。

析造方法的声明格式与构造方法 __construct() 比较类似,也是以两个下划线开始的方法 __destruct() ,这种析构方法名称也是固定的。

1、 析构方法的声明格式

注意:析构函数不能带有任何参数。

2、 析构方法的作用

一般来说,析构方法在PHP中并不是很常用,它属类中可选择的一部分,通常用来完成一些在对象销毁前的清理任务。举例演示,如下:

上面的程序运行时输出:

我觉得我还可以再抢救一下,我的名字叫小明

三、 __call(),在对象中调用一个不可访问方法时调用。

该方法有两个参数,第一个参数 $function_name 会自动接收不存在的方法名,第二个 $arguments 则以数组的方式接收不存在方法的多个参数。

1、 __call() 方法的格式:

2、 __call() 方法的作用:

为了避免当调用的方法不存在时产生错误,而意外的导致程序中止,可以使用 __call() 方法来避免。

该方法在调用的方法不存在时会自动调用,程序仍会继续执行下去。

请参考如下代码:

运行结果:

你所调用的函数:run(参数:Array ( [0] => teacher ) )不存在!

你所调用的函数:eat(参数:Array ( [0] => 小明 [1] => 苹果 ) )不存在!

Hello, world!

四、 __callStatic(),用静态方式中调用一个不可访问方法时调用

此方法与上面所说的 __call() 功能除了 __callStatic() 是未静态方法准备的之外,其它都是一样的。

请看下面代码:

运行结果如下:

你所调用的静态方法:run(参数:Array ( [0] => teacher ) )不存在!你所调用的静态方法:eat(参数:Array ( [0] => 小明 [1] => 苹果 ) )不存在!Hello, world!

五、 __get(),获得一个类的成员变量时调用

在 php 面向对象编程中,类的成员属性被设定为 private 后,如果我们试图在外面调用它则会出现“不能访问某个私有属性”的错误。那么为了解决这个问题,我们可以使用魔术方法 __get()。

魔术方法__get()的作用

在程序运行过程中,通过它可以在对象的外部获取私有成员属性的值。

我们通过下面的 __get() 的实例来更进一步的连接它吧:

运行结果:

姓名:小明年龄:

六、 __set(),设置一个类的成员变量时调用

__set() 的作用:

__set( $property, $value )` 方法用来设置私有属性, 给一个未定义的属性赋值时,此方法会被触发,传递的参数是被设置的属性名和值。

请看下面的演示代码:

运行结果:

我叫小红,今年岁了

七、 __isset(),当对不可访问属性调用isset()或empty()时调用

在看这个方法之前我们看一下isset()函数的应用,isset()是测定变量是否设定用的函数,传入一个变量作为参数,如果传入的变量存在则传回true,否则传回false。

那么如果在一个对象外面使用isset()这个函数去测定对象里面的成员是否被设定可不可以用它呢?

分两种情况,如果对象里面成员是公有的,我们就可以使用这个函数来测定成员属性,如果是私有的成员属性,这个函数就不起作用了,原因就是因为私有的被封装了,在外部不可见。那么我们就不可以在对象的外部使用isset()函数来测定私有成员属性是否被设定了呢?当然是可以的,但不是一成不变。你只要在类里面加上一个__isset()方法就可以了,当在类外部使用isset()函数来测定对象里面的私有成员是否被设定时,就会自动调用类里面的__isset()方法了帮我们完成这样的操作。

__isset()的作用:当对不可访问属性调用 isset() 或 empty() 时,__isset() 会被调用。

请看下面代码演示:

运行结果如下:

1 // public 可以 isset()当在类外部使用isset()函数测定私有成员name时,自动调用 // __isset() 内 第一个echo1 // __isset() 内第二个echo当在类外部使用isset()函数测定私有成员age时,自动调用 // __isset() 内 第一个echo1 // __isset() 内第二个echo

八、 __unset(),当对不可访问属性调用unset()时被调用。

看这个方法之前呢,我们也先来看一下 unset() 函数,unset()这个函数的作用是删除指定的变量且传回true,参数为要删除的变量。

那么如果在一个对象外部去删除对象内部的成员属性用unset()函数可以吗?

这里自然也是分两种情况:

1、 如果一个对象里面的成员属性是公有的,就可以使用这个函数在对象外面删除对象的公有属性。

2、 如果对象的成员属性是私有的,我使用这个函数就没有权限去删除。

虽然有以上两种情况,但我想说的是同样如果你在一个对象里面加上__unset()这个方法,就可以在对象的外部去删除对象的私有成员属性了。在对象里面加上了__unset()这个方法之后,在对象外部使用“unset()”函数删除对象内部的私有成员属性时,对象会自动调用__unset()函数来帮我们删除对象内部的私有成员属性。

请看如下代码:

运行结果:

当在类外部使用unset()函数来删除私有成员时自动调用的1当在类外部使用unset()函数来删除私有成员时自动调用的

九、 __sleep(),执行serialize()时,先会调用这个函数

serialize() 函数会检查类中是否存在一个魔术方法 __sleep()。如果存在,则该方法会优先被调用,然后才执行序列化操作。

此功能可以用于清理对象,并返回一个包含对象中所有应被序列化的变量名称的数组。

如果该方法未返回任何内容,则 NULL 被序列化,并产生一个 E_NOTICE 级别的错误。

注意:

__sleep() 不能返回父类的私有成员的名字。这样做会产生一个 E_NOTICE 级别的错误。可以用 Serializable 接口来替代。作用:

__sleep() 方法常用于提交未提交的数据,或类似的清理操作。同时,如果有一些很大的对象,但不需要全部保存,这个功能就很好用。

具体请参考如下代码:

代码运行结果:

PHP之十六个魔术方法详细介绍(php5魔术方法)

当在类外部使用serialize()时会调用这里的__sleep()方法O:6:"Person":2:{s:4:"name";s:8:"5bCP5piO";s:3:"age";i:;}

十、 __wakeup(),执行unserialize()时,先会调用这个函数

如果说 __sleep() 是白的,那么 __wakeup() 就是黑的了。

那么为什么呢?

因为:

与之相反,`unserialize()` 会检查是否存在一个 `__wakeup()` 方法。如果存在,则会先调用 `__wakeup` 方法,预先准备对象需要的资源。

作用:

__wakeup() 经常用在反序列化操作中,例如重新建立数据库连接,或执行其它初始化操作。

还是看代码:

运行结果:

当在类外部使用serialize()时会调用这里的__sleep()方法string() "O:6:"Person":2:{s:4:"name";s:8:"5bCP5piO";s:3:"age";i:;}" 当在类外部使用serialize()时会调用这里的__sleep()方法当在类外部使用unserialize()时会调用这里的__wakeup()方法object(Person)#2 (3) { ["sex"]=> string(3) "男" ["name"]=> int(2) ["age"]=> int() }

十一、 __toString(),类被当成字符串时的回应方法

作用:

__toString() 方法用于一个类被当成字符串时应怎样回应。例如 `echo $obj;` 应该显示些什么。

注意:

此方法必须返回一个字符串,否则将发出一条 `E_RECOVERABLE_ERROR` 级别的致命错误。

警告:

不能在 __toString() 方法中抛出异常。这么做会导致致命错误。

代码:

结果:

go go go

那么如果类中没有 __toString() 这个魔术方法运行会发生什么呢?让我们来测试下:

代码:

结果:

Catchable fatal error: Object of class Person could not be converted to string in D:phpStudyWWWtestindex.php on line 很明显,页面报了一个致命错误,这是语法所不允许的。

十二、 __invoke(),调用函数的方式调用一个对象时的回应方法

作用:

当尝试以调用函数的方式调用一个对象时,__invoke() 方法会被自动调用。

注意:

本特性只在 PHP 5.3.0 及以上版本有效。

直接上代码:

查看运行结果:

这可是一个对象哦

当然,如果你执意要将对象当函数方法使用,那么会得到下面结果:

Fatal error: Function name must be a string in D:phpStudyWWWtestindex.php on line

十三、 __set_state(),调用var_export()导出类时,此静态方法会被调用。

作用:

自 PHP 5.1.0 起,当调用 var_export() 导出类时,此静态方法会被自动调用。

参数:

本方法的唯一参数是一个数组,其中包含按 array('property' => value, ...) 格式排列的类属性。

下面我们先来看看在没有加 __set_state() 情况按下,代码及运行结果如何:

上代码:

看结果:

Person::__set_state(array( 'sex' => '男', 'name' => '小明', 'age' => , ))

很明显,将对象中的属性都打印出来了

加了 __set_state() 之后:

继续上代码:

继续看结果:

Person::__set_state(array( 'sex' => '男', 'name' => '小红', 'age' => , ))

十四、 __clone(),当对象复制完成时调用

在多数情况下,我们并不需要完全复制一个对象来获得其中属性。但有一个情况下确实需要:如果你有一个 GTK 窗口对象,该对象持有窗口相关的资源。你可能会想复制一个新的窗口,保持所有属性与原来的窗口相同,但必须是一个新的对象(因为如果不是新的对象,那么一个窗口中的改变就会影响到另一个窗口)。还有一种情况:如果对象 A 中保存着对象 B 的引用,当你复制对象 A 时,你想其中使用的对象不再是对象 B 而是 B 的一个副本,那么你必须得到对象 A 的一个副本。

作用:

对象复制可以通过 clone 关键字来完成(如果可能,这将调用对象的 __clone() 方法)。对象中的 __clone() 方法不能被直接调用。

语法:

$copy_of_object = clone $object;

注意:

当对象被复制后,PHP 5 会对对象的所有属性执行一个浅复制(shallow copy)。所有的引用属性 仍然会是一个指向原来的变量的引用。

当复制完成时,如果定义了 __clone() 方法,则新创建的对象(复制生成的对象)中的 __clone() 方法会被调用,可用于修改属性的值(如果有必要的话)。看代码:

看结果:

Person::__clone你正在克隆对象string(9) "persion1:" object(Person)#1 (3) { ["sex"]=> string(3) "男" ["name"]=> string(6) "小明" ["age"]=> int() } string(9) "persion2:" object(Person)#2 (3) { ["sex"]=> string(3) "男" ["name"]=> string(6) "小明" ["age"]=> int() }

克隆成功。

十五、__autoload(),尝试加载未定义的类

作用:

你可以通过定义这个函数来启用类的自动加载。

在魔术函数 __autoload() 方法出现以前,如果你要在一个程序文件中实例化个对象,那么你必须用include或者require包含进来个类文件,或者你把这个类定义在同一个类文件中 —— 相信这个文件一定会非常大,然后你就痛苦了。

但是有了 __autoload() 方法,以后就不必为此大伤脑筋了,这个类会在你实例化对象之前自动加载制定的文件。

还是通过例子来看看吧:

先看看以往的方式:

看到了吗?不用个,只是3个看起来就有点烦了。而且这样就会有一个问题:如果脚本执行“条件B”这个分支时,C.php这个文件其实没有必要包含。因为,任何一个被包含的文件,无论是否使用,均会被php引擎编译。如果不使用,却被编译,这样可以被视作一种资源浪费。更进一步,如果C.php包含了D.php,D.php包含了E.php。并且大部分情况都执行“条件B”分支,那么就会浪费一部分资源去编译C.php,D.php,E.php三个“无用”的文件。

那么如果使用 __autoload() 方式呢?

ok,不论效率怎么用,最起码界面看起来舒服多了,没有太多冗余的代。

再来看看这里的效率如何,我们分析下:

当php引擎第一次使用类A,但是找不到时,会自动调用 __autoload 方法,并将类名“A”作为参数传入。所以,我们在 __autoload() 中需要的做的就是根据类名,找到相应的文件,并包含进来,如果我们的方法也找不到,那么php引擎就会报错了。

注意:

这里可以只用require,因为一旦包含进来后,php引擎再遇到类A时,将不会调用__autoload,而是直接使用内存中的类A,不会导致多次包含。

扩展:

其实php发展到今天,已经有将 `spl_autoload_register` — 注册给定的函数作为 __autoload 的实现了,但是这个不在啊本文讲解之内,有兴趣可以自行看手册。

十六、__debugInfo(),打印所需调试信息

注意:

该方法在PHP 5.6.0及其以上版本才可以用,如果你发现使用无效或者报错,请查看啊你的版本。

看代码:

结果:

object(C)#1 (1) { ["propSquared"]=> int() }

再次注意:

这里的 `**` 是乘方的意思,也是在PHP5.6.0及其以上才可以使用,详情请查看PHP手册

总结

标签: php5魔术方法

本文链接地址:https://www.jiuchutong.com/biancheng/301436.html 转载请保留说明!

上一篇:php有效防止图片盗用、盗链的两种方法(php隐藏图片地址)

下一篇:CI框架(ajax分页,全选,反选,不选,批量删除)完整代码详解(使用ajax实现页面分页)

  • 小规模企业所得税2023年税收政策
  • 增值税一般纳税人和小规模纳税人的区别
  • 预缴企业所得税计税依据
  • 小微企业所得税减免政策
  • 金蝶专业版仓库反审核怎么做
  • 研发费用成本化和费用化
  • 工程款和借款能一起诉讼吗
  • 企业所得税申报表A类
  • 隔月发票红冲操作流程
  • 现金支付借款如何认定
  • 应付股东款可以结转实收资本吗
  • 充值卡充值发票可以报销吗
  • 股东取得利息收入如何纳税
  • 收到运输发票需要开票吗
  • 应收账款转销怎么记账
  • 水泥厂水泥增值税率是多少?
  • 跨年度的应收账款少记了怎么办
  • 增值税价外费用不包括
  • 收到财政拨款开什么票据
  • 行政单位以前年度会计错账调整
  • 贸易企业出口退税的操作明细流程
  • windows11我的电脑怎么放到桌面
  • windows10如何添加英文输入法
  • 公司暂估成本过高,如何处理
  • 生产企业结账流程
  • 水养绿萝怎么养护长得才茂盛
  • 税收返还需要缴纳什么税
  • php zmq
  • 家里装饰镜太多了怎么化解
  • 深入php:面向对象、模式与实践
  • 存货的盘亏损毁和报废
  • 什么叫股权溢价之谜?
  • command对象可以执行sql语句吗
  • 接受捐赠固定资产的改建支出
  • 小规模单位没交五险一金
  • nginx解决跨域问题原理
  • br命令怎么用
  • wordpress建立数据库错误
  • 运输途中发生的费用
  • php命令行模式
  • 代销手续费未付怎么处理
  • 合并会计报表合并范围
  • sql server分为哪两类
  • 一般纳税人一直零申报会怎么样
  • 企业返聘退休人员需要交社保吗
  • 出货后90天付款
  • 去年多摊销了怎么办
  • 收到费用发票没有付款的会计分录
  • 建筑行业工程施工当月可以不结转吗
  • 资产减值损失如何计提
  • 跨年红冲收入记在本年度
  • 公司买车可以抵税几年
  • 固定资产为什么提折旧,有何实际意义
  • 产成品核算的内容
  • CentOS 7.2下MySQL的安装与相关配置
  • 计算机上没有运行windows无线服务
  • 深度技术win11
  • redhat 7.0
  • rhel7.4安装
  • windrv.exe
  • win7系统开机蓝屏0x0000007b
  • ubuntu rar压缩
  • centos挂载lun
  • 苹果发布首款MR头显
  • linux系统怎么增大磁盘io
  • 如何搭建react项目
  • jQuery实现select模糊查询(反射机制)
  • android图片布局
  • javascript题
  • python如何处理文本
  • node 回调函数
  • 玩端游的平台
  • jquery ztree实现树的搜索功能
  • JavaScript中的数据类型分为两大类
  • Android调用系统的电话拨号程序
  • 河南医疗保险网上怎么缴费截止时间
  • 广西公安厅有几个处长
  • 贵州省地方税务局税源管理平台(二次)招标合同公告
  • 外经证注销网上操作
  • 特斯拉购车补贴2023苏州
  • 免责声明:网站部分图片文字素材来源于网络,如有侵权,请及时告知,我们会第一时间删除,谢谢! 邮箱:opceo@qq.com

    鄂ICP备2023003026号

    网站地图: 企业信息 工商信息 财税知识 网络常识 编程技术

    友情链接: 武汉网站建设