PHP的那些魔术方法(一)
在PHP中,有一堆魔术方法,服务于类和对象。PHP虽然也是纯种的面向对象语言,但是之前的PHP还真不是,所以有一些面向对象的标准实现并不完善,比如重载。但是,我们可以通过一些魔术方法来弥补,例如__call()方法就可以用来实现重载。
话不多说,我们一个一个的来看。
__construct()和__destruct()
这两个是非常出名并且也是非常常用的魔术方法。__construct()是构造函数。在Java中,构造函数是与类名相同的方法名,而PHP在早期的版本中也是这样的,但从5以后改成了__construct()方法来实现,原因是当类名进行修改的时候,可以不用再去修改这个方法名了。当然,我们用与类名相同的方法名也是可以向下兼容的,不过最好不要这样用。
__destruct()方法是析构函数,不需要显式的调用,系统会自动调用这个方法。而且析构函数不需要参数,因为它不需要去调用嘛,系统自动调用的时候也是不会去带参数的。
public function __construct()
{
echo '构造函数' . PHP_EOL;
}
public function __destruct()
{
echo '析构函数' . PHP_EOL;
}
__call()与__callStatic()
非常重要而且也是面试时经常会问到的魔术方法。它们俩的作用其实差不多,都是用于未定义的方法,当使用这些未定义的方法时就会进入这两个函数中。比如说我们调用$a->b();这个方法,但其实在$a的类模板中并没有b()方法,这时就会进入__call()方法进行处理。__callStatic()则是通过静态调用时如果没有定义对应的方法,就进入到__callStatic()方法中,如A::b(),并没有定义b()方法,这时就进入了__callStatic()中进行处理。
开头说道,__call()可以实现类似于Java中的函数重载的能力。函数重载其实就是同名的函数,但参数或返回值不同,在Java等强类型语言中可以方便的实现,但PHP是弱类型语言,无法准确的定位方法的重载,使用__call()方法其实也需要很多的判断,并不是非常的推荐一定要和Java一样的去实现函数重载。我们还是需要根据语言的特性来对业务功能进行深入的分析后再进行对应的实现。
在Laravel框架中,使用的Facade模式,也就是门面模式,核心代码就是使用了__callStatic()方法。有兴趣的小伙伴可以自行查看下Laravel的源码。
public function __call($name, $arguments)
{
echo '===call===' . PHP_EOL;
echo '未定义的方法找我' . PHP_EOL;
echo '您需要的是' . $name . ',参数是:';
print_r($arguments);
echo '===call===' . PHP_EOL;
}
public static function __callStatic($name, $arguments)
{
echo '===callStatic===' . PHP_EOL;
echo '未定义的静态方法找我' . PHP_EOL;
echo '您需要的是' . $name . ',参数是:';
print_r($arguments);
echo '===callStatic===' . PHP_EOL;
}
$name参数是方法的名称,如$a->b(),$name的值就是"b"。$arguments是参数数组,如$a->b("1",2);则$arguments=["1", 2];
__set()和__get()
上面的__call()方法针对的是未定义的方法。而__set()和__get()则是操作不可访问的属性。注意,这里并不是指没有定义的属性,如果定义为private的属性也可以通过这两个魔术方法来进行定义,当然,也包括未定义的属性。这两个属性其实可以对应Java中对于Java Bean的属性封装。
例如$a->p=1;,两种情况:
- 我们没有定义$p这个属性
- 我们定义了$p,但是是private $p;
以上两种情况都适用于__set()和__get()魔术方法。
public function __set($name, $value)
{
echo '===set===' . PHP_EOL;
echo '给不可访问的属性赋值时找我' . PHP_EOL;
echo '您需要的是' . $name . ',值是:' . $value . PHP_EOL;
echo '===set===' . PHP_EOL;
if ($name == 'a') {
$this->$name = $value;
}
}
public function __get($name)
{
echo '===get===' . PHP_EOL;
echo '获取不可访问的属性赋值时找我' . PHP_EOL;
echo '您需要的是' . $name . PHP_EOL;
echo '===get===' . PHP_EOL;
return $this->$name;
}
__isset()与__unset()
这两个就很好理解了,从字面意思也可以看出,一个是在使用isset()时会触发,而另一个则是在使用unset()时会触发。
需要注意的是,__isset()是在isset()和empty()时都会进行触发。都是在判断属性是否存在或者是否为空时可以进行一些操作,也是属性封装相关的操作函数。
public function __isset($name)
{
echo '===isset===' . PHP_EOL;
echo '调用isset()或empty()时来找我了' . PHP_EOL;
echo '您要找的是' . $name . PHP_EOL;
echo '===isset===' . PHP_EOL;
return property_exists($this, $name);
}
public function __unset($name)
{
echo '===unset===' . PHP_EOL;
echo '调用unset()时来找我' . PHP_EOL;
echo '您要找的是' . $name . PHP_EOL;
echo '===unset===' . PHP_EOL;
}
这篇文章主要介绍的是几个非常常用的,而且在面试时出现频率也是非常高的魔术方法。在下一篇中将会介绍其它一些出现频率较低但更有意思的魔术方法。
完整代码:https://github.com/zhangyue0503/php/blob/master/newblog/PHPMagic.php
关注公众号:【硬核项目经理】获取最新文章
添加微信/QQ好友:【xiaoyuezigonggong/149844827】免费得PHP、项目管理学习资料
知乎、公众号、抖音、头条搜索【硬核项目经理】
B站ID:482780532
PHP的那些魔术方法(一)的更多相关文章
- PHP基础知识之魔术方法
__construct(), __destruct(), __call(), __callStatic(), __get(), __set(), __isset(), __unset(), __sle ...
- 前端学PHP之面向对象系列第二篇——魔术方法
× 目录 [1]构造方法 [2]析构方法 [3]不可访问属性[4]对象复制[5]字符串[6]对象不存在[7]自动加载类[8]串行化[9]函数调用 前面的话 php在面向对象部分有很多相关的魔术方法,这 ...
- PHP中的魔术方法(2)
1.__get.__set这两个方法是为在类和他们的父类中没有声明的属性而设计的__get( $property ) 当调用一个未定义的属性时访问此方法__set( $property, $value ...
- 魔术方法__sleep 和 __wakeup
感觉序列化和反序列化用得倒是比较少了,而json_encode和json_decode用得相对多,都是转化成串,进行入库.传输等.json更方便,但是序列化和反序列化结合这两个魔术方法使用倒还行< ...
- Python魔术方法-Magic Method
介绍 在Python中,所有以"__"双下划线包起来的方法,都统称为"Magic Method",例如类的初始化方法 __init__ ,Python中所有的魔 ...
- php魔术方法使用场景
php魔术方法-----__tostring(),__invoke,__call(),__callStatic ... __tostring(),__invoke() __tostring()方法是在 ...
- PHP中的魔术方法:__construct, __destruct , __call, __callStatic,__get, __set, __isset, __unset , __sleep, __wakeup, __toString, __set_state, __clone and __autoload
1.__get.__set 这两个方法是为在类和他们的父类中没有声明的属性而设计的: __get( $property ) 当调用一个未定义的属性时访问此方法: __set( $property, $ ...
- PHP 类中的魔术方法
定义: PHP类中以两个下画线“__”开头的方法被称为魔术方法. 分类: 例如:构造方法:__construct:析构方法:__destruct:动态重载:__set().__get().__call ...
- php中的魔术方法
__construct 构造器是一个魔术方法,当对象被实例化时它会被调用.在一个类声明时它常常是第一件做的事但是没得必要他也像其他任何方法在类中任何地方都可以声明,构造器也能像其他方法样继承.如果我们 ...
- PHP面向对象之魔术方法复习
魔术方法复习 2014-9-2 10:08:00 NotePad++ By jiancaigege 飞鸿影~========================= 1.__construct() 构造方法 ...
随机推荐
- spring-session-data-redis反序列化问题
springCloud项目,采用springSession,用户模块同时引入了spring-cloud-starter-security,在其他模块request.getSession()的时候抛了以 ...
- Dubbo系列讲解之扩展点实现原理分析【2万字分享】
Apache Dubbo 是一款微服务开发框架,它提供了 RPC通信 与 微服务治理 两大关键能力.这意味着,使用 Dubbo 开发的微服务,将具备相互之间的远程发现与通信能力, 同时利用 Dubbo ...
- ubuntu20.04 apache2 配置安装ssl证书
1. 获取SSL证书 根据自己的网站服务器来获取不同的ssl证书,我的服务器是ubuntu20.04. 证书如下: 00_***.key ## 私钥文件 01_CERTIFICATE_***_***. ...
- Javaweb学习——request&response
request对象的作用 request是服务器对浏览器访问请求的封装 访问请求参数,通过getParameter()方法获取传递参数的值. 在进行转发请求时,需要把一些参数传递到转发后的页面进行处理 ...
- virtualenv 创建python虚拟环境
为什么要创建python虚拟环境 在开发Python应用程序的时候,系统安装的Python3只有一个版本:3.4.所有第三方的包都会被pip安装到Python3的site-packages目录下. 如 ...
- 怎样在Qt中建立使用动态链接库
参考网址: https://blog.csdn.net/q496713258/article/details/6990837 qt 的学习网址: http://c.biancheng.net/view ...
- MySQL常用权限操作
MySQL常用权限操作 ** ubuntu mysql 8.0.21修改root密码 ** 1.查看默认安装密码: sudo cat /etc/mysql/debian.cnf 2. 登录mysql ...
- 剑指offer面试题4
1 #include<iostream> 2 using namespace std; 3 4 void replace(char ch[]) { 5 int count = 0; 6 i ...
- 网络操作系统VyOS之NAT实践
本文基于 网络操作系统VyOS应用实践(四) 修改,完善了实验细节及1-to-1 NAT部分. NAT NAT即网络地址转换,最常见的就是各种虚拟机工具的NAT模式,让虚拟机以宿主的网络地址与外网通讯 ...
- opencv入门系列教学(六)图像上的算术运算(加法、融合、按位运算)
0.序言 这一篇博客我们将学习图像的几种算术运算,例如加法,减法,按位运算等. 1.图像加法 我们可以通过OpenCV函数 cv.add() 或仅通过numpy操作 res=img1+img2 res ...