我可以使用实例化的Object作为数组键吗?

时间:2011-01-10 01:20:43

标签: php arrays object

例如:

$product = new Product("cat");

if(isset($sales[$product])){
     $sales[$product]++;
}
else{
     $sales[$product] = 1;
}

7 个答案:

答案 0 :(得分:45)

来自docs

  

数组和对象不能用作键。这样做会导致警告:非法偏移类型。

您可以为每个实例提供一个唯一ID或覆盖__toString(),以便它返回一些唯一的ID,例如。

$array[(string) $instance] = 42;

答案 1 :(得分:21)

您可以使用http://www.php.net/manual/en/class.splobjectstorage.php

$product = new Product("cat");
$sales = new SplObjectStorage();
if(isset($sales[$product])){
     $sales[$product]++;
}
else{
     $sales[$product] = 1;
}

它不是一个真正的数组,但具有相当数量的类似数组的功能和语法。但是,由于它是一个对象,由于其奇怪的foreach行为,它在php中表现得像一个错配,并且它与所有本机php数组函数不兼容。有时您会发现通过

将其转换为真实数组很有用
$arr = iterator_to_array($sales);

所以它与你的其余代码库一起玩得很好。

答案 2 :(得分:16)

有一个 spl_object_hash 函数,用于将唯一对象id作为字符串获取,可用作数组键。 http://php.net/manual/en/function.spl-object-hash.php

答案 3 :(得分:2)

integers and strings are allowed as array keys。如果你绝对需要这个功能,你可以编写一个实现ArrayAccess的类。

答案 4 :(得分:0)

如果对象是使用new stdClass()创建的简单预定义类,则将此类的json表示与json_encode一起使用可能是有效的选项。

$product = new stdClass();
$product->brand = "Acme";
$product->name = "Patator 3.14";

$product_key = json_encode($product);

if(isset($sales[$product_key])){
     $sales[$product_key]++;
}
else{
    $sales[$product_key] = 1;
}

但请记住,两个对象的相等性始终是商业模式的选择,必须仔细设计。

答案 5 :(得分:0)

您可以有两个数组:

Array 1 contains the keys:   |  Array 2 contains the values
+--------+-------------+     |  +--------+------------+
| index: | value:      |     |  | index: | value:     |
| 0      | Object(key) |     |  | 0      | sth(value) |
| 1      | Object(key) |     |  | 1      | sth(value) |
+--------+-------------+     |  +--------+------------+

您在数组1中搜索对象,
然后选择该对象的索引
将其用作数组2和
的索引 =>获取值

用php代码

public function getValue($ObjectIndexOfYourArray){
  foreach(array1 as $key => $value) {
    if($value == ObjectIndexOfYourArray){
      return array2[$key];
    }
  }
}

我希望对您有帮助

答案 6 :(得分:0)

我知道这个问题很老,而且 SplObjectStorage 有一些奇怪的行为(例如,当循环使用 foreach 时)。

截至今天,我写了一个名为 linked-hash-map (https://github.com/tonix-tuft/linked-hash-map) 的库,它在 PHP 中实现了关联数组/哈希映射/哈希表,并允许您使用任何 PHP 数据类型关键:

<?php

use LinkedHashMap\LinkedHashMap;

$map = new LinkedHashMap();
$map[true] = 'bool (true)';
$map[false] = 'bool (false)';
$map[32441] = 'int (32441)';
$map[-32441] = 'int (-32441)';
$map[2147483647] = 'int (2147483647)';
$map[-2147483648] = 'int (-2147483648)';
$map[PHP_INT_MAX - 100] = 'int (PHP_INT_MAX - 100)';
$map[PHP_INT_MIN] = 'int (PHP_INT_MIN)';
$map[0.5] = 'float/double (0.5)';
$map[-0.5] = 'float/double (-0.5)';
$map[123891.73] = 'float/double (123891.73)';
$map[-123891.73] = 'float/double (-123891.73)';
$map[PHP_INT_MAX + 10] = 'float/double (PHP_INT_MAX + 10)';
$map[PHP_INT_MIN - 10] = 'float/double (PHP_INT_MIN - 10)';
$map['abc'] = 'string (abc)';
$map["abcdef"] = "string (abcdef)";
$map['hfudsh873hu2ifl'] = "string (hfudsh873hu2ifl)";
$map["The quick brown fox jumps over the lazy dog"] =
  'string (The quick brown fox jumps over the lazy dog)';
$map[[1, 2, 3]] = 'array ([1, 2, 3])';
$map[['a', 'b', 'c']] = "array (['a', 'b', 'c'])";
$map[[1, 'a', false, 5, true, [1, 2, 3, ['f', 5, []]]]] =
  "array ([1, 'a', false, 5, true, [1, 2, 3, ['f', 5, []]]])";

class A {
}
$objA = new A();
$map[$objA] = "object (new A())";

// You can even use file handles/resources:
$fp = fopen(__DIR__ . '/private_local_file', 'w');
$map[$fp] = "resource (fopen())";

$ch = curl_init();
$map[$ch] = "resource (curl_init())";

// All the values can be retrieved later using the corresponding key, e.g.:
var_dump($map[[1, 2, 3]]); // "array ([1, 2, 3])"
var_dump($map[$objA]); // "object (new A())"
var_dump($map[$ch]); // "resource (curl_init())"