On Sat, Mar 15, 2008 at 6:02 PM, Jim Lucas <lists@xxxxxxxxx> wrote: > It has been brought to my attention that with Perl and Ruby, you can use > Objects as the value of the key within an array. The examples that were > shown to me make me think that this would be an awesome ability to have > within PHP. this is essentially already possible, w/ some limitations due to type checking w/in php. remember that spl thing that everyone loves to bash? well thats what makes this remotely possible. you can put elements in using array notation and objects as keys, but thats about as far as it goes. some of the global functions like array_key_exists() dont work because they check the type of the $needle argument internally. also, iteration via foreach does not work correctly. implementing the Iterator interface to tell php how to iterate over the structure works as expected however a strange error is raised when trying to retrieve the current key: PHP Warning: Illegal type returned from ObjectArray::key(). LAME, *sigh*. anyway, its still pretty cool, and part of what youre looking for. i might see if marcus could tell me something about a condition w/in the code for key() inside of php that would allow this to actually work, because imho, if its overridden the internal check thats currently in place should be bypassed. also forgive the long post (theres code to follow ;)) <?php class ObjectArray implements ArrayAccess, Countable, Iterator{ private $indexes = array(); private $values = array(); private $curOffset = -1; private $totalElements = 0; /// Countable interface public function count() { return $this->totalElements; } /// ArrayAccess interface public function offsetExists($offset) { $offsetExists = false; foreach($this->indexes as $curIndex => $curObj) { if($curObj === $offset) { $offsetExists = true; $this->curOffset = $curIndex; break; } } return $offsetExists; } public function offsetGet($offset) { if($this->offsetExists($offset)) { return $this->values[$this->curOffset]; } } public function offsetSet($offset, $value) { if(!$this->offsetExists($offset)) { // grab index of offset /// set value of offset for first time $this->indexes[] = $offset; $this->values[] = $value; $this->totalElements++; } else { /// update value of offset $this->values[$this->curOffset] = $value; } } public function offsetUnset($offset) { if($this->offsetExists($offset)) { unset($this->indexes[$this->curOffset]); unset($this->values[$this->curOffset]); $this->totalElements--; } } /// Iterator interface public function current() { return $this->values[$this->curOffset]; } public function key() { return $this->indexes[$this->curOffset]; } public function next() { $this->curOffset++; } public function rewind() { $this->curOffset = 0; } public function valid() { $isValid = false; if(isset($this->indexes[$this->curOffset]) && isset($this->values[$this->curOffset])) { $isValid = true; } return $isValid; } } $objArr = new ObjectArray(); /// make $a & $c the same so == comparison should succeed $a = new StdClass(); $b = new StdClass(); $b->a = 'spl is the shit ;)'; $c = new stdClass(); // test putting a value in w/ object as index $objArr[$a] = 5; echo $objArr[$a] . PHP_EOL; // test changing the value $objArr[$a] = 6; echo $objArr[$a] . PHP_EOL; // note we can put in objs that pass == test, because internally // we use === $objArr[$c] = 7; echo 'count: ' . count($objArr) . PHP_EOL; $objArr[$b] = 8; echo 'count: ' . count($objArr) . PHP_EOL; var_dump($objArr[$a] == $objArr[$b]); // false var_dump($objArr[$a] == $objArr[$c]); // false /// broken even w/ Iterator implemented :( foreach($objArr as $key => $val) { if($a === $key) { echo "keyFound: {$objArr[$a]}" . PHP_EOL; break; } } -nathan