PHP中的对象比较
在之前的文章中,我们讲过PHP中比较数组的时候发生了什么?。这次,我们来讲讲在对象比较的时候PHP是怎样进行比较的。
首先,我们先根据PHP文档来定义对象比较的方式:
- 同一个类的实例,比较属性大小,根据顺序,遇到不同的属性值后比较返回,后续的不会再比较
- 不同类的实例,比较属性值
- ===,必须是同一个实例
我们通过一个例子来看下:
function bool2str($bool)
{
if ($bool === false) {
return 'FALSE';
} else {
return 'TRUE';
}
}
function compareObjects(&$o1, &$o2)
{
echo 'o1 == o2 : ' . bool2str($o1 == $o2) . "\n";
echo 'o1 === o2 : ' . bool2str($o1 === $o2) . "\n";
}
class A {
private $t = true;
public function setT($t){
$this->t = $t;
}
}
class B {
protected $t = true;
public function setT1($t){
$this->t = $t;
}
}
class C {
private $t = true;
public function setT($t){
$this->t = $t;
}
}
$a1 = new A();
$a2 = new A();
compareObjects($a1, $a2); // 相同的类
// o1 == o2 : TRUE
// o1 === o2 : FALSE
$a11 = $a1;
compareObjects($a1, $a11); // 相同的实例
// o1 == o2 : TRUE
// o1 === o2 : TRUE
$a11->setT(false);
compareObjects($a1, $a11); // 相同实例属性值不同
// o1 == o2 : TRUE
// o1 === o2 : TRUE
$b = new B();
compareObjects($a1, $b); // 不同的类
// o1 == o2 : FALSE
// o1 === o2 : FALSE
$c = new C();
compareObjects($a1, $b); // 相同属性不同的类
// o1 == o2 : FALSE
// o1 === o2 : FALSE
从例子中,我们可以看出基本都是符合上述三个条件的,不过需要注意的是,在===的情况下,如果是同一个实例对象,属性值不同也会返回TRUE。我们再通过一个更复杂的例子来观察:
$c = new stdClass();
$d = new stdClass();
$c->t1 = 'c';
$c->t2 = 10;
$c->t3 = 50;
$d->t1 = 'c';
$d->t2 = 11;
$d->t3 = 40;
echo 'c > d:', $c > $d ? 'TRUE' : 'FALSE', PHP_EOL; // FALSE
echo 'c < d:', $c < $d ? 'TRUE' : 'FALSE', PHP_EOL; // TRUE
$d->t2 = 10; // $t2属性改成相等的
echo 'c > d:', $c > $d ? 'TRUE' : 'FALSE', PHP_EOL; // TRUE
echo 'c < d:', $c < $d ? 'TRUE' : 'FALSE', PHP_EOL; // FALSE
$d->t3 = 50; // $c、$d属性都相等了
echo 'c >= d:', $c >= $d ? 'TRUE' : 'FALSE', PHP_EOL; // TRUE
echo 'c <= d:', $c <= $d ? 'TRUE' : 'FALSE', PHP_EOL; // TRUE
echo 'c == d:', $c == $d ? 'TRUE' : 'FALSE', PHP_EOL; // TRUE
echo 'c === d:', $c === $d ? 'TRUE' : 'FALSE', PHP_EOL; // FALSE
$c1 = clone $c; // 复制同一个对象
echo 'c == c1:', $c == $c1 ? 'TRUE' : 'FALSE', PHP_EOL; // TRUE
echo 'c === c1:', $c === $c1 ? 'TRUE' : 'FALSE', PHP_EOL; // FALSE
$c1->t4 = 'f'; // 增加了一个属性
echo 'c > c1:', $c > $c1 ? 'TRUE' : 'FALSE', PHP_EOL; // TRUE
echo 'c < c1:', $c < $c1 ? 'TRUE' : 'FALSE', PHP_EOL; // FALSE
echo 'c == c1:', $c == $c1 ? 'TRUE' : 'FALSE', PHP_EOL; // FALSE
echo 'c === c1:', $c === $c1 ? 'TRUE' : 'FALSE', PHP_EOL; // FALSE
unset($c1->t4);
$c1->t1 = 'd'; // 修改了一个值
echo 'c == c1:', $c == $c1 ? 'TRUE' : 'FALSE', PHP_EOL; // FALSE
echo 'c === c1:', $c === $c1 ? 'TRUE' : 'FALSE', PHP_EOL; // FALSE
这个例子中,我们进行了<、>的对比,在这种对比中,都是根据属性值来进行比对的,而对比的顺序也是属性值的英文排序。当$t2有了不相等的比较结果时,$t3就不会再进行比对了。此外,clone之后的对象并不是原来的实例对象了,所以clone后的对象和原对象是无法用===来获得相等的结果的。当一个对象的属性比另一个对象多时,这个对象也会比属性少的对象大。
对象的比较其实和数组是有些类似的,但它们又有着些许的不同。一个重要的方面就是把握住它们都会进行属性比较,另外还有就是=的差别,数组中=必须是所有属性的类型都相同,而对象中则必须是同一个实例,而且对象只要是同一个实例,使用===就不会在乎它属性值的不同了。
参考文档:
https://www.php.net/manual/zh/language.oop5.object-comparison.php
===============
关注公众号:【硬核项目经理】获取最新文章
添加微信/QQ好友:【xiaoyuezigonggong/149844827】免费得PHP、项目管理学习资料
知乎、公众号、抖音、头条搜索【硬核项目经理】
B站ID:482780532
PHP中的对象比较的更多相关文章
- [转]ThinkPHP中实例化对象M()和D()的区别,select和find的区别
1.ThinkPHP中实例化对象M()和D()的区别 在实例化的过程中,经常使用D方法和M方法,这两个方法的区别在于M方法实例化模型无需用户为每个数据表定义模型类,如果D方法没有找到定义的模型类,则会 ...
- js中判断对象具体类型
大家可能知道js中判断对象类型可以用typeof来判断.看下面的情况 <script> alert(typeof 1);//number alert(typeof "2" ...
- 浅解析js中的对象
浅解析js中的对象 原文网址:http://www.cnblogs.com/foodoir/p/5971686.html,转载请注明出处. 前面的话: 说到对象,我首先想到的是每到过年过节见长辈的时候 ...
- js中XMLHttpRequest对象实现GET、POST异步传输
js中XMLHttpRequest对象实现GET.POST异步传输 /* * 统一XHR接口 */ function createXHR() { // IE7+,Firefox, Opera, Chr ...
- 浅谈Java中的对象和引用
浅谈Java中的对象和对象引用 在Java中,有一组名词经常一起出现,它们就是“对象和对象引用”,很多朋友在初学Java的时候可能经常会混淆这2个概念,觉得它们是一回事,事实上则不然.今天我们就来一起 ...
- Hibernate中Java对象的三种状态
Hibernate中Java对象的三种 ...
- 批量导出oracle中的对象
背景 Oracle数据库中有table,view,procedure,function,package,type等对象,需要将这些对象导出到不同的文件中.常用的方法有3种:1. 通过开发工具直接导出. ...
- 缓存依赖中cachedependency对象
缓存依赖主要提供以下功能:1.SQL 缓存依赖项可用于应用程序缓存和页输出缓存.2.可在 SQL Server 7.0 及更高版本中使用 SQL 缓存依赖项.3.可以在网络园(一台服务器上存在多个处理 ...
- JVM中,对象在内存中的布局
在hotSpot虚拟机中,对象在内存中的布局可以分成对象头.实例数据.对齐填充三部分. 对象头:主要包括: 1.对象自身的运行行元数据,比如哈希码.GC分代年龄.锁状态标志等,这部分长度在32位虚拟机 ...
- javascript中的对象,原型,原型链和面向对象
一.javascript中的属性.方法 1.首先,关于javascript中的函数/“方法”,说明两点: 1)如果访问的对象属性是一个函数,有些开发者容易认为该函数属于这个对象,因此把“属性访问”叫做 ...
随机推荐
- MongoDB-04-备份和恢复
mongodb备份和恢复 常用的备份恢复工具 1 ** mongoexport/mongoimport 2 ***** mongodump/mongorestore 备份工具区别在哪里 应用场景总结: ...
- Golang语言系列-01-Go语言简介和变量
Go语言简介 Go(又称Golang)是Google开发的一种静态强类型.编译型.并发型,并具有垃圾回收功能的编程语言. 罗伯特·格瑞史莫(Robert Griesemer),罗勃·派克(Rob Pi ...
- Prometheus alertmanager邮件发送+grafana告警展示
前言 前面一篇博客,我已经介绍了prometheus如何监控mysql. 这一篇我来介绍如何通过alertmanger进行告警邮件发送(微信或钉钉类似,因为需要企业帐户,我就不试了),以及如何通过gr ...
- ARM的九种寻址方式
文章目录 1.立即数寻址 2.寄存器寻址 3.寄存器间接寻址 4.寄存器偏移寻址 5.寄存器基址变址寻址 6.批量寄存器寻址 7.相对寻址 8.堆栈寻址 9.块拷贝寻址 寻址方式就是CPU根据指令中的 ...
- 【力扣leetcode】-787. K站中转内最便宜的航班
题目描述: 有 n 个城市通过一些航班连接.给你一个数组 flights ,其中 flights[i] = [fromi, toi, pricei] ,表示该航班都从城市 fromi 开始,以价格 p ...
- arthas-Java诊断工具
Arthas 是Alibaba开源的Java诊断工具,深受开发者喜爱. 官网:https://arthas.aliyun.com/zh-cn/ 当你遇到以下类似问题而束手无策时,Arthas可以帮助你 ...
- maven打jar包,导入本地jar
本地jar包存放目录 项目目录/lib/*.jar 导入jar包配置 <resources> <!--扫描到的配置yml--> <resource> <dir ...
- Javascript - Vue - webpack中的组件、路由和动画
引入vue.js 1.cnpm i vue -S 2.在mian.js中引入vue文件 import Vue from "vue"//在main.js中使用这种方式引用vue文件时 ...
- Timer和TimerTask(转载)
下面内容转载自: http://blog.csdn.net/xieyuooo/article/details/8607220 其实就Timer来讲就是一个调度器,而TimerTask呢只是一个实现了r ...
- Python如何读写Excel文件-使用xlrd/xlwt模块
时间: 2020-08-18 整理: qiyuan 安装和导入 1.模块介绍 在 python 中使用 xlrd/xlwt 和 openpyxl 模块可以对Excel电子表格(xls.xlsx文件)进 ...