Verzeichnisstruktur phpBB-3.3.15
- Veröffentlicht
- 28.08.2024
So funktioniert es
|
Auf das letzte Element klicken. Dies geht jeweils ein Schritt zurück |
Auf das Icon klicken, dies öffnet das Verzeichnis. Nochmal klicken schließt das Verzeichnis. |
|
(Beispiel Datei-Icons)
|
Auf das Icon klicken um den Quellcode anzuzeigen |
JsonResponse.php
001 <?php
002
003 /*
004 * This file is part of the Symfony package.
005 *
006 * (c) Fabien Potencier <fabien@symfony.com>
007 *
008 * For the full copyright and license information, please view the LICENSE
009 * file that was distributed with this source code.
010 */
011
012 namespace Symfony\Component\HttpFoundation;
013
014 /**
015 * Response represents an HTTP response in JSON format.
016 *
017 * Note that this class does not force the returned JSON content to be an
018 * object. It is however recommended that you do return an object as it
019 * protects yourself against XSSI and JSON-JavaScript Hijacking.
020 *
021 * @see https://github.com/OWASP/CheatSheetSeries/blob/master/cheatsheets/AJAX_Security_Cheat_Sheet.md#always-return-json-with-an-object-on-the-outside
022 *
023 * @author Igor Wiedler <igor@wiedler.ch>
024 */
025 class JsonResponse extends Response
026 {
027 protected $data;
028 protected $callback;
029
030 // Encode <, >, ', &, and " characters in the JSON, making it also safe to be embedded into HTML.
031 // 15 === JSON_HEX_TAG | JSON_HEX_APOS | JSON_HEX_AMP | JSON_HEX_QUOT
032 const DEFAULT_ENCODING_OPTIONS = 15;
033
034 protected $encodingOptions = self::DEFAULT_ENCODING_OPTIONS;
035
036 /**
037 * @param mixed $data The response data
038 * @param int $status The response status code
039 * @param array $headers An array of response headers
040 * @param bool $json If the data is already a JSON string
041 */
042 public function __construct($data = null, $status = 200, $headers = [], $json = false)
043 {
044 parent::__construct('', $status, $headers);
045
046 if (null === $data) {
047 $data = new \ArrayObject();
048 }
049
050 $json ? $this->setJson($data) : $this->setData($data);
051 }
052
053 /**
054 * Factory method for chainability.
055 *
056 * Example:
057 *
058 * return JsonResponse::create(['key' => 'value'])
059 * ->setSharedMaxAge(300);
060 *
061 * @param mixed $data The JSON response data
062 * @param int $status The response status code
063 * @param array $headers An array of response headers
064 *
065 * @return static
066 */
067 public static function create($data = null, $status = 200, $headers = [])
068 {
069 return new static($data, $status, $headers);
070 }
071
072 /**
073 * Factory method for chainability.
074 *
075 * Example:
076 *
077 * return JsonResponse::fromJsonString('{"key": "value"}')
078 * ->setSharedMaxAge(300);
079 *
080 * @param string|null $data The JSON response string
081 * @param int $status The response status code
082 * @param array $headers An array of response headers
083 *
084 * @return static
085 */
086 public static function fromJsonString($data = null, $status = 200, $headers = [])
087 {
088 return new static($data, $status, $headers, true);
089 }
090
091 /**
092 * Sets the JSONP callback.
093 *
094 * @param string|null $callback The JSONP callback or null to use none
095 *
096 * @return $this
097 *
098 * @throws \InvalidArgumentException When the callback name is not valid
099 */
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 }
236