CaseInsensitiveArrayService.php 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234
  1. <?php
  2. namespace App\Services\Common;
  3. class CaseInsensitiveArrayService implements \ArrayAccess, \Countable, \Iterator
  4. {
  5. /**
  6. * @var mixed[] Data storage with lower-case keys
  7. * @see offsetSet()
  8. * @see offsetExists()
  9. * @see offsetUnset()
  10. * @see offsetGet()
  11. * @see count()
  12. * @see current()
  13. * @see next()
  14. * @see key()
  15. */
  16. private $data = array();
  17. /**
  18. * @var string[] Case-Sensitive keys.
  19. * @see offsetSet()
  20. * @see offsetUnset()
  21. * @see key()
  22. */
  23. private $keys = array();
  24. /**
  25. * Construct
  26. *
  27. * Allow creating either an empty Array, or convert an existing Array to a
  28. * Case-Insensitive Array. (Caution: Data may be lost when converting Case-
  29. * Sensitive Arrays to Case-Insensitive Arrays)
  30. *
  31. * @param mixed[] $initial (optional) Existing Array to convert.
  32. *
  33. * @return void
  34. *
  35. * @access public
  36. */
  37. public function __construct(Array $initial = null)
  38. {
  39. if ($initial !== null) {
  40. foreach ($initial as $key => $value) {
  41. $this->offsetSet($key, $value);
  42. }
  43. }
  44. }
  45. /**
  46. * Offset Set
  47. *
  48. * Set data at a specified Offset. Converts the offset to lower-case, and
  49. * stores the Case-Sensitive Offset and the Data at the lower-case indexes
  50. * in $this->keys and @this->data.
  51. *
  52. * @see https://secure.php.net/manual/en/arrayaccess.offseteset.php
  53. *
  54. * @param string $offset The offset to store the data at (case-insensitive).
  55. * @param mixed $value The data to store at the specified offset.
  56. *
  57. * @return void
  58. *
  59. * @access public
  60. */
  61. public function offsetSet($offset, $value)
  62. {
  63. if ($offset === null) {
  64. $this->data[] = $value;
  65. } else {
  66. $offsetlower = strtolower($offset);
  67. $this->data[$offsetlower] = $value;
  68. $this->keys[$offsetlower] = $offset;
  69. }
  70. }
  71. /**
  72. * Offset Exists
  73. *
  74. * Checks if the Offset exists in data storage. The index is looked up with
  75. * the lower-case version of the provided offset.
  76. *
  77. * @see https://secure.php.net/manual/en/arrayaccess.offsetexists.php
  78. *
  79. * @param string $offset Offset to check
  80. *
  81. * @return bool If the offset exists.
  82. *
  83. * @access public
  84. */
  85. public function offsetExists($offset)
  86. {
  87. return (bool) array_key_exists(strtolower($offset), $this->data);
  88. }
  89. /**
  90. * Offset Unset
  91. *
  92. * Unsets the specified offset. Converts the provided offset to lowercase,
  93. * and unsets the Case-Sensitive Key, as well as the stored data.
  94. *
  95. * @see https://secure.php.net/manual/en/arrayaccess.offsetunset.php
  96. *
  97. * @param string $offset The offset to unset.
  98. *
  99. * @return void
  100. *
  101. * @access public
  102. */
  103. public function offsetUnset($offset)
  104. {
  105. $offsetlower = strtolower($offset);
  106. unset($this->data[$offsetlower]);
  107. unset($this->keys[$offsetlower]);
  108. }
  109. /**
  110. * Offset Get
  111. *
  112. * Return the stored data at the provided offset. The offset is converted to
  113. * lowercase and the lookup is done on the Data store directly.
  114. *
  115. * @see https://secure.php.net/manual/en/arrayaccess.offsetget.php
  116. *
  117. * @param string $offset Offset to lookup.
  118. *
  119. * @return mixed The data stored at the offset.
  120. *
  121. * @access public
  122. */
  123. public function offsetGet($offset)
  124. {
  125. $offsetlower = strtolower($offset);
  126. return isset($this->data[$offsetlower]) ? $this->data[$offsetlower] : null;
  127. }
  128. /**
  129. * Count
  130. *
  131. * @see https://secure.php.net/manual/en/countable.count.php
  132. *
  133. * @param void
  134. *
  135. * @return int The number of elements stored in the Array.
  136. *
  137. * @access public
  138. */
  139. public function count()
  140. {
  141. return (int) count($this->data);
  142. }
  143. /**
  144. * Current
  145. *
  146. * @see https://secure.php.net/manual/en/iterator.current.php
  147. *
  148. * @param void
  149. *
  150. * @return mixed Data at the current position.
  151. *
  152. * @access public
  153. */
  154. public function current()
  155. {
  156. return current($this->data);
  157. }
  158. /**
  159. * Next
  160. *
  161. * @see https://secure.php.net/manual/en/iterator.next.php
  162. *
  163. * @param void
  164. *
  165. * @return void
  166. *
  167. * @access public
  168. */
  169. public function next()
  170. {
  171. next($this->data);
  172. }
  173. /**
  174. * Key
  175. *
  176. * @see https://secure.php.net/manual/en/iterator.key.php
  177. *
  178. * @param void
  179. *
  180. * @return mixed Case-Sensitive key at current position.
  181. *
  182. * @access public
  183. */
  184. public function key()
  185. {
  186. $key = key($this->data);
  187. return isset($this->keys[$key]) ? $this->keys[$key] : $key;
  188. }
  189. /**
  190. * Valid
  191. *
  192. * @see https://secure.php.net/manual/en/iterator.valid.php
  193. *
  194. * @param void
  195. *
  196. * @return bool If the current position is valid.
  197. *
  198. * @access public
  199. */
  200. public function valid()
  201. {
  202. return (bool) !(key($this->data) === null);
  203. }
  204. /**
  205. * Rewind
  206. *
  207. * @see https://secure.php.net/manual/en/iterator.rewind.php
  208. *
  209. * @param void
  210. *
  211. * @return void
  212. *
  213. * @access public
  214. */
  215. public function rewind()
  216. {
  217. reset($this->data);
  218. }
  219. }