[ Index ] |
PHP Cross Reference of phpBB-3.1.12-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://www.owasp.org/index.php/OWASP_AJAX_Security_Guidelines#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 " for RFC4627-compliant JSON, which may also be embedded into HTML. 31 // 15 === JSON_HEX_TAG | JSON_HEX_APOS | JSON_HEX_AMP | JSON_HEX_QUOT 32 private $encodingOptions = 15; 33 34 /** 35 * Constructor. 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 */ 41 public function __construct($data = null, $status = 200, $headers = array()) 42 { 43 parent::__construct('', $status, $headers); 44 45 if (null === $data) { 46 $data = new \ArrayObject(); 47 } 48 49 $this->setData($data); 50 } 51 52 /** 53 * {@inheritdoc} 54 */ 55 public static function create($data = null, $status = 200, $headers = array()) 56 { 57 return new static($data, $status, $headers); 58 } 59 60 /** 61 * Sets the JSONP callback. 62 * 63 * @param string|null $callback The JSONP callback or null to use none 64 * 65 * @return JsonResponse 66 * 67 * @throws \InvalidArgumentException When the callback name is not valid 68 */ 69 public function setCallback($callback = null) 70 { 71 if (null !== $callback) { 72 // taken from http://www.geekality.net/2011/08/03/valid-javascript-identifier/ 73 $pattern = '/^[$_\p{L}][$_\p{L}\p{Mn}\p{Mc}\p{Nd}\p{Pc}\x{200C}\x{200D}]*+$/u'; 74 $parts = explode('.', $callback); 75 foreach ($parts as $part) { 76 if (!preg_match($pattern, $part)) { 77 throw new \InvalidArgumentException('The callback name is not valid.'); 78 } 79 } 80 } 81 82 $this->callback = $callback; 83 84 return $this->update(); 85 } 86 87 /** 88 * Sets the data to be sent as JSON. 89 * 90 * @param mixed $data 91 * 92 * @return JsonResponse 93 * 94 * @throws \InvalidArgumentException 95 */ 96 public function setData($data = array()) 97 { 98 if (defined('HHVM_VERSION')) { 99 // HHVM does not trigger any warnings and let exceptions 100 // thrown from a JsonSerializable object pass through. 101 // If only PHP did the same... 102 $data = json_encode($data, $this->encodingOptions); 103 } else { 104 try { 105 if (PHP_VERSION_ID < 50400) { 106 // PHP 5.3 triggers annoying warnings for some 107 // types that can't be serialized as JSON (INF, resources, etc.) 108 // but doesn't provide the JsonSerializable interface. 109 set_error_handler(function () { return false; }); 110 $data = @json_encode($data, $this->encodingOptions); 111 } else { 112 // PHP 5.4 and up wrap exceptions thrown by JsonSerializable 113 // objects in a new exception that needs to be removed. 114 // Fortunately, PHP 5.5 and up do not trigger any warning anymore. 115 if (PHP_VERSION_ID < 50500) { 116 // Clear json_last_error() 117 json_encode(null); 118 $errorHandler = set_error_handler('var_dump'); 119 restore_error_handler(); 120 set_error_handler(function () use ($errorHandler) { 121 if (JSON_ERROR_NONE === json_last_error()) { 122 return $errorHandler && false !== call_user_func_array($errorHandler, func_get_args()); 123 } 124 }); 125 } 126 127 $data = json_encode($data, $this->encodingOptions); 128 } 129 130 if (PHP_VERSION_ID < 50500) { 131 restore_error_handler(); 132 } 133 } catch (\Exception $e) { 134 if (PHP_VERSION_ID < 50500) { 135 restore_error_handler(); 136 } 137 if (PHP_VERSION_ID >= 50400 && 'Exception' === get_class($e) && 0 === strpos($e->getMessage(), 'Failed calling ')) { 138 throw $e->getPrevious() ?: $e; 139 } 140 throw $e; 141 } 142 } 143 144 if (JSON_ERROR_NONE !== json_last_error()) { 145 throw new \InvalidArgumentException($this->transformJsonError()); 146 } 147 148 $this->data = $data; 149 150 return $this->update(); 151 } 152 153 /** 154 * Updates the content and headers according to the JSON data and callback. 155 * 156 * @return JsonResponse 157 */ 158 protected function update() 159 { 160 if (null !== $this->callback) { 161 // Not using application/javascript for compatibility reasons with older browsers. 162 $this->headers->set('Content-Type', 'text/javascript'); 163 164 return $this->setContent(sprintf('/**/%s(%s);', $this->callback, $this->data)); 165 } 166 167 // Only set the header when there is none or when it equals 'text/javascript' (from a previous update with callback) 168 // in order to not overwrite a custom definition. 169 if (!$this->headers->has('Content-Type') || 'text/javascript' === $this->headers->get('Content-Type')) { 170 $this->headers->set('Content-Type', 'application/json'); 171 } 172 173 return $this->setContent($this->data); 174 } 175 176 private function transformJsonError() 177 { 178 if (function_exists('json_last_error_msg')) { 179 return json_last_error_msg(); 180 } 181 182 switch (json_last_error()) { 183 case JSON_ERROR_DEPTH: 184 return 'Maximum stack depth exceeded.'; 185 186 case JSON_ERROR_STATE_MISMATCH: 187 return 'Underflow or the modes mismatch.'; 188 189 case JSON_ERROR_CTRL_CHAR: 190 return 'Unexpected control character found.'; 191 192 case JSON_ERROR_SYNTAX: 193 return 'Syntax error, malformed JSON.'; 194 195 case JSON_ERROR_UTF8: 196 return 'Malformed UTF-8 characters, possibly incorrectly encoded.'; 197 198 default: 199 return 'Unknown error.'; 200 } 201 } 202 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Thu Jan 11 00:25:41 2018 | Cross-referenced by PHPXref 0.7.1 |