# Indexing an array

- Thread: https://externals.io/message/49213
- Original archive: https://news-web.php.net/php.internals/49213
- Started by mathieu.suen on 2010-08-06T14:33:18+00:00
- Messages: 11
- Reply by email to internals@lists.php.net
- More for agents: search with https://externals.io/search.md?q={query} · JSON API at https://externals.io/api · documentation at https://externals.io/llms.txt

---

## #49213 — mathieu.suen — 2010-08-06T14:33:18+00:00

URL: https://externals.io/message/49213#49213

Hi,

For now you can only index an array using a scalar type or a string.
Is there some rfc or work going on to enlarge the possibility so that it 
is possible to have some other object like:

- closure
- object
- etc.

Thanks

-- Mathieu Suen

---

## #49214 — Gustavo Lopes — 2010-08-06T14:42:01+00:00

URL: https://externals.io/message/49213#49214 · In reply to: #49213

On Fri, 06 Aug 2010 15:33:18 +0100, mathieu.suen  
<mathieu.suen@easyflirt.com> wrote:

> Hi,
>
> For now you can only index an array using a scalar type or a string.
> Is there some rfc or work going on to enlarge the possibility so that it
> is possible to have some other object like:
>
> - closure
> - object
> - etc.

I think the problem with that is how you are going to generate the hash of  
arbitrary objects in order to store them in the hash table. It's not like  
all PHP objects have a hashCode() method.

So the only plausible option would be to attribute the same hash to all  
and the test all for equality on an insertion with a new key or in the  
worst case scenario for updates and reads.

-- 
Gustavo Lopes

---

## #49215 — Richard Quadling — 2010-08-06T14:44:23+00:00

URL: https://externals.io/message/49213#49215 · In reply to: #49213

> Hi,
>
> For now you can only index an array using a scalar type or a string.
> Is there some rfc or work going on to enlarge the possibility so that it is
> possible to have some other object like:
>
> - closure
> - object
> - etc.
>
> Thanks
>
> -- Mathieu Suen
>
>
>
>

If an object implements a __toString() magic method, then it can work ...


<?php
class randomizer {
	public function __toString() {
		return (string)mt_rand();
	}
}

$randomizer = new randomizer;
$array = array (
	"$randomizer" => 'First',
	"$randomizer" => 'Second',
	"$randomizer" => 'Third',
	"$randomizer" => 'Fourth',
);

print_r($array);
?>

outputs ...

Array
(
    [1365443950] => First
    [1235256771] => Second
    [520059180] => Third
    [486985268] => Fourth
)

---

## #49217 — Hannes Magnusson — 2010-08-06T15:20:47+00:00

URL: https://externals.io/message/49213#49217 · In reply to: #49213

> Hi,
>
> For now you can only index an array using a scalar type or a string.
> Is there some rfc or work going on to enlarge the possibility so that it is
> possible to have some other object like:
>

I don't think it makes sense.

You can however kindof fake it:


$ php -r '$objs = new SplObjectStorage; $std = new stdclass; $std->foo
= 1; $objs->attach($std, array(1,2,3,4)); var_dump($objs[$std]);'
array(4) {
  [0]=>
  int(1)
  [1]=>
  int(2)
  [2]=>
  int(3)
  [3]=>
  int(4)
}


-Hannes

---

## #49220 — Stas Malyshev — 2010-08-06T17:46:55+00:00

URL: https://externals.io/message/49213#49220 · In reply to: #49213

Hi!

> For now you can only index an array using a scalar type or a string.
> Is there some rfc or work going on to enlarge the possibility so that it
> is possible to have some other object like:

I think SplObjectStorage implements most common use-case for such 
behavior, do you have any other one that is not covered there and can't 
be done by __toString()?
-- 
Stanislav Malyshev, Software Architect
SugarCRM: http://www.sugarcrm.com/
(408)454-6900 ext. 227

---

## #49222 — Ionut G. Stan — 2010-08-07T13:50:46+00:00

URL: https://externals.io/message/49213#49222 · In reply to: #49217

> 
> > […]
>
> I don't think it makes sense.

It makes. That's why SplObjectStorage implements ArrayAccess.

-- 
Ionuț G. Stan  |  http://igstan.ro

---

## #49224 — mathieu.suen — 2010-08-09T11:44:03+00:00

URL: https://externals.io/message/49213#49224 · In reply to: #49214

> On Fri, 06 Aug 2010 15:33:18 +0100, mathieu.suen 
> <mathieu.suen@easyflirt.com> wrote:
>
> > […]
>
> I think the problem with that is how you are going to generate the 
> hash of arbitrary objects in order to store them in the hash table. 
> It's not like all PHP objects have a hashCode() method.

IMHO It should.

>
> So the only plausible option would be to attribute the same hash to 
> all and the test all for equality on an insertion with a new key or in 
> the worst case scenario for updates and reads.
>

Since php is not referentially transparent I would rather use identity 
unless object can redefine equality.

-- Mathieu Suen

---

## #49225 — mathieu.suen — 2010-08-09T11:47:03+00:00

URL: https://externals.io/message/49213#49225 · In reply to: #49215

> 
>    
> > […]
> If an object implements a __toString() magic method, then it can work ...
>
>
> <?php
> class randomizer {
> 	public function __toString() {
> 		return (string)mt_rand();
> 	}
> }
>
> $randomizer = new randomizer;
> $array = array (
> 	"$randomizer" =>  'First',
> 	"$randomizer" =>  'Second',
> 	"$randomizer" =>  'Third',
> 	"$randomizer" =>  'Fourth',
> );
>
> print_r($array);
> ?>
>
> outputs ...
>
> Array
> (
>      [1365443950] =>  First
>      [1235256771] =>  Second
>      [520059180] =>  Third
>      [486985268] =>  Fourth
> )

Well that is not the expected behavior since if you call array_keys you 
won't get the object.

--Mathieu Suen

---

## #49226 — mathieu.suen — 2010-08-09T11:50:34+00:00

URL: https://externals.io/message/49213#49226 · In reply to: #49220

> Hi!
>
> > […]
>
> I think SplObjectStorage implements most common use-case for such 
> behavior, do you have any other one that is not covered there and 
> can't be done by __toString()?

Yes but what I don't like with the Spl is that it does not work with the 
array_* function and the sort function.

-- Mathieu Suen

---

## #49227 — johannes@php.net — 2010-08-09T12:36:50+00:00

URL: https://externals.io/message/49213#49227 · In reply to: #49225

> > […]
> 
> Well that is not the expected behavior since if you call array_keys you 
> won't get the object.

Well, "arrays" are implemented as hash tables, hash tables work by
generating a hash to identify a value. Changing this is a big change
(rewrite everything accessing array keys) and you can always do
something like

$array = array(
  spl_object_hash($object1) => array('object' => $object1, 'data' => /* ...*/),
  spl_object_hash($object2) => array('object' => $object2, 'data' => /* ...*/),
 /*...*/
);

The only thing I can imagine is that we add support for objects
implementing ArrayAccess and Traversable (Iterator) on more places.

johannes

---

## #49230 — Gustavo Lopes — 2010-08-09T14:24:52+00:00

URL: https://externals.io/message/49213#49230 · In reply to: #49224

On Mon, 09 Aug 2010 12:44:03 +0100, mathieu.suen  
<mathieu.suen@easyflirt.com> wrote:

> 
> > […]
>
> IMHO It should.
>
> > […]
>
> Since php is not referentially transparent I would rather use identity
> unless object can redefine equality.
>

Well, even if one could overcome the hash problem by using suboptimal  
methods like calling __toString (or even use `spl_object_hash()`, though  
we'd be limited to identity) as if  they were hashCode() methods, one big  
problem remains: the hash tables only store a simple integer (for  
numerical indexing) or a char * string (for string indexing) to identify  
the key. It would have to be changed to be able to store an object, and  
now we'd break a lot of code that expects keys to be either strings or  
integers, not to mention the arrays API would be more complicated that it  
already is.

SplObjectStorage is a so-so alternative because it only allows identity in  
indexing, but you seem to be OK with that.

As to it not working with array functions, you're right, it sucks. In  
fact, only array_key_exists and array_walk(_recursive) work with object  
(if you can call it "work").

Perhaps one path here is to change the array functions so that if they  
receive an object they try to cast it into an array with the cast_object  
handler/convert_object_to_type and change the current default  
implementation for standard objects, which only handles conversions to  
string, to also handle conversions to arrays by traversing the object, if  
possible. Not the most efficient thing to do, since it requires copying  
everything, but it would be easier than changing the array functions in a  
more profound fashion. The "H" parse argument is useless because it tries  
to call get_properties (by the way, I don't understand why  
convert_to_array(_ex) and convert_to_explicit_type prefer get_properties  
to cast_object).

-- 
Gustavo Lopes
