I started creating a Dictionary class that accepts objects as there keys:
class Dictionary
implements ArrayAccess
{
private $_keys = array();
private $_values = array();
public function offsetExists( $key )
{
return false !== array_search( $key, $this->_keys, true );
}
public function offsetGet( $key )
{
if( false === ( $index = array_search( $key, $this->_keys, true ) ) )
{
throw new OutOfBoundsException( 'Invalid dictionary key' );
}
if( !isset( $this->_values[ $index ] ) )
{
throw new LogicException( 'No matching value found for dictionary key' );
}
return $this->_values[ $index ];
}
public function offsetSet( $key, $value )
{
if( false !== ( $index = array_search( $key, $this->_keys, true ) ) )
{
$this->_values[ $index ] = $value;
}
else
{
$this->_keys[] = $key;
$this->_values[] = $value;
}
}
public function offsetUnset( $key )
{
if( false === ( $index = array_search( $key, $this->_keys, true ) ) )
{
throw new OutOfBoundsException( 'Invalid dictionary key' );
}
if( !isset( $this->_values[ $index ] ) )
{
throw new LogicException( 'No matching value found for dictionary key' );
}
array_splice( $this->_keys, $index, 1 );
array_splice( $this->_values, $index, 1 );
}
}
It works pretty well for the very elementary test cases I've done so far. However, I'm worried about three things:
Can you think of a situation where
$this->_keys
and$this->_values
will not be synchronized with each other anymore, thus leading to data corruption? I thought maybe there could occur a situation where something might happen between the twoarray_splice
s, for instance, in:public function offsetUnset( $key ) { ... array_splice( $this->_keys, $index, 1 ); array_splice( $this->_values, $index, 1 );
... leading to data corruption.
I feel
array_search()
might be inefficient, but I specifically don't want to resort to usingspl_object_hash()
as keys (and thereby circumventing the need for an internal keys and valuesarray
) as I belief this is not bulletproof, as it doesn't guarantee hash uniqueness for objects at all.I feel
array_splice()
might be inefficient, but I don't want to resort tounset()
as I feel this could lead to unwieldy internalarray
s keys eventually. I'd like to keep the internalarray
s keys as tightly packed as possible.
Looking forward to your feedback.