Phly Documentation Phly
[ return to channel ] [ class tree: Phly ] [ index: Phly ] [ all elements ]

Source for file Hash.php

Documentation is available at Hash.php

  1. <?php
  2. /**
  3. * PHLY - PHp LibrarY
  4. *
  5. * PHLY is a library of PHP classes designed with the following intentions:
  6. * - Loosely coupled; dependencies should be few, and no base class should be
  7. * necessary.
  8. * - Extendible; all classes should be easily extendible. This may be via
  9. * observers, interfaces, adapters, etc.. The base class should solve 80% of
  10. * usage, and allow extensions to the class to fill in the remainder.
  11. * - Designed for PHP5 and up; all classes should make use of PHP5's features.
  12. * - Documented; all classes should minimally have excellent API-level
  13. * documentation, with use cases in the class docblock.
  14. * - Tested; all classes should have (passing) unit tests accompanying them.
  15. * - Open source and commercial friendly; all classes should use a
  16. * commercial-friendly open source license. The BSD license is one such
  17. * example.
  18. *
  19. * @license New BSD, http://www.opensource.org/licenses/bsd-license.php
  20. * @package Phly
  21. * @copyright 2006 - Present, Matthew Weier O'Phinney
  22. */
  23.  
  24. /**
  25. * Exceptions
  26. */
  27. require_once 'Phly/Struct/Exception.php';
  28.  
  29. /**
  30. * Phly_Hash: Access associative arrays as object properties
  31. *
  32. * Phly_Hash provides general purpose, recursive, object property storage.
  33. * Values may be accessed and set using normal object notation:
  34. *
  35. * <code>
  36. * $storage->db->host = 'phly.weierophinney.net';
  37. * $host = $storage->db->host;
  38. * </code>
  39. *
  40. * The only rule is that the only argument that may be passed to the constructor
  41. * is an associative array. After that, any property of the object may be set to
  42. * any type of value. Setting a property to an associative array builds trees of
  43. * Phly_Hash objects.
  44. *
  45. * Phly_Hash implements Iterator, which means that you may iterate over a
  46. * Phly_Hash or any subvalue using foreach() and the like. It also implements
  47. * Countable, allowing you to use count() to retrieve a count of properties.
  48. *
  49. * @category Phly
  50. * @subcategory Phly_Hash
  51. * @subpackage Phly_Hash
  52. * @copyright 2006 - Present, Matthew Weier O'Phinney
  53. * @author Matthew Weier O'Phinney <mweierophinney@gmail.com>
  54. * @version @release-version@
  55. */
  56. class Phly_Hash implements Iterator,Countable
  57. {
  58. /**
  59. * Original array passed to constructor
  60. * @var string
  61. * @access private
  62. */
  63. protected $_array;
  64.  
  65. /**
  66. * Values as Phly_Hashes
  67. * @var array
  68. * @access protected
  69. */
  70. protected $_values;
  71.  
  72. /**
  73. * Iterator: valid flag
  74. * @var boolean
  75. * @access private
  76. */
  77. private $_valid = false;
  78.  
  79. /**
  80. * Constructor
  81. *
  82. * Load an (associative) array recursively into the object. Any
  83. * (associative) array values will be loaded into child objects.
  84. *
  85. * @access public
  86. * @param array $array
  87. * @return void
  88. * @throws Phly_Hash_Exception when non-associative array provided
  89. */
  90. public function __construct($array)
  91. {
  92. if (!is_array($array)
  93. || (array_keys($array) === range(0, count($array) - 1)))
  94. {
  95. throw new Phly_Hash_Exception('Non-associative array passed to Phly_Hash');
  96. }
  97.  
  98. $this->_array = $array;
  99. $this->_values = array();
  100.  
  101. foreach ($array as $key => $value) {
  102. if (is_array($value)
  103. && (array_keys($value) !== range(0, count($value) - 1)))
  104. {
  105. // Recursively load associative array into object
  106. $this->_values[$key] = new self($value);
  107. } else {
  108. // Scalar, indexed array, boolean, object, etc...
  109. $this->_values[$key] = $value;
  110. }
  111. }
  112. }
  113.  
  114. /**
  115. * Overloading: retrieve properties
  116. *
  117. * @access public
  118. * @param string $key
  119. * @return mixed
  120. */
  121. public function __get($key)
  122. {
  123. $key = (string) $key;
  124. if (isset($this->_values[$key])) {
  125. return $this->_values[$key];
  126. }
  127.  
  128. return null;
  129. }
  130.  
  131. /**
  132. * Overloading: set properties
  133. *
  134. * If $value is an associative array, it is cast as a Phly_Hash prior to
  135. * setting the associated property.
  136. *
  137. * @access public
  138. * @param string $key
  139. * @param mixed $value
  140. * @return void
  141. */
  142. public function __set($key, $value)
  143. {
  144. $key = (string) $key;
  145.  
  146. if (is_array($value)
  147. && (array_keys($value) !== range(0, count($value) - 1)))
  148. {
  149. // Associative array -- recast as Phly_Hash
  150. $value = new self($value);
  151. }
  152.  
  153. $this->_values[$key] = $value;
  154. }
  155.  
  156. /**
  157. * Return configuration subtree as array
  158. *
  159. * @access public
  160. * @return array
  161. */
  162. public function toArray()
  163. {
  164. return $this->_array;
  165. }
  166.  
  167. /**
  168. * Iterator: return current value
  169. *
  170. * @access public
  171. * @return void
  172. */
  173. public function current()
  174. {
  175. return current($this->_values);
  176. }
  177.  
  178. /**
  179. * Iterator: return current key
  180. *
  181. * @access public
  182. * @return string
  183. */
  184. public function key()
  185. {
  186. return key($this->_values);
  187. }
  188.  
  189. /**
  190. * Iterator: return next array element
  191. *
  192. * @access public
  193. * @return void
  194. */
  195. public function next()
  196. {
  197. $this->_valid = (false !== next($this->_values));
  198. }
  199.  
  200. /**
  201. * Iterator: return to first element of array
  202. *
  203. * @access public
  204. * @return void
  205. */
  206. public function rewind()
  207. {
  208. $this->_valid = (false !== reset($this->_values));
  209. }
  210.  
  211. /**
  212. * Iterator: is this a valid key?
  213. *
  214. * @access public
  215. * @return boolean
  216. */
  217. public function valid()
  218. {
  219. return $this->_valid;
  220. }
  221.  
  222. /**
  223. * Countable: return count of elements
  224. *
  225. * @access public
  226. * @return int
  227. */
  228. public function count()
  229. {
  230. return count($this->_values);
  231. }
  232. }