Skip to content

Commit 2cccd7f

Browse files
committed
added ArrayData that supports dot notation
1 parent a008a14 commit 2cccd7f

File tree

3 files changed

+401
-1
lines changed

3 files changed

+401
-1
lines changed

README.md

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ Simple PHP Data Storage.
55
## Usage
66

77
```php
8-
$storage = new frostealth\storage\Data(); // or $storage = new frostealth\storage\Data($array);
8+
$storage = new frostealth\storage\Data(); // or new frostealth\storage\Data($array);
99
$storage->set('login', 'example@example.com');
1010

1111
// ...
@@ -24,6 +24,19 @@ if ($storage->get('login', false)) {
2424

2525
$storage->clear();
2626

27+
28+
// working with arrays using "dot" notation
29+
$storage = new frostealth\storage\ArrayData();
30+
$storage->set('params', ['method' => 'post', 'url' => 'http://example.com/']);
31+
32+
$url = $storage->get('params.url'); // 'http://example.com/'
33+
$storage->set('params.method', 'get');
34+
$method = $storage->get('params.method'); // 'get'
35+
$params = $storage->get('params'); // ['method' => 'get', 'url' => 'http://example.com/']
36+
37+
$storage->set('options.my_option', 'value');
38+
$options = $storage->get('options'); // ['my_option' => 'value]
39+
2740
```
2841

2942
## Dependency Injection

src/storage/ArrayData.php

Lines changed: 235 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,235 @@
1+
<?php
2+
3+
namespace frostealth\storage;
4+
5+
/**
6+
* Class ArrayData
7+
*
8+
* @package frostealth\storage
9+
*/
10+
class ArrayData implements DataInterface, \ArrayAccess
11+
{
12+
/**
13+
* @var array
14+
*/
15+
protected $data;
16+
17+
/**
18+
* @param array $data
19+
*/
20+
public function __construct(array $data = [])
21+
{
22+
$this->fill($data);
23+
}
24+
25+
/**
26+
* Set an array item to a given value using "dot" notation
27+
* If no key is given to the method, the entire array will be replaced
28+
*
29+
* @param string $key
30+
* @param mixed $value
31+
*/
32+
public function set($key, $value)
33+
{
34+
$data = &$this->data;
35+
if ($this->isDotNotation($key)) {
36+
$keys = explode('.', $key);
37+
$key = array_pop($keys);
38+
39+
foreach ($keys as $segment) {
40+
if (!isset($data[$segment]) || !is_array($data[$segment])) {
41+
$data[$segment] = [];
42+
}
43+
44+
$data = &$data[$segment];
45+
}
46+
}
47+
48+
$data[$key] = $value;
49+
}
50+
51+
/**
52+
* Get an item from an array using "dot" notation
53+
*
54+
* @param string $key
55+
* @param mixed $default
56+
*
57+
* @return mixed
58+
*/
59+
public function get($key, $default = null)
60+
{
61+
if (array_key_exists($key, $this->data)) {
62+
return $this->data[$key];
63+
}
64+
65+
$value = $default;
66+
if ($this->isDotNotation($key)) {
67+
$keys = explode('.', $key);
68+
$value = $this->data;
69+
70+
foreach ($keys as $segment) {
71+
if (!is_array($value) || !array_key_exists($segment, $value)) {
72+
$value = $default;
73+
break;
74+
}
75+
76+
$value = $value[$segment];
77+
}
78+
}
79+
80+
return $value;
81+
}
82+
83+
/**
84+
* Check if an item exists in an array using "dot" notation
85+
*
86+
* @param string $key
87+
*
88+
* @return bool
89+
*/
90+
public function has($key)
91+
{
92+
$result = array_key_exists($key, $this->data);
93+
if (!$result && $this->isDotNotation($key)) {
94+
$result = true;
95+
$keys = explode('.', $key);
96+
$data = $this->data;
97+
98+
foreach ($keys as $key) {
99+
if (!is_array($data) || !array_key_exists($key, $data)) {
100+
$result = false;
101+
break;
102+
}
103+
104+
$data = $data[$key];
105+
}
106+
}
107+
108+
return $result;
109+
}
110+
111+
/**
112+
* @return array
113+
*/
114+
public function keys()
115+
{
116+
return array_keys($this->data);
117+
}
118+
119+
/**
120+
* @param string $key
121+
*/
122+
public function remove($key)
123+
{
124+
$data = &$this->data;
125+
if ($this->isDotNotation($key)) {
126+
$keys = explode('.', $key);
127+
$key = array_pop($keys);
128+
129+
foreach ($keys as $segment) {
130+
if (!is_array($data) || !array_key_exists($segment, $data)) {
131+
break;
132+
}
133+
134+
$data = &$data[$segment];
135+
}
136+
}
137+
138+
if (is_array($data)) {
139+
unset($data[$key]);
140+
}
141+
}
142+
143+
/**
144+
* @param array $data
145+
* @param bool $recursive
146+
*/
147+
public function replace(array $data, $recursive = false)
148+
{
149+
$function = $recursive ? 'array_replace_recursive' : 'array_replace';
150+
$result = call_user_func($function, $this->all(), $data);
151+
$this->fill($result);
152+
}
153+
154+
/**
155+
* @param array $data
156+
*/
157+
public function fill(array $data)
158+
{
159+
$this->data = $data;
160+
}
161+
162+
/**
163+
* @return array
164+
*/
165+
public function all()
166+
{
167+
return $this->data;
168+
}
169+
170+
/**
171+
* @inheritDoc
172+
*/
173+
public function count()
174+
{
175+
return count($this->data);
176+
}
177+
178+
/**
179+
* @inheritDoc
180+
*/
181+
public function getIterator()
182+
{
183+
return new \ArrayIterator($this->data);
184+
}
185+
186+
/**
187+
* Clear all values
188+
*/
189+
public function clear()
190+
{
191+
$this->fill([]);
192+
}
193+
194+
/**
195+
* @inheritDoc
196+
*/
197+
public function offsetExists($offset)
198+
{
199+
return $this->has($offset);
200+
}
201+
202+
/**
203+
* @inheritDoc
204+
*/
205+
public function offsetGet($offset)
206+
{
207+
return $this->get($offset);
208+
}
209+
210+
/**
211+
* @inheritDoc
212+
*/
213+
public function offsetSet($offset, $value)
214+
{
215+
$this->set($offset, $value);
216+
}
217+
218+
/**
219+
* @inheritDoc
220+
*/
221+
public function offsetUnset($offset)
222+
{
223+
$this->remove($offset);
224+
}
225+
226+
/**
227+
* @param string $key
228+
*
229+
* @return bool
230+
*/
231+
protected function isDotNotation($key)
232+
{
233+
return strpos($key, '.') !== false;
234+
}
235+
}

0 commit comments

Comments
 (0)