Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 1282c40

Browse files
authoredApr 19, 2019
Merge pull request #20 from swaggest/class-pointer
Add support for PHP classes in JsonPointer
2 parents dadb65f + 114edf2 commit 1282c40

File tree

5 files changed

+139
-65
lines changed

5 files changed

+139
-65
lines changed
 

‎Makefile

+2-2
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ phar:
33

44
docker56-composer-update:
55
test -f ./composer.phar || wget https://getcomposer.org/composer.phar
6-
docker run -v $$(pwd):/code php:5.6-cli bash -c "apt-get update;apt-get install -y unzip;cd /code;php composer.phar update --prefer-source"
6+
docker run --rm -v $$(pwd):/code php:5.6-cli bash -c "apt-get update;apt-get install -y unzip;cd /code;php composer.phar update --prefer-source"
77

88
docker56-test:
9-
docker run -v $$(pwd):/code php:5.6-cli bash -c "cd /code;php vendor/bin/phpunit"
9+
docker run --rm -v $$(pwd):/code -w /code php:5.6-cli php vendor/bin/phpunit

‎README.md

+6
Original file line numberDiff line numberDiff line change
@@ -231,6 +231,12 @@ $patch->apply($original);
231231
$this->assertEquals($diff->getRearranged(), $original);
232232
```
233233

234+
## PHP Classes as JSON objects
235+
236+
Due to magical methods and other restrictions PHP classes can not be reliably mapped to/from JSON objects.
237+
There is support for objects of PHP classes in `JsonPointer` with limitations:
238+
* `null` is equal to non-existent
239+
234240
## CLI tool
235241

236242
Moved to [`swaggest/json-cli`](https://github.com/swaggest/json-cli)

‎composer.lock

+58-59
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

‎src/JsonPointer.php

+14-2
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ public static function add(&$holder, $pathItems, $value, $flags = self::RECURSIV
9898
{
9999
$ref = &$holder;
100100
while (null !== $key = array_shift($pathItems)) {
101-
if ($ref instanceof \stdClass) {
101+
if ($ref instanceof \stdClass || is_object($ref)) {
102102
if (PHP_VERSION_ID < 71000 && '' === $key) {
103103
throw new Exception('Empty property name is not supported by PHP <7.1',
104104
Exception::EMPTY_PROPERTY_NAME_UNSUPPORTED);
@@ -208,6 +208,12 @@ public static function get($holder, $pathItems)
208208
} else {
209209
throw new Exception('Key not found: ' . $key);
210210
}
211+
} elseif (is_object($ref)) {
212+
if (isset($ref->$key)) {
213+
$ref = $ref->$key;
214+
} else {
215+
throw new Exception('Key not found: ' . $key);
216+
}
211217
} else {
212218
throw new Exception('Key not found: ' . $key);
213219
}
@@ -244,6 +250,12 @@ public static function remove(&$holder, $pathItems)
244250
} else {
245251
throw new Exception('Key not found: ' . $key);
246252
}
253+
} elseif (is_object($ref)) {
254+
if (isset($ref->$key)) {
255+
$ref = &$ref->$key;
256+
} else {
257+
throw new Exception('Key not found: ' . $key);
258+
}
247259
} else {
248260
if (array_key_exists($key, $ref)) {
249261
$ref = &$ref[$key];
@@ -254,7 +266,7 @@ public static function remove(&$holder, $pathItems)
254266
}
255267

256268
if (isset($parent) && isset($refKey)) {
257-
if ($parent instanceof \stdClass) {
269+
if ($parent instanceof \stdClass || is_object($parent)) {
258270
unset($parent->$refKey);
259271
} else {
260272
unset($parent[$refKey]);

‎tests/src/JsonPointerTest.php

+59-2
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ class JsonPointerTest extends \PHPUnit_Framework_TestCase
1414
public function testProcess()
1515
{
1616
$json = new \stdClass();
17-
JsonPointer::add($json, ['l1','l2','l3'], 'hello!');
17+
JsonPointer::add($json, ['l1', 'l2', 'l3'], 'hello!');
1818
$this->assertSame('{"l1":{"l2":{"l3":"hello!"}}}', json_encode($json));
1919

2020
JsonPointer::add($json, ['l1', 'l2', 'l3'], 'hello again!', JsonPointer::SKIP_IF_ISSET);
@@ -34,7 +34,7 @@ public function testProcess()
3434
$this->assertSame('Key not found: non-existent', $exception->getMessage());
3535
}
3636

37-
JsonPointer::remove($json, ['l1','l2']);
37+
JsonPointer::remove($json, ['l1', 'l2']);
3838
$this->assertSame('{"l1":{}}', json_encode($json));
3939

4040
JsonPointer::add($json, JsonPointer::splitPath('/l1/l2/0/0'), 0);
@@ -71,4 +71,61 @@ public function testBuildPath()
7171
$this->assertSame('#/key1/~1project~1%7Busername%7D~1%7Bproject%7D/key2',
7272
JsonPointer::buildPath($pathItems, true));
7373
}
74+
75+
public function testGetSetDeleteObject()
76+
{
77+
$s = new Sample();
78+
$s->one = new Sample();
79+
$s->one->two = 2;
80+
81+
$this->assertEquals(2, JsonPointer::get($s, ['one', 'two']));
82+
83+
84+
JsonPointer::add($s, ['one', 'two'], 22);
85+
$this->assertEquals(22, JsonPointer::get($s, ['one', 'two']));
86+
$this->assertEquals(22, $s->one->two);
87+
88+
JsonPointer::remove($s, ['one', 'two']);
89+
try {
90+
JsonPointer::get($s, ['one', 'two']);
91+
$this->fail('Exception expected');
92+
} catch (Exception $e) {
93+
$this->assertEquals('Key not found: two', $e->getMessage());
94+
}
95+
$this->assertEquals(null, $s->one->two);
96+
}
97+
98+
}
99+
100+
class Sample
101+
{
102+
public $declared;
103+
104+
private $_data = [];
105+
106+
public function __isset($name)
107+
{
108+
return isset($this->_data[$name]);
109+
}
110+
111+
public function &__get($name)
112+
{
113+
if (array_key_exists($name, $this->_data)) {
114+
return $this->_data[$name];
115+
} else {
116+
$tmp = null;
117+
return $tmp;;
118+
}
119+
}
120+
121+
public function __set($name, $value)
122+
{
123+
$this->_data[$name] = $value;
124+
}
125+
126+
public function __unset($name)
127+
{
128+
unset($this->_data[$name]);
129+
}
130+
74131
}

0 commit comments

Comments
 (0)
Please sign in to comment.