- <?php
- /**
- * PHLY - PHp LibrarY
- *
- * PHLY is a library of PHP classes designed with the following intentions:
- * - Loosely coupled; dependencies should be few, and no base class should be
- * necessary.
- * - Extendible; all classes should be easily extendible. This may be via
- * observers, interfaces, adapters, etc.. The base class should solve 80% of
- * usage, and allow extensions to the class to fill in the remainder.
- * - Designed for PHP5 and up; all classes should make use of PHP5's features.
- * - Documented; all classes should minimally have excellent API-level
- * documentation, with use cases in the class docblock.
- * - Tested; all classes should have (passing) unit tests accompanying them.
- * - Open source and commercial friendly; all classes should use a
- * commercial-friendly open source license. The BSD license is one such
- * example.
- *
- * @license New BSD, http://www.opensource.org/licenses/bsd-license.php
- * @package Phly
- * @copyright 2006 - Present, Matthew Weier O'Phinney
- */
-
- /**
- * Exceptions
- */
- require_once 'Phly/Struct/Exception.php';
-
- /**
- * Phly_Hash: Access associative arrays as object properties
- *
- * Phly_Hash provides general purpose, recursive, object property storage.
- * Values may be accessed and set using normal object notation:
- *
- * <code>
- * $storage->db->host = 'phly.weierophinney.net';
- * $host = $storage->db->host;
- * </code>
- *
- * The only rule is that the only argument that may be passed to the constructor
- * is an associative array. After that, any property of the object may be set to
- * any type of value. Setting a property to an associative array builds trees of
- * Phly_Hash objects.
- *
- * Phly_Hash implements Iterator, which means that you may iterate over a
- * Phly_Hash or any subvalue using foreach() and the like. It also implements
- * Countable, allowing you to use count() to retrieve a count of properties.
- *
- * @category Phly
- * @subcategory Phly_Hash
- * @subpackage Phly_Hash
- * @copyright 2006 - Present, Matthew Weier O'Phinney
- * @author Matthew Weier O'Phinney <mweierophinney@gmail.com>
- * @version @release-version@
- */
- class Phly_Hash implements Iterator,Countable
- {
- /**
- * Original array passed to constructor
- * @var string
- * @access private
- */
- protected $_array;
-
- /**
- * Values as Phly_Hashes
- * @var array
- * @access protected
- */
- protected $_values;
-
- /**
- * Iterator: valid flag
- * @var boolean
- * @access private
- */
- private $_valid = false;
-
- /**
- * Constructor
- *
- * Load an (associative) array recursively into the object. Any
- * (associative) array values will be loaded into child objects.
- *
- * @access public
- * @param array $array
- * @return void
- * @throws Phly_Hash_Exception when non-associative array provided
- */
- public function __construct($array)
- {
- if (!is_array($array)
- || (array_keys($array) === range(0, count($array) - 1)))
- {
- throw new Phly_Hash_Exception('Non-associative array passed to Phly_Hash');
- }
-
- $this->_array = $array;
- $this->_values = array();
-
- foreach ($array as $key => $value) {
- if (is_array($value)
- && (array_keys($value) !== range(0, count($value) - 1)))
- {
- // Recursively load associative array into object
- $this->_values[$key] = new self($value);
- } else {
- // Scalar, indexed array, boolean, object, etc...
- $this->_values[$key] = $value;
- }
- }
- }
-
- /**
- * Overloading: retrieve properties
- *
- * @access public
- * @param string $key
- * @return mixed
- */
- public function __get($key)
- {
- $key = (string) $key;
- if (isset($this->_values[$key])) {
- return $this->_values[$key];
- }
-
- return null;
- }
-
- /**
- * Overloading: set properties
- *
- * If $value is an associative array, it is cast as a Phly_Hash prior to
- * setting the associated property.
- *
- * @access public
- * @param string $key
- * @param mixed $value
- * @return void
- */
- public function __set($key, $value)
- {
- $key = (string) $key;
-
- if (is_array($value)
- && (array_keys($value) !== range(0, count($value) - 1)))
- {
- // Associative array -- recast as Phly_Hash
- $value = new self($value);
- }
-
- $this->_values[$key] = $value;
- }
-
- /**
- * Return configuration subtree as array
- *
- * @access public
- * @return array
- */
- public function toArray()
- {
- return $this->_array;
- }
-
- /**
- * Iterator: return current value
- *
- * @access public
- * @return void
- */
- public function current()
- {
- return current($this->_values);
- }
-
- /**
- * Iterator: return current key
- *
- * @access public
- * @return string
- */
- public function key()
- {
- return key($this->_values);
- }
-
- /**
- * Iterator: return next array element
- *
- * @access public
- * @return void
- */
- public function next()
- {
- $this->_valid = (false !== next($this->_values));
- }
-
- /**
- * Iterator: return to first element of array
- *
- * @access public
- * @return void
- */
- public function rewind()
- {
- $this->_valid = (false !== reset($this->_values));
- }
-
- /**
- * Iterator: is this a valid key?
- *
- * @access public
- * @return boolean
- */
- public function valid()
- {
- return $this->_valid;
- }
-
- /**
- * Countable: return count of elements
- *
- * @access public
- * @return int
- */
- public function count()
- {
- return count($this->_values);
- }
- }