@@ -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