On Wed, Mar 19, 2008 at 10:37 AM, Jim Lucas <[EMAIL PROTECTED]> wrote:
> I would be interested in your examples. From what you described, I can't
> see in
> my head how it all goes together.
>
there was one caveat; i had to introduce a keyVal() instance method so
client code can get the object that is the current array 'key' because
internally it is the hash from spl_object_hash(), which is a string. using
this hash cut down on a number of loops that were in the old implementation
so i suspect this one is a little faster to boot.
<?php
class ObjectArray implements ArrayAccess, Countable, Iterator{
private $offsets = array(); // for optimizing iterator
implementation
private $indexes = array(); // array of object hashes
private $values = array(); // array of mixed values
private $curOffset = '';
private $curOffsetNum = -1;
private $totalElements = 0;
/// Countable interface
public function count() {
return $this->totalElements;
}
/**
* a function to grab the actual value of the key,
* if needed
*/
public function keyVal($key=null) {
if(!is_null($key)) {
return $this->indexes[$key];
} else {
return $this->indexes[$this->key()];
}
}
/// ArrayAccess interface
public function offsetExists($offset) {
$offsetExists = false;
$hash = spl_object_hash($offset);
if(isset($this->indexes[$hash]) &&
isset($this->values[$hash])) {
$offsetExists = true;
$this->curOffset = $hash;
}
return $offsetExists;
}
public function offsetGet($offset) {
if($this->offsetExists($offset)) {
return $this->values[$this->curOffset];
}
}
/**
* @note at this point it is assumed that $offset is an object
*/
public function offsetSet($offset, $value) {
if(!$this->offsetExists($offset)) { // grab index of offset
/// set value of offset for first time
$hash = spl_object_hash($offset);
$this->indexes[$hash] = $offset;
$this->values[$hash] = $value;
$this->offsets[] = $hash;
$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->key()];
}
public function key() {
return $this->offsets[$this->curOffsetNum];
}
public function next() {
$this->curOffsetNum++;
}
public function rewind() {
if($this->totalElements > 0) {
$this->curOffsetNum = 0;
} else {
$this->curOffsetNum = -1;
}
}
public function valid() {
$isValid = false;
if(isset($this->indexes[$this->offsets[$this->curOffsetNum]]) &&
isset($this->values[$this->key()])) {
$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
/// now working thanks to spl_object_hash()
foreach($objArr as $key => $val) {
if($a === $objArr->keyVal()) {
echo "keyFound: {$objArr[$a]}" . PHP_EOL;
break;
}
}
?>
-nathan