Re: Objects as array key names??

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Wed, Mar 19, 2008 at 10:37 AM, Jim Lucas <lists@xxxxxxxxx> 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

[Index of Archives]     [PHP Home]     [Apache Users]     [PHP on Windows]     [Kernel Newbies]     [PHP Install]     [PHP Classes]     [Pear]     [Postgresql]     [Postgresql PHP]     [PHP on Windows]     [PHP Database Programming]     [PHP SOAP]

  Powered by Linux