我发现了一些有趣的事情: in_array()函数不仅在“指针”是特定值时有效,而且在它是特定对象实例时也有效。我举个例子:
class Message{
private $str;
function __construct($str){
$this->str= $str;
}
}
$message1 = new Message('Hey there!');
$message2 = new Message('sup');
$message3 = new Message('yo');
$arr= [$message2, 545,'hey'];
echo in_array($message2 ,$arr) ? 'true' : 'false';
正如您所看到的,我正在创建某个类的不同实例。将对这些实例之一的引用放入数组中。
当我检查数组中是否存在"message2“对象时,我得到了true。如果我将指针改为"message1“或"message3",我会得到false。
这是怎么回事?文档说它“检查数组中是否存在一个值”。但是引用一个对象是一个“值”吗?有人能澄清这个问题吗?
发布于 2018-07-25 02:07:44
从PHP docs
从PHP5开始,对象变量不再包含对象本身作为值。它只包含一个对象标识符,允许对象访问者找到实际的对象。当对象通过参数发送、返回或赋值给另一个变量时,不同的变量不是别名:它们持有指向同一对象的标识符的副本。
在"OOP“PHP (即PHP < 5)出现之前,所有变量都是通过值传递的。您始终可以使用&
运算符通过引用传递变量,尽管这与使用指针的C等语言不同。在PHP5+中,对象不是通过引用传递的,但是对象变量并不包含对象本身,而是对象的标识符。当您将该变量传递给函数时,该标识符的副本将作为参数发送,就像任何其他原语一样。
要理解的最重要的事情是,当您将一个对象传递给一个函数时,对象本身并不被传递,而是一个标识符被传递给一个对象。这些标识符提供对对象本身的访问,同时仍然允许您在实例之间执行数组搜索和相等比较(===
)。
虽然PHP文档有点晦涩,但我们可以看到对象标识符实际上是一个值:
不同的变量不是别名:它们保存了指向同一对象的标识符的副本。
包含对象的变量的值是对象标识符,而不是对象本身。
// $obj contains an identifier to an instance of `MyObject`
$obj = new MyObject();
当您将$obj
传递给函数时,该标识符的副本将作为参数发送。PHP 总是通过值传递变量,除非显式指示使用&$var
通过引用传递。因此,为了回答您的问题,对对象的引用(或者更确切地说,标识符)实际上是一个可用于比较对象的特定实例的值。
编辑
正如@Chris Anderson和@Lou指出的那样,in_array
默认情况下会进行松散比较。在比较两个对象时,==
会检查它们是否是相同的实例并且具有相同的属性值,而===
会检查它们是否是同一个类的实例。除非我误解了,否则你最初的问题是关于存储类实例的变量的行为的本质,所以我最初的答案应该足以回答手头的问题。但是,重要的是要注意,如果对象的值相同,则在没有显式请求严格比较(===
)的情况下,您将获得true
。
发布于 2018-07-25 04:29:42
class Message{
private $str;
function __construct($str){
$this->str= $str;
}
}
$message1 = new Message('Hey there!');
$message2 = new Message('yo');
$message3 = new Message('yo');
$arr = [$message2, 545,'hey'];
//loose comparison using ==
echo in_array($message3 ,$arr) ? 'true' : 'false'; // returns true
//strict comparison using ===
echo in_array($message3 ,$arr, true) ? 'true' : 'false'; // returns false
in_array()
bool in_array ( mixed $needle , array $haystack [, bool $strict = FALSE ] )
除非设置了strict,否则
将使用宽松比较来搜索针。
宽松比较(==) :
使用比较运算符(==)时,对象变量以一种简单的方式进行比较,即:如果两个对象实例具有相同的属性和值(值与==进行比较),并且是同一类的实例,则它们是相等的。
严格比较(===):
使用标识运算符(===)时,当且仅当对象变量引用相同类的相同实例时,它们才相同。
https://stackoverflow.com/questions/51504841
复制相似问题