Skip to content
This repository was archived by the owner on Jan 29, 2020. It is now read-only.

Commit 275f7a2

Browse files
committed
Merge branch 'features/json-optional' into develop
Close #113
2 parents 5f2f4cc + ed718ec commit 275f7a2

File tree

4 files changed

+62
-12
lines changed

4 files changed

+62
-12
lines changed

CHANGELOG.md

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,11 @@ for full details on how to migrate your v2 application.
5151

5252
### Fixed
5353

54-
- Nothing.
54+
- [#113](https://github.com/zendframework/zend-mvc/pull/113) updates
55+
`AbstractRestfulController` to make usage of zend-json for deserializing JSON
56+
requests optional. `json_decode()` is now used by default, falling back to
57+
`Zend\Json\Json::decode()` if it is available. If neither are available, an
58+
exception is now thrown.
5559

5660
## 2.7.4 - TBD
5761

composer.json

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,6 @@
2828
"zendframework/zend-di": "^2.6",
2929
"zendframework/zend-filter": "^2.6.1",
3030
"zendframework/zend-inputfilter": "^2.6",
31-
"zendframework/zend-json": "^2.6.1",
3231
"zendframework/zend-log": "^2.7.1",
3332
"zendframework/zend-modulemanager": "^2.7.1",
3433
"zendframework/zend-serializer": "^2.6.1",
@@ -43,7 +42,7 @@
4342
"zendframework/zend-filter": "Zend\\Filter component",
4443
"zendframework/zend-http": "Zend\\Http component",
4544
"zendframework/zend-inputfilter": "Zend\\Inputfilter component",
46-
"zendframework/zend-json": "Zend\\Json component",
45+
"zendframework/zend-json": "To auto-deserialize JSON body content in AbstractRestfulController extensions, when json_decode is unavailable",
4746
"zendframework/zend-log": "Zend\\Log component",
4847
"zendframework/zend-modulemanager": "Zend\\ModuleManager component",
4948
"zendframework/zend-mvc-console": "zend-mvc-console provides the ability to expose zend-mvc as a console application",

composer.lock

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/Controller/AbstractRestfulController.php

Lines changed: 54 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -45,9 +45,23 @@ abstract class AbstractRestfulController extends AbstractController
4545
protected $identifierName = 'id';
4646

4747
/**
48-
* @var int From Zend\Json\Json
48+
* Flag to pass to json_decode and/or Zend\Json\Json::decode.
49+
*
50+
* The flags in Zend\Json\Json::decode are integers, but when evaluated
51+
* in a boolean context map to the flag passed as the second parameter
52+
* to json_decode(). As such, you can specify either the Zend\Json\Json
53+
* constant or the boolean value. By default, starting in v3, we use
54+
* the boolean value, and cast to integer if using Zend\Json\Json::decode.
55+
*
56+
* Default value is boolean true, meaning JSON should be cast to
57+
* associative arrays (vs objects).
58+
*
59+
* Override the value in an extending class to set the default behavior
60+
* for your class.
61+
*
62+
* @var int|bool
4963
*/
50-
protected $jsonDecodeType = Json::TYPE_ARRAY;
64+
protected $jsonDecodeType = true;
5165

5266
/**
5367
* Map of custom HTTP methods and their handlers
@@ -444,16 +458,16 @@ public function onDispatch(MvcEvent $e)
444458
*
445459
* @param Request $request
446460
* @return mixed
461+
* @throws Exception\DomainException If a JSON request was made, but no
462+
* method for parsing JSON is available.
447463
*/
448464
public function processPostData(Request $request)
449465
{
450466
if ($this->requestHasContentType($request, self::CONTENT_TYPE_JSON)) {
451-
$data = Json::decode($request->getContent(), $this->jsonDecodeType);
452-
} else {
453-
$data = $request->getPost()->toArray();
467+
return $this->create($this->jsonDecode($request->getContent()));
454468
}
455469

456-
return $this->create($data);
470+
return $this->create($request->getPost()->toArray());
457471
}
458472

459473
/**
@@ -564,14 +578,16 @@ protected function getIdentifier($routeMatch, $request)
564578
*
565579
* @param mixed $request
566580
* @return object|string|array
581+
* @throws Exception\DomainException If a JSON request was made, but no
582+
* method for parsing JSON is available.
567583
*/
568584
protected function processBodyContent($request)
569585
{
570586
$content = $request->getContent();
571587

572588
// JSON content? decode and return it.
573589
if ($this->requestHasContentType($request, self::CONTENT_TYPE_JSON)) {
574-
return Json::decode($content, $this->jsonDecodeType);
590+
return $this->jsonDecode($request->getContent());
575591
}
576592

577593
parse_str($content, $parsedParams);
@@ -585,4 +601,35 @@ protected function processBodyContent($request)
585601

586602
return $parsedParams;
587603
}
604+
605+
/**
606+
* Decode a JSON string.
607+
*
608+
* Uses json_decode by default. If that is not available, checks for
609+
* availability of Zend\Json\Json, and uses that if present.
610+
*
611+
* Otherwise, raises an exception.
612+
*
613+
* Marked protected to allow usage from extending classes.
614+
*
615+
* @param string
616+
* @return mixed
617+
* @throws Exception\DomainException if no JSON decoding functionality is
618+
* available.
619+
*/
620+
protected function jsonDecode($string)
621+
{
622+
if (function_exists('json_decode')) {
623+
return json_decode($string, (bool) $this->jsonDecodeType);
624+
}
625+
626+
if (class_exists(Json::class)) {
627+
return Json::decode($string, (int) $this->jsonDecodeType);
628+
}
629+
630+
throw new Exception\DomainException(sprintf(
631+
'Unable to parse JSON request, due to missing ext/json and/or %s',
632+
Json::class
633+
));
634+
}
588635
}

0 commit comments

Comments
 (0)