1: <?php
2:
3: 4: 5: 6: 7: 8: 9: 10: 11:
12:
13:
14:
15: 16: 17: 18: 19:
20: class NKeyNotFoundException extends RuntimeException
21: {
22: }
23:
24:
25:
26: 27: 28: 29: 30: 31:
32: class NHashtable extends NCollection implements IMap
33: {
34:
35: private $throwKeyNotFound = FALSE;
36:
37:
38:
39: 40: 41: 42: 43: 44: 45:
46: public function add($key, $item)
47: {
48:
49: if (!is_scalar($key)) {
50: throw new InvalidArgumentException("Key must be either a string or an integer, " . gettype($key) ." given.");
51: }
52:
53: if (parent::offsetExists($key)) {
54: throw new InvalidStateException('An element with the same key already exists.');
55: }
56:
57: $this->beforeAdd($item);
58: parent::offsetSet($key, $item);
59: return TRUE;
60: }
61:
62:
63:
64: 65: 66:
67: public function append($item)
68: {
69: throw new NotSupportedException;
70: }
71:
72:
73:
74: 75: 76: 77:
78: public function getKeys()
79: {
80: return array_keys($this->getArrayCopy());
81: }
82:
83:
84:
85: 86: 87: 88: 89: 90:
91: public function search($item)
92: {
93: return array_search($item, $this->getArrayCopy(), TRUE);
94: }
95:
96:
97:
98: 99: 100: 101: 102: 103:
104: public function import($arr)
105: {
106: $this->updating();
107:
108: if (!(is_array($arr) || $arr instanceof Traversable)) {
109: throw new InvalidArgumentException("Argument must be traversable.");
110: }
111:
112: if ($this->getItemType() === NULL) {
113: $this->setArray((array) $arr);
114:
115: } else {
116: $this->clear();
117: foreach ($arr as $key => $item) {
118: $this->offsetSet($key, $item);
119: }
120: }
121: }
122:
123:
124:
125: 126: 127: 128: 129: 130: 131:
132: public function get($key, $default = NULL)
133: {
134: if (!is_scalar($key)) {
135: throw new InvalidArgumentException("Key must be either a string or an integer, " . gettype($key) ." given.");
136: }
137:
138: if (parent::offsetExists($key)) {
139: return parent::offsetGet($key);
140:
141: } else {
142: return $default;
143: }
144: }
145:
146:
147:
148: 149: 150: 151:
152: public function throwKeyNotFound($val = TRUE)
153: {
154: $this->throwKeyNotFound = (bool) $val;
155: }
156:
157:
158:
159:
160:
161:
162:
163: 164: 165: 166: 167: 168: 169:
170: public function offsetSet($key, $item)
171: {
172: if (!is_scalar($key)) {
173: throw new InvalidArgumentException("Key must be either a string or an integer, " . gettype($key) ." given.");
174: }
175:
176: $this->beforeAdd($item);
177: parent::offsetSet($key, $item);
178: }
179:
180:
181:
182: 183: 184: 185: 186: 187:
188: public function offsetGet($key)
189: {
190: if (!is_scalar($key)) {
191: throw new InvalidArgumentException("Key must be either a string or an integer, " . gettype($key) ." given.");
192: }
193:
194: if (parent::offsetExists($key)) {
195: return parent::offsetGet($key);
196:
197: } elseif ($this->throwKeyNotFound) {
198: throw new NKeyNotFoundException;
199:
200: } else {
201: return NULL;
202: }
203: }
204:
205:
206:
207: 208: 209: 210: 211: 212:
213: public function offsetExists($key)
214: {
215: if (!is_scalar($key)) {
216: throw new InvalidArgumentException("Key must be either a string or an integer, " . gettype($key) ." given.");
217: }
218:
219: return parent::offsetExists($key);
220: }
221:
222:
223:
224: 225: 226: 227: 228: 229:
230: public function offsetUnset($key)
231: {
232: $this->updating();
233:
234: if (!is_scalar($key)) {
235: throw new InvalidArgumentException("Key must be either a string or an integer, " . gettype($key) ." given.");
236: }
237:
238: if (parent::offsetExists($key)) {
239: parent::offsetUnset($key);
240: }
241: }
242:
243: }
244: