setPayload($data); $this->encodingOptions = $encodingOptions; $json = $this->jsonEncode($data, $this->encodingOptions); $body = $this->createBodyFromJson($json); $headers = $this->injectContentType('application/json', $headers); parent::__construct($body, $status, $headers); } /** * @return mixed */ public function getPayload() { return $this->payload; } /** * @param mixed $data */ public function withPayload($data): JsonResponse { $new = clone $this; $new->setPayload($data); return $this->updateBodyFor($new); } public function getEncodingOptions(): int { return $this->encodingOptions; } public function withEncodingOptions(int $encodingOptions): JsonResponse { $new = clone $this; $new->encodingOptions = $encodingOptions; return $this->updateBodyFor($new); } private function createBodyFromJson(string $json): Stream { $body = new Stream('php://temp', 'wb+'); $body->write($json); $body->rewind(); return $body; } /** * Encode the provided data to JSON. * * @param mixed $data * @throws Exception\InvalidArgumentException If unable to encode the $data to JSON. */ private function jsonEncode($data, int $encodingOptions): string { if (is_resource($data)) { throw new Exception\InvalidArgumentException('Cannot JSON encode resources'); } // Clear json_last_error() json_encode(null); $json = json_encode($data, $encodingOptions); if (JSON_ERROR_NONE !== json_last_error()) { throw new Exception\InvalidArgumentException(sprintf( 'Unable to encode data to JSON in %s: %s', self::class, json_last_error_msg() )); } return $json; } /** * @param mixed $data */ private function setPayload($data): void { if (is_object($data)) { $data = clone $data; } $this->payload = $data; } /** * Update the response body for the given instance. * * @param self $toUpdate Instance to update. * @return JsonResponse Returns a new instance with an updated body. */ private function updateBodyFor(JsonResponse $toUpdate): JsonResponse { $json = $this->jsonEncode($toUpdate->payload, $toUpdate->encodingOptions); $body = $this->createBodyFromJson($json); return $toUpdate->withBody($body); } }