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)如果访问的对象属性是一个函数,有些开发者容易认为该函数属于这个对象,因此把“属性访问”叫做 ...
随机推荐
- MySQL-15-主从复制
企业高可用性标准 1 全年无故障率(非计划内故障停机) 99.9% ----> 0.001*365*24*60=525.6 min 99.99% ----> 0.0001*365*24*6 ...
- 013 PCIe体系结构的组成部件
一.PCIe体系结构的组成部件 PCIe总线作为处理器系统的局部总线,其作用与PCI总线类似,主要目的是为了连接处理器系统中的外部设备,当然PCIe总线也可以连接其他处理器系统.在不同的处理器系统中, ...
- SQL 练习19
统计各科成绩各分数段人数:课程编号,课程名称,[100-85],[85-70],[70-60],[60-0] SELECT Course.CId,Course.Cname ,t.[0-60],t.[6 ...
- 源码安装nginx开启SSL功能
编译安装nginx的环境 yum -y install gcc zlib zlib-devel pcre-devel openssl openssl-devel 下载nginx安装包 cd /usr/ ...
- 图文详解两种算法:深度优先遍历(DFS)和广度优先遍历(BFS)
参考网址:图文详解两种算法:深度优先遍历(DFS)和广度优先遍历(BFS) - 51CTO.COM 深度优先遍历(Depth First Search, 简称 DFS) 与广度优先遍历(Breath ...
- HttpURLconnection的介绍
一,HttpURLconnection的介绍 在Android开发中网络请求是最常用的操作之一, Android SDK中对HTTP(超文本传输协议)也提供了很好的支持,这里包括两种接口: 1.标准J ...
- 【nodejs】express框架+mysql后台数据查询
一 环境部署 1,首先安装nodejs,并配置好环境变量(看自己习惯), 2,安装Express npm install express -g //全局安装 npm install express-g ...
- Java随手记录
Spring @Configuration注解及配置方法 转自:https://www.jb51.net/article/184822.htm Spring @Configuration注解 Spri ...
- Spring Data JPA:解析CriteriaBuilder
源码 在Spring Data JPA相关的文章[地址]中提到了有哪几种方式可以构建Specification的实例,该处需要借助CriteriaBuilder,回顾一下Specification中t ...
- reids rdb与aof
rdb:时合高并发场景,容易备份恢复,会丢失部分数据 1.默认开启的方式,可以进过压缩,可以根据时间点生成快照 2.数据量大的情况下恢复快 3.bgsave一边开启fork保存文件,一边继续响应客户端 ...