Namespaces

  • Latte
    • Loaders
    • Macros
    • Runtime
  • Nette
    • Application
      • Responses
      • Routers
      • UI
    • Bridges
      • ApplicationDI
      • ApplicationLatte
      • ApplicationTracy
      • CacheDI
      • CacheLatte
      • DatabaseDI
      • DatabaseTracy
      • DITracy
      • FormsDI
      • FormsLatte
      • Framework
      • HttpDI
      • HttpTracy
      • MailDI
      • ReflectionDI
      • SecurityDI
      • SecurityTracy
    • Caching
      • Storages
    • ComponentModel
    • Database
      • Conventions
      • Drivers
      • Reflection
      • Table
    • DI
      • Config
        • Adapters
      • Extensions
    • Diagnostics
    • Forms
      • Controls
      • Rendering
    • Http
    • Iterators
    • Latte
    • Loaders
    • Localization
    • Mail
    • Neon
    • PhpGenerator
    • Reflection
    • Security
    • Templating
    • Utils
  • NetteModule
  • none
  • Tracy
    • Bridges
      • Nette

Classes

  • Context
  • FileUpload
  • Helpers
  • Request
  • RequestFactory
  • Response
  • Session
  • SessionSection
  • Url
  • UrlScript
  • UserStorage

Interfaces

  • IRequest
  • IResponse
  • ISessionStorage
  • Overview
  • Namespace
  • Class
  • Tree
  • Deprecated
  1: <?php
  2: 
  3: /**
  4:  * This file is part of the Nette Framework (https://nette.org)
  5:  * Copyright (c) 2004 David Grudl (https://davidgrudl.com)
  6:  */
  7: 
  8: namespace Nette\Http;
  9: 
 10: use Nette;
 11: use Nette\Utils\DateTime;
 12: 
 13: 
 14: /**
 15:  * HttpResponse class.
 16:  */
 17: class Response extends Nette\Object implements IResponse
 18: {
 19:     /** @var bool  Send invisible garbage for IE 6? */
 20:     private static $fixIE = TRUE;
 21: 
 22:     /** @var string The domain in which the cookie will be available */
 23:     public $cookieDomain = '';
 24: 
 25:     /** @var string The path in which the cookie will be available */
 26:     public $cookiePath = '/';
 27: 
 28:     /** @var string Whether the cookie is available only through HTTPS */
 29:     public $cookieSecure = FALSE;
 30: 
 31:     /** @var string Whether the cookie is hidden from client-side */
 32:     public $cookieHttpOnly = TRUE;
 33: 
 34:     /** @var bool Whether warn on possible problem with data in output buffer */
 35:     public $warnOnBuffer = TRUE;
 36: 
 37:     /** @var int HTTP response code */
 38:     private $code = self::S200_OK;
 39: 
 40: 
 41:     public function __construct()
 42:     {
 43:         if (PHP_VERSION_ID >= 50400) {
 44:             if (is_int($code = http_response_code())) {
 45:                 $this->code = $code;
 46:             }
 47:         }
 48: 
 49:         if (PHP_VERSION_ID >= 50401) { // PHP bug #61106
 50:             $rm = new \ReflectionMethod('Nette\Http\Helpers::removeDuplicateCookies');
 51:             header_register_callback($rm->getClosure()); // requires closure due PHP bug #66375
 52:         }
 53:     }
 54: 
 55: 
 56:     /**
 57:      * Sets HTTP response code.
 58:      * @param  int
 59:      * @return self
 60:      * @throws Nette\InvalidArgumentException  if code is invalid
 61:      * @throws Nette\InvalidStateException  if HTTP headers have been sent
 62:      */
 63:     public function setCode($code)
 64:     {
 65:         $code = (int) $code;
 66:         if ($code < 100 || $code > 599) {
 67:             throw new Nette\InvalidArgumentException("Bad HTTP response '$code'.");
 68:         }
 69:         self::checkHeaders();
 70:         $this->code = $code;
 71:         $protocol = isset($_SERVER['SERVER_PROTOCOL']) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.1';
 72:         header($protocol . ' ' . $code, TRUE, $code);
 73:         return $this;
 74:     }
 75: 
 76: 
 77:     /**
 78:      * Returns HTTP response code.
 79:      * @return int
 80:      */
 81:     public function getCode()
 82:     {
 83:         return $this->code;
 84:     }
 85: 
 86: 
 87:     /**
 88:      * Sends a HTTP header and replaces a previous one.
 89:      * @param  string  header name
 90:      * @param  string  header value
 91:      * @return self
 92:      * @throws Nette\InvalidStateException  if HTTP headers have been sent
 93:      */
 94:     public function setHeader($name, $value)
 95:     {
 96:         self::checkHeaders();
 97:         if ($value === NULL) {
 98:             header_remove($name);
 99:         } elseif (strcasecmp($name, 'Content-Length') === 0 && ini_get('zlib.output_compression')) {
100:             // ignore, PHP bug #44164
101:         } else {
102:             header($name . ': ' . $value, TRUE, $this->code);
103:         }
104:         return $this;
105:     }
106: 
107: 
108:     /**
109:      * Adds HTTP header.
110:      * @param  string  header name
111:      * @param  string  header value
112:      * @return self
113:      * @throws Nette\InvalidStateException  if HTTP headers have been sent
114:      */
115:     public function addHeader($name, $value)
116:     {
117:         self::checkHeaders();
118:         header($name . ': ' . $value, FALSE, $this->code);
119:         return $this;
120:     }
121: 
122: 
123:     /**
124:      * Sends a Content-type HTTP header.
125:      * @param  string  mime-type
126:      * @param  string  charset
127:      * @return self
128:      * @throws Nette\InvalidStateException  if HTTP headers have been sent
129:      */
130:     public function setContentType($type, $charset = NULL)
131:     {
132:         $this->setHeader('Content-Type', $type . ($charset ? '; charset=' . $charset : ''));
133:         return $this;
134:     }
135: 
136: 
137:     /**
138:      * Redirects to a new URL. Note: call exit() after it.
139:      * @param  string  URL
140:      * @param  int     HTTP code
141:      * @return void
142:      * @throws Nette\InvalidStateException  if HTTP headers have been sent
143:      */
144:     public function redirect($url, $code = self::S302_FOUND)
145:     {
146:         $this->setCode($code);
147:         $this->setHeader('Location', $url);
148:         if (preg_match('#^https?:|^\s*+[a-z0-9+.-]*+[^:]#i', $url)) {
149:             $escapedUrl = htmlSpecialChars($url, ENT_IGNORE | ENT_QUOTES, 'UTF-8');
150:             echo "<h1>Redirect</h1>\n\n<p><a href=\"$escapedUrl\">Please click here to continue</a>.</p>";
151:         }
152:     }
153: 
154: 
155:     /**
156:      * Sets the number of seconds before a page cached on a browser expires.
157:      * @param  string|int|\DateTime  time, value 0 means "until the browser is closed"
158:      * @return self
159:      * @throws Nette\InvalidStateException  if HTTP headers have been sent
160:      */
161:     public function setExpiration($time)
162:     {
163:         $this->setHeader('Pragma', NULL);
164:         if (!$time) { // no cache
165:             $this->setHeader('Cache-Control', 's-maxage=0, max-age=0, must-revalidate');
166:             $this->setHeader('Expires', 'Mon, 23 Jan 1978 10:00:00 GMT');
167:             return $this;
168:         }
169: 
170:         $time = DateTime::from($time);
171:         $this->setHeader('Cache-Control', 'max-age=' . ($time->format('U') - time()));
172:         $this->setHeader('Expires', Helpers::formatDate($time));
173:         return $this;
174:     }
175: 
176: 
177:     /**
178:      * Checks if headers have been sent.
179:      * @return bool
180:      */
181:     public function isSent()
182:     {
183:         return headers_sent();
184:     }
185: 
186: 
187:     /**
188:      * Returns value of an HTTP header.
189:      * @param  string
190:      * @param  mixed
191:      * @return mixed
192:      */
193:     public function getHeader($header, $default = NULL)
194:     {
195:         $header .= ':';
196:         $len = strlen($header);
197:         foreach (headers_list() as $item) {
198:             if (strncasecmp($item, $header, $len) === 0) {
199:                 return ltrim(substr($item, $len));
200:             }
201:         }
202:         return $default;
203:     }
204: 
205: 
206:     /**
207:      * Returns a list of headers to sent.
208:      * @return array (name => value)
209:      */
210:     public function getHeaders()
211:     {
212:         $headers = array();
213:         foreach (headers_list() as $header) {
214:             $a = strpos($header, ':');
215:             $headers[substr($header, 0, $a)] = (string) substr($header, $a + 2);
216:         }
217:         return $headers;
218:     }
219: 
220: 
221:     /**
222:      * @deprecated
223:      */
224:     public static function date($time = NULL)
225:     {
226:         return Helpers::formatDate($time);
227:     }
228: 
229: 
230:     /**
231:      * @return void
232:      */
233:     public function __destruct()
234:     {
235:         if (self::$fixIE && isset($_SERVER['HTTP_USER_AGENT']) && strpos($_SERVER['HTTP_USER_AGENT'], 'MSIE ') !== FALSE
236:             && in_array($this->code, array(400, 403, 404, 405, 406, 408, 409, 410, 500, 501, 505), TRUE)
237:             && preg_match('#^text/html(?:;|$)#', $this->getHeader('Content-Type', 'text/html'))
238:         ) {
239:             echo Nette\Utils\Random::generate(2e3, " \t\r\n"); // sends invisible garbage for IE
240:             self::$fixIE = FALSE;
241:         }
242:     }
243: 
244: 
245:     /**
246:      * Sends a cookie.
247:      * @param  string name of the cookie
248:      * @param  string value
249:      * @param  string|int|\DateTime  expiration time, value 0 means "until the browser is closed"
250:      * @param  string
251:      * @param  string
252:      * @param  bool
253:      * @param  bool
254:      * @return self
255:      * @throws Nette\InvalidStateException  if HTTP headers have been sent
256:      */
257:     public function setCookie($name, $value, $time, $path = NULL, $domain = NULL, $secure = NULL, $httpOnly = NULL)
258:     {
259:         self::checkHeaders();
260:         setcookie(
261:             $name,
262:             $value,
263:             $time ? DateTime::from($time)->format('U') : 0,
264:             $path === NULL ? $this->cookiePath : (string) $path,
265:             $domain === NULL ? $this->cookieDomain : (string) $domain,
266:             $secure === NULL ? $this->cookieSecure : (bool) $secure,
267:             $httpOnly === NULL ? $this->cookieHttpOnly : (bool) $httpOnly
268:         );
269:         Helpers::removeDuplicateCookies();
270:         return $this;
271:     }
272: 
273: 
274:     /**
275:      * Deletes a cookie.
276:      * @param  string name of the cookie.
277:      * @param  string
278:      * @param  string
279:      * @param  bool
280:      * @return void
281:      * @throws Nette\InvalidStateException  if HTTP headers have been sent
282:      */
283:     public function deleteCookie($name, $path = NULL, $domain = NULL, $secure = NULL)
284:     {
285:         $this->setCookie($name, FALSE, 0, $path, $domain, $secure);
286:     }
287: 
288: 
289:     /** @internal @deprecated */
290:     public function removeDuplicateCookies()
291:     {
292:         trigger_error('Use Nette\Http\Helpers::removeDuplicateCookies()', E_USER_WARNING);
293:     }
294: 
295: 
296:     private function checkHeaders()
297:     {
298:         if (headers_sent($file, $line)) {
299:             throw new Nette\InvalidStateException('Cannot send header after HTTP headers have been sent' . ($file ? " (output started at $file:$line)." : '.'));
300: 
301:         } elseif ($this->warnOnBuffer && ob_get_length() && !array_filter(ob_get_status(TRUE), function ($i) { return !$i['chunk_size']; })) {
302:             trigger_error('Possible problem: you are sending a HTTP header while already having some data in output buffer. Try Tracy\OutputDebugger or start session earlier.', E_USER_NOTICE);
303:         }
304:     }
305: 
306: }
307: 
Nette 2.3-20160731 API API documentation generated by ApiGen 2.8.0