standardStore = []; $this->floatStore = []; $this->objectStore = new SplObjectStorage(); $this->arrayKeys = []; $this->arrayValues = []; $this->nullValueIsSet = false; $this->trueValueIsSet = false; $this->falseValueIsSet = false; } /** * Whether a offset exists * * @link http://php.net/manual/en/arrayaccess.offsetexists.php * * @param mixed $offset
* An offset to check for. *
* * @return bool true on success or false on failure. * ** The return value will be casted to boolean if non-boolean was returned. */ public function offsetExists($offset) { if ($offset === false) { return $this->falseValueIsSet; } if ($offset === true) { return $this->trueValueIsSet; } if (is_int($offset) || is_string($offset)) { return array_key_exists($offset, $this->standardStore); } if (is_float($offset)) { return array_key_exists((string) $offset, $this->floatStore); } if (is_object($offset)) { return $this->objectStore->offsetExists($offset); } if (is_array($offset)) { foreach ($this->arrayKeys as $index => $entry) { if ($entry === $offset) { $this->lastArrayKey = $offset; $this->lastArrayValue = $this->arrayValues[$index]; return true; } } } if ($offset === null) { return $this->nullValueIsSet; } return false; } /** * Offset to retrieve * * @link http://php.net/manual/en/arrayaccess.offsetget.php * * @param mixed $offset
* The offset to retrieve. *
* * @return mixed Can return all value types. */ public function offsetGet($offset) { if ($offset === true) { return $this->trueValue; } if ($offset === false) { return $this->falseValue; } if (is_int($offset) || is_string($offset)) { return $this->standardStore[$offset]; } if (is_float($offset)) { return $this->floatStore[(string) $offset]; } if (is_object($offset)) { return $this->objectStore->offsetGet($offset); } if (is_array($offset)) { // offsetGet is often called directly after offsetExists, so optimize to avoid second loop: if ($this->lastArrayKey === $offset) { return $this->lastArrayValue; } foreach ($this->arrayKeys as $index => $entry) { if ($entry === $offset) { return $this->arrayValues[$index]; } } } if ($offset === null) { return $this->nullValue; } return null; } /** * Offset to set * * @link http://php.net/manual/en/arrayaccess.offsetset.php * * @param mixed $offset* The offset to assign the value to. *
* @param mixed $value* The value to set. *
* * @return void */ public function offsetSet($offset, $value) { if ($offset === false) { $this->falseValue = $value; $this->falseValueIsSet = true; } elseif ($offset === true) { $this->trueValue = $value; $this->trueValueIsSet = true; } elseif (is_int($offset) || is_string($offset)) { $this->standardStore[$offset] = $value; } elseif (is_float($offset)) { $this->floatStore[(string) $offset] = $value; } elseif (is_object($offset)) { $this->objectStore[$offset] = $value; } elseif (is_array($offset)) { $this->arrayKeys[] = $offset; $this->arrayValues[] = $value; } elseif ($offset === null) { $this->nullValue = $value; $this->nullValueIsSet = true; } else { throw new InvalidArgumentException('Unexpected offset type: ' . Utils::printSafe($offset)); } } /** * Offset to unset * * @link http://php.net/manual/en/arrayaccess.offsetunset.php * * @param mixed $offset* The offset to unset. *
* * @return void */ public function offsetUnset($offset) { if ($offset === true) { $this->trueValue = null; $this->trueValueIsSet = false; } elseif ($offset === false) { $this->falseValue = null; $this->falseValueIsSet = false; } elseif (is_int($offset) || is_string($offset)) { unset($this->standardStore[$offset]); } elseif (is_float($offset)) { unset($this->floatStore[(string) $offset]); } elseif (is_object($offset)) { $this->objectStore->offsetUnset($offset); } elseif (is_array($offset)) { $index = array_search($offset, $this->arrayKeys, true); if ($index !== false) { array_splice($this->arrayKeys, $index, 1); array_splice($this->arrayValues, $index, 1); } } elseif ($offset === null) { $this->nullValue = null; $this->nullValueIsSet = false; } } }