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

发布于 2024-10-11 01:10:30 字数 159 浏览 3 评论 0原文

例如:

$product = new Product("cat");

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

For example:

$product = new Product("cat");

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(8

尽揽少女心 2024-10-18 01:10:30

来自 文档

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

您可以为每个实例指定一个唯一的 ID 或覆盖 __toString() 这样它会返回一些独特的东西并执行例如

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

From the docs:

Arrays and objects can not be used as keys. Doing so will result in a warning: Illegal offset type.

You could give each instance a unique ID or override __toString() such that it returns something unique and do e.g.

$array[(string) $instance] = 42;
香橙ぽ 2024-10-18 01:10:30

您可以使用 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);

因此它可以与代码库的其余部分很好地配合。

You can use 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;
}

It's not a real array, but has a decent amount of array-like functionality and syntax. However, due to it being an object, it behaves like a misfit in php due to its odd foreach behavior, and its incompatibility with all the native php array functions. Sometimes you'll find it useful to convert it to a real array via

$arr = iterator_to_array($sales);

so it plays nice with the rest of your codebase.

心凉 2024-10-18 01:10:30

有一个 spl_object_hash 函数用于获取字符串形式的唯一对象 ID,该 ID 可以用作数组键。 http://php.net/manual/en/function.spl-object -hash.php

There is a spl_object_hash function for getting unique object id as string, which can be used as array key. http://php.net/manual/en/function.spl-object-hash.php

仅此而已 2024-10-18 01:10:30

仅允许整数和字符串作为数组键。如果您绝对需要该功能,您可以编写一个实现 ArrayAccess 的类。

Only integers and strings are allowed as array keys. You could write a class that implements ArrayAccess if you absolutely need that functionality.

烟火散人牵绊 2024-10-18 01:10:30

您终于可以在 PHP 8.0+ 中使用对象作为数组键。但这有点谎言。它不会是您使用的常规数组,而是新的 WeakMap 类< /a>.

声明一个 new WeakMap();,然后您可以将其填充为对象作为键。与任何基于 Spl 的技巧相比,使用此方法的优点是 WeakMap 能够更好地防止内存泄漏。 “弱”部分是指映射中对象的引用是“弱”的,并且一旦对象不再在范围内,就不会阻止对象被垃圾收集。 WeakMap 会自动从自身中删除该对象。

这是关于用例的一个很好的运行

PHP RFC 也是一本好书。

You finally can use objects as array keys in PHP 8.0+. But that's a bit of a lie. It won't be regular arrays you're using, but the new WeakMap class.

Declare a new WeakMap(); and then you can pack it full of objects as keys. The advantage of using this over any Spl-based trick, is that WeakMap is better on memory leaks. The "weak" part refers to the fact that the object's reference in the map is "weak" and will not prevent the object from getting garbage-collected once it's no longer in-scope. The WeakMap will automatically remove the object from itself.

Here's a good run-through on use cases.

The PHP RFC is a good read, too.

请帮我爱他 2024-10-18 01:10:30

我知道这个问题很老了,并且 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())"

I know this question is old, and that SplObjectStorage has some weird behaviour (e.g. when looping with foreach).

As of today, there is this library I wrote called linked-hash-map (https://github.com/tonix-tuft/linked-hash-map) which implements an associative array/hash map/hash table in PHP and allows you to use any PHP data type for the key:

<?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())"
野鹿林 2024-10-18 01:10:30

如果对象是使用 new stdClass() 创建的简单预定义类,则通过 json_encode 使用此类的 json 表示形式可能是有效的选择。

$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;
}

但请记住,两个对象的相等始终是一种业务模型选择,必须仔细设计。

If the object is a simple predefined classes made with new stdClass() it may be valid option to use the json representation of this class with 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;
}

But keep in mind that the equality of two objects is always a business model choice and must be carefully designed.

涙—继续流 2024-10-18 01:10:30

您可以有两个数组:

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];
    }
  }
}

我希望它有帮助

You could have two arrays:

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) |
+--------+-------------+     |  +--------+------------+

You search for the Object in array 1,
then you pick the index of that Object
use it as index for array 2 and
=> get the value

in php code

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

I hope it helps

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文