[ Index ] |
PHP Cross Reference of phpBB-3.3.14-deutsch |
[Summary view] [Print] [Text view]
1 <?php 2 3 /* 4 * This file is part of the Symfony package. 5 * 6 * (c) Fabien Potencier <fabien@symfony.com> 7 * 8 * For the full copyright and license information, please view the LICENSE 9 * file that was distributed with this source code. 10 */ 11 12 namespace Symfony\Component\HttpFoundation; 13 14 /** 15 * Response represents an HTTP response in JSON format. 16 * 17 * Note that this class does not force the returned JSON content to be an 18 * object. It is however recommended that you do return an object as it 19 * protects yourself against XSSI and JSON-JavaScript Hijacking. 20 * 21 * @see https://github.com/OWASP/CheatSheetSeries/blob/master/cheatsheets/AJAX_Security_Cheat_Sheet.md#always-return-json-with-an-object-on-the-outside 22 * 23 * @author Igor Wiedler <igor@wiedler.ch> 24 */ 25 class JsonResponse extends Response 26 { 27 protected $data; 28 protected $callback; 29 30 // Encode <, >, ', &, and " characters in the JSON, making it also safe to be embedded into HTML. 31 // 15 === JSON_HEX_TAG | JSON_HEX_APOS | JSON_HEX_AMP | JSON_HEX_QUOT 32 const DEFAULT_ENCODING_OPTIONS = 15; 33 34 protected $encodingOptions = self::DEFAULT_ENCODING_OPTIONS; 35 36 /** 37 * @param mixed $data The response data 38 * @param int $status The response status code 39 * @param array $headers An array of response headers 40 * @param bool $json If the data is already a JSON string 41 */ 42 public function __construct($data = null, $status = 200, $headers = [], $json = false) 43 { 44 parent::__construct('', $status, $headers); 45 46 if (null === $data) { 47 $data = new \ArrayObject(); 48 } 49 50 $json ? $this->setJson($data) : $this->setData($data); 51 } 52 53 /** 54 * Factory method for chainability. 55 * 56 * Example: 57 * 58 * return JsonResponse::create(['key' => 'value']) 59 * ->setSharedMaxAge(300); 60 * 61 * @param mixed $data The JSON response data 62 * @param int $status The response status code 63 * @param array $headers An array of response headers 64 * 65 * @return static 66 */ 67 public static function create($data = null, $status = 200, $headers = []) 68 { 69 return new static($data, $status, $headers); 70 } 71 72 /** 73 * Factory method for chainability. 74 * 75 * Example: 76 * 77 * return JsonResponse::fromJsonString('{"key": "value"}') 78 * ->setSharedMaxAge(300); 79 * 80 * @param string|null $data The JSON response string 81 * @param int $status The response status code 82 * @param array $headers An array of response headers 83 * 84 * @return static 85 */ 86 public static function fromJsonString($data = null, $status = 200, $headers = []) 87 { 88 return new static($data, $status, $headers, true); 89 } 90 91 /** 92 * Sets the JSONP callback. 93 * 94 * @param string|null $callback The JSONP callback or null to use none 95 * 96 * @return $this 97 * 98 * @throws \InvalidArgumentException When the callback name is not valid 99 */ 100 public function setCallback($callback = null) 101 { 102 if (null !== $callback) { 103 // partially taken from https://geekality.net/2011/08/03/valid-javascript-identifier/ 104 // partially taken from https://github.com/willdurand/JsonpCallbackValidator 105 // JsonpCallbackValidator is released under the MIT License. See https://github.com/willdurand/JsonpCallbackValidator/blob/v1.1.0/LICENSE for details. 106 // (c) William Durand <william.durand1@gmail.com> 107 $pattern = '/^[$_\p{L}][$_\p{L}\p{Mn}\p{Mc}\p{Nd}\p{Pc}\x{200C}\x{200D}]*(?:\[(?:"(?:\\\.|[^"\\\])*"|\'(?:\\\.|[^\'\\\])*\'|\d+)\])*?$/u'; 108 $reserved = [ 109 'break', 'do', 'instanceof', 'typeof', 'case', 'else', 'new', 'var', 'catch', 'finally', 'return', 'void', 'continue', 'for', 'switch', 'while', 110 'debugger', 'function', 'this', 'with', 'default', 'if', 'throw', 'delete', 'in', 'try', 'class', 'enum', 'extends', 'super', 'const', 'export', 111 'import', 'implements', 'let', 'private', 'public', 'yield', 'interface', 'package', 'protected', 'static', 'null', 'true', 'false', 112 ]; 113 $parts = explode('.', $callback); 114 foreach ($parts as $part) { 115 if (!preg_match($pattern, $part) || \in_array($part, $reserved, true)) { 116 throw new \InvalidArgumentException('The callback name is not valid.'); 117 } 118 } 119 } 120 121 $this->callback = $callback; 122 123 return $this->update(); 124 } 125 126 /** 127 * Sets a raw string containing a JSON document to be sent. 128 * 129 * @param string $json 130 * 131 * @return $this 132 * 133 * @throws \InvalidArgumentException 134 */ 135 public function setJson($json) 136 { 137 $this->data = $json; 138 139 return $this->update(); 140 } 141 142 /** 143 * Sets the data to be sent as JSON. 144 * 145 * @param mixed $data 146 * 147 * @return $this 148 * 149 * @throws \InvalidArgumentException 150 */ 151 public function setData($data = []) 152 { 153 if (\defined('HHVM_VERSION')) { 154 // HHVM does not trigger any warnings and let exceptions 155 // thrown from a JsonSerializable object pass through. 156 // If only PHP did the same... 157 $data = json_encode($data, $this->encodingOptions); 158 } else { 159 if (!interface_exists('JsonSerializable', false)) { 160 set_error_handler(function () { return false; }); 161 try { 162 $data = @json_encode($data, $this->encodingOptions); 163 } finally { 164 restore_error_handler(); 165 } 166 } else { 167 try { 168 $data = json_encode($data, $this->encodingOptions); 169 } catch (\Exception $e) { 170 if ('Exception' === \get_class($e) && 0 === strpos($e->getMessage(), 'Failed calling ')) { 171 throw $e->getPrevious() ?: $e; 172 } 173 throw $e; 174 } 175 176 if (\PHP_VERSION_ID >= 70300 && (\JSON_THROW_ON_ERROR & $this->encodingOptions)) { 177 return $this->setJson($data); 178 } 179 } 180 } 181 182 if (\JSON_ERROR_NONE !== json_last_error()) { 183 throw new \InvalidArgumentException(json_last_error_msg()); 184 } 185 186 return $this->setJson($data); 187 } 188 189 /** 190 * Returns options used while encoding data to JSON. 191 * 192 * @return int 193 */ 194 public function getEncodingOptions() 195 { 196 return $this->encodingOptions; 197 } 198 199 /** 200 * Sets options used while encoding data to JSON. 201 * 202 * @param int $encodingOptions 203 * 204 * @return $this 205 */ 206 public function setEncodingOptions($encodingOptions) 207 { 208 $this->encodingOptions = (int) $encodingOptions; 209 210 return $this->setData(json_decode($this->data)); 211 } 212 213 /** 214 * Updates the content and headers according to the JSON data and callback. 215 * 216 * @return $this 217 */ 218 protected function update() 219 { 220 if (null !== $this->callback) { 221 // Not using application/javascript for compatibility reasons with older browsers. 222 $this->headers->set('Content-Type', 'text/javascript'); 223 224 return $this->setContent(sprintf('/**/%s(%s);', $this->callback, $this->data)); 225 } 226 227 // Only set the header when there is none or when it equals 'text/javascript' (from a previous update with callback) 228 // in order to not overwrite a custom definition. 229 if (!$this->headers->has('Content-Type') || 'text/javascript' === $this->headers->get('Content-Type')) { 230 $this->headers->set('Content-Type', 'application/json'); 231 } 232 233 return $this->setContent($this->data); 234 } 235 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Mon Nov 25 19:05:08 2024 | Cross-referenced by PHPXref 0.7.1 |