4 * This file is part of the Symfony package.
6 * (c) Fabien Potencier <fabien@symfony.com>
8 * For the full copyright and license information, please view the LICENSE
9 * file that was distributed with this source code.
12 namespace Symfony\Component\HttpFoundation
;
15 * Request represents an HTTP request.
17 * @author Fabien Potencier <fabien@symfony.com>
23 static protected
$trustProxy = false
;
26 * @var \Symfony\Component\HttpFoundation\ParameterBag
33 * @var \Symfony\Component\HttpFoundation\ParameterBag
40 * @var \Symfony\Component\HttpFoundation\ParameterBag
47 * @var \Symfony\Component\HttpFoundation\ServerBag
54 * @var \Symfony\Component\HttpFoundation\FileBag
61 * @var \Symfony\Component\HttpFoundation\ParameterBag
68 * @var \Symfony\Component\HttpFoundation\HeaderBag
77 protected
$acceptableContentTypes;
79 protected
$requestUri;
86 static protected
$formats;
91 * @param array $query The GET parameters
92 * @param array $request The POST parameters
93 * @param array $attributes The request attributes (parameters parsed from the PATH_INFO, ...)
94 * @param array $cookies The COOKIE parameters
95 * @param array $files The FILES parameters
96 * @param array $server The SERVER parameters
97 * @param string $content The raw body data
101 public
function __construct(array $query = array(), array $request = array(), array $attributes = array(), array $cookies = array(), array $files = array(), array $server = array(), $content = null
)
103 $this->initialize($query, $request, $attributes, $cookies, $files, $server, $content);
107 * Sets the parameters for this request.
109 * This method also re-initializes all properties.
111 * @param array $query The GET parameters
112 * @param array $request The POST parameters
113 * @param array $attributes The request attributes (parameters parsed from the PATH_INFO, ...)
114 * @param array $cookies The COOKIE parameters
115 * @param array $files The FILES parameters
116 * @param array $server The SERVER parameters
117 * @param string $content The raw body data
121 public
function initialize(array $query = array(), array $request = array(), array $attributes = array(), array $cookies = array(), array $files = array(), array $server = array(), $content = null
)
123 $this->request
= new
ParameterBag($request);
124 $this->query
= new
ParameterBag($query);
125 $this->attributes
= new
ParameterBag($attributes);
126 $this->cookies
= new
ParameterBag($cookies);
127 $this->files
= new
FileBag($files);
128 $this->server
= new
ServerBag($server);
129 $this->headers
= new
HeaderBag($this->server
->getHeaders());
131 $this->content
= $content;
132 $this->languages
= null
;
133 $this->charsets
= null
;
134 $this->acceptableContentTypes
= null
;
135 $this->pathInfo = null
;
136 $this->requestUri
= null
;
137 $this->baseUrl
= null
;
138 $this->basePath
= null
;
139 $this->method
= null
;
140 $this->format
= null
;
144 * Creates a new request with values from PHP's super globals.
146 * @return Request A new request
150 static public
function createFromGlobals()
152 $request = new
static($_GET, $_POST, array(), $_COOKIE, $_FILES, $_SERVER);
154 if (0 === strpos($request->server
->get('CONTENT_TYPE'), 'application/x-www-form-urlencoded')
155 && in_array(strtoupper($request->server
->get('REQUEST_METHOD', 'GET')), array('PUT', 'DELETE'))
157 parse_str($request->getContent(), $data);
158 $request->request
= new
ParameterBag($data);
165 * Creates a Request based on a given URI and configuration.
167 * @param string $uri The URI
168 * @param string $method The HTTP method
169 * @param array $parameters The request (GET) or query (POST) parameters
170 * @param array $cookies The request cookies ($_COOKIE)
171 * @param array $files The request files ($_FILES)
172 * @param array $server The server parameters ($_SERVER)
173 * @param string $content The raw body data
175 * @return Request A Request instance
179 static public
function create($uri, $method = 'GET', $parameters = array(), $cookies = array(), $files = array(), $server = array(), $content = null
)
182 'SERVER_NAME' => 'localhost',
184 'HTTP_HOST' => 'localhost',
185 'HTTP_USER_AGENT' => 'Symfony/2.X',
186 'HTTP_ACCEPT' => 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
187 'HTTP_ACCEPT_LANGUAGE' => 'en-us,en;q=0.5',
188 'HTTP_ACCEPT_CHARSET' => 'ISO-8859-1,utf-8;q=0.7,*;q=0.7',
189 'REMOTE_ADDR' => '127.0.0.1',
191 'SCRIPT_FILENAME' => '',
192 'SERVER_PROTOCOL' => 'HTTP/1.1',
193 'REQUEST_TIME' => time(),
196 $components = parse_url($uri);
197 if (isset($components['host'])) {
198 $defaults['SERVER_NAME'] = $components['host'];
199 $defaults['HTTP_HOST'] = $components['host'];
202 if (isset($components['scheme'])) {
203 if ('https' === $components['scheme']) {
204 $defaults['HTTPS'] = 'on';
205 $defaults['SERVER_PORT'] = 443;
209 if (isset($components['port'])) {
210 $defaults['SERVER_PORT'] = $components['port'];
211 $defaults['HTTP_HOST'] = $defaults['HTTP_HOST'].
':'.
$components['port'];
214 if (!isset($components['path'])) {
215 $components['path'] = '';
218 if (in_array(strtoupper($method), array('POST', 'PUT', 'DELETE'))) {
219 $request = $parameters;
221 $defaults['CONTENT_TYPE'] = 'application/x-www-form-urlencoded';
224 $query = $parameters;
225 if (false
!== $pos = strpos($uri, '?')) {
226 $qs = substr($uri, $pos + 1);
227 parse_str($qs, $params);
229 $query = array_merge($params, $query);
233 $queryString = isset($components['query']) ?
html_entity_decode($components['query']) : '';
234 parse_str($queryString, $qs);
236 $query = array_replace($qs, $query);
239 $uri = $components['path'].
($queryString ?
'?'.
$queryString : '');
241 $server = array_replace($defaults, $server, array(
242 'REQUEST_METHOD' => strtoupper($method),
244 'REQUEST_URI' => $uri,
245 'QUERY_STRING' => $queryString,
248 return new
static($query, $request, array(), $cookies, $files, $server, $content);
252 * Clones a request and overrides some of its parameters.
254 * @param array $query The GET parameters
255 * @param array $request The POST parameters
256 * @param array $attributes The request attributes (parameters parsed from the PATH_INFO, ...)
257 * @param array $cookies The COOKIE parameters
258 * @param array $files The FILES parameters
259 * @param array $server The SERVER parameters
263 public
function duplicate(array $query = null
, array $request = null
, array $attributes = null
, array $cookies = null
, array $files = null
, array $server = null
)
266 if ($query !== null
) {
267 $dup->query
= new
ParameterBag($query);
269 if ($request !== null
) {
270 $dup->request
= new
ParameterBag($request);
272 if ($attributes !== null
) {
273 $dup->attributes
= new
ParameterBag($attributes);
275 if ($cookies !== null
) {
276 $dup->cookies
= new
ParameterBag($cookies);
278 if ($files !== null
) {
279 $dup->files
= new
FileBag($files);
281 if ($server !== null
) {
282 $dup->server
= new
ServerBag($server);
283 $dup->headers
= new
HeaderBag($dup->server
->getHeaders());
285 $dup->languages
= null
;
286 $dup->charsets
= null
;
287 $dup->acceptableContentTypes
= null
;
288 $dup->pathInfo = null
;
289 $dup->requestUri
= null
;
290 $dup->baseUrl
= null
;
291 $dup->basePath
= null
;
299 * Clones the current request.
301 * Note that the session is not cloned as duplicated requests
302 * are most of the time sub-requests of the main one.
304 public
function __clone()
306 $this->query
= clone
$this->query
;
307 $this->request
= clone
$this->request
;
308 $this->attributes
= clone
$this->attributes
;
309 $this->cookies
= clone
$this->cookies
;
310 $this->files
= clone
$this->files
;
311 $this->server
= clone
$this->server
;
312 $this->headers
= clone
$this->headers
;
316 * Returns the request as a string.
318 * @return string The request
320 public
function __toString()
323 sprintf('%s %s %s', $this->getMethod(), $this->getRequestUri(), $this->server
->get('SERVER_PROTOCOL')).
"\r\n".
324 $this->headers.
"\r\n".
329 * Overrides the PHP global variables according to this request instance.
331 * It overrides $_GET, $_POST, $_REQUEST, $_SERVER, $_COOKIE, and $_FILES.
335 public
function overrideGlobals()
337 $_GET = $this->query
->all();
338 $_POST = $this->request
->all();
339 $_SERVER = $this->server
->all();
340 $_COOKIE = $this->cookies
->all();
341 // FIXME: populate $_FILES
343 foreach ($this->headers
->all() as
$key => $value) {
344 $key = strtoupper(str_replace('-', '_', $key));
345 if (in_array($key, array('CONTENT_TYPE', 'CONTENT_LENGTH'))) {
346 $_SERVER[$key] = implode(', ', $value);
348 $_SERVER['HTTP_'.
$key] = implode(', ', $value);
352 // FIXME: should read variables_order and request_order
353 // to know which globals to merge and in which order
354 $_REQUEST = array_merge($_GET, $_POST);
358 * Trusts $_SERVER entries coming from proxies.
360 * You should only call this method if your application
361 * is hosted behind a reverse proxy that you manage.
365 static public
function trustProxyData()
367 self
::$trustProxy = true
;
371 * Gets a "parameter" value.
373 * This method is mainly useful for libraries that want to provide some flexibility.
375 * Order of precedence: GET, PATH, POST, COOKIE
376 * Avoid using this method in controllers:
378 * * prefer to get from a "named" source
380 * @param string $key the key
381 * @param mixed $default the default value
382 * @param type $deep is parameter deep in multidimensional array
386 public
function get($key, $default = null
, $deep = false
)
388 return $this->query
->get($key, $this->attributes
->get($key, $this->request
->get($key, $default, $deep), $deep), $deep);
394 * @return Session|null The session
398 public
function getSession()
400 return $this->session
;
404 * Whether the request contains a Session which was started in one of the
411 public
function hasPreviousSession()
413 // the check for $this->session avoids malicious users trying to fake a session cookie with proper name
414 return $this->cookies
->has(session_name()) && null
!== $this->session
;
418 * Whether the request contains a Session object.
424 public
function hasSession()
426 return null
!== $this->session
;
432 * @param Session $session The Session
436 public
function setSession(Session
$session)
438 $this->session
= $session;
442 * Returns the client IP address.
444 * @param Boolean $proxy Whether the current request has been made behind a proxy or not
446 * @return string The client IP address
450 public
function getClientIp($proxy = false
)
453 if ($this->server
->has('HTTP_CLIENT_IP')) {
454 return $this->server
->get('HTTP_CLIENT_IP');
455 } elseif (self
::$trustProxy && $this->server
->has('HTTP_X_FORWARDED_FOR')) {
456 return $this->server
->get('HTTP_X_FORWARDED_FOR');
460 return $this->server
->get('REMOTE_ADDR');
464 * Returns current script name.
470 public
function getScriptName()
472 return $this->server
->get('SCRIPT_NAME', $this->server
->get('ORIG_SCRIPT_NAME', ''));
476 * Returns the path being requested relative to the executed script.
478 * The path info always starts with a /.
480 * Suppose this request is instantiated from /mysite on localhost:
482 * * http://localhost/mysite returns an empty string
483 * * http://localhost/mysite/about returns '/about'
484 * * http://localhost/mysite/about?var=1 returns '/about'
490 public
function getPathInfo()
492 if (null
=== $this->pathInfo) {
493 $this->pathInfo = $this->preparePathInfo();
496 return $this->pathInfo;
500 * Returns the root path from which this request is executed.
502 * Suppose that an index.php file instantiates this request object:
504 * * http://localhost/index.php returns an empty string
505 * * http://localhost/index.php/page returns an empty string
506 * * http://localhost/web/index.php return '/web'
512 public
function getBasePath()
514 if (null
=== $this->basePath
) {
515 $this->basePath
= $this->prepareBasePath();
518 return $this->basePath
;
522 * Returns the root url from which this request is executed.
524 * The base URL never ends with a /.
526 * This is similar to getBasePath(), except that it also includes the
527 * script filename (e.g. index.php) if one exists.
533 public
function getBaseUrl()
535 if (null
=== $this->baseUrl
) {
536 $this->baseUrl
= $this->prepareBaseUrl();
539 return $this->baseUrl
;
543 * Gets the request's scheme.
549 public
function getScheme()
551 return $this->isSecure() ?
'https' : 'http';
555 * Returns the port on which the request is made.
561 public
function getPort()
563 return $this->headers
->get('X-Forwarded-Port') ?
: $this->server
->get('SERVER_PORT');
567 * Returns the HTTP host being requested.
569 * The port name will be appended to the host if it's non-standard.
575 public
function getHttpHost()
577 $scheme = $this->getScheme();
578 $port = $this->getPort();
580 if (('http' == $scheme && $port == 80) || ('https' == $scheme && $port == 443)) {
581 return $this->getHost();
584 return $this->getHost().
':'.
$port;
588 * Returns the requested URI.
594 public
function getRequestUri()
596 if (null
=== $this->requestUri
) {
597 $this->requestUri
= $this->prepareRequestUri();
600 return $this->requestUri
;
604 * Generates a normalized URI for the Request.
606 * @return string A normalized URI for the Request
608 * @see getQueryString()
612 public
function getUri()
614 $qs = $this->getQueryString();
619 return $this->getScheme().
'://'.
$this->getHttpHost().
$this->getBaseUrl().
$this->getPathInfo().
$qs;
623 * Generates a normalized URI for the given path.
625 * @param string $path A path to use instead of the current one
627 * @return string The normalized URI for the path
631 public
function getUriForPath($path)
633 return $this->getScheme().
'://'.
$this->getHttpHost().
$this->getBaseUrl().
$path;
637 * Generates the normalized query string for the Request.
639 * It builds a normalized query string, where keys/value pairs are alphabetized
640 * and have consistent escaping.
642 * @return string A normalized query string for the Request
646 public
function getQueryString()
648 if (!$qs = $this->server
->get('QUERY_STRING')) {
655 foreach (explode('&', $qs) as
$segment) {
656 if (false
=== strpos($segment, '=')) {
660 $tmp = explode('=', rawurldecode($segment), 2);
661 $parts[] = rawurlencode($tmp[0]).
'='.
rawurlencode($tmp[1]);
665 array_multisort($order, SORT_ASC
, $parts);
667 return implode('&', $parts);
671 * Checks whether the request is secure or not.
677 public
function isSecure()
680 (strtolower($this->server
->get('HTTPS')) == 'on' || $this->server
->get('HTTPS') == 1)
682 (self
::$trustProxy && strtolower($this->headers
->get('SSL_HTTPS')) == 'on' || $this->headers
->get('SSL_HTTPS') == 1)
684 (self
::$trustProxy && strtolower($this->headers
->get('X_FORWARDED_PROTO')) == 'https')
689 * Returns the host name.
695 public
function getHost()
697 if (self
::$trustProxy && $host = $this->headers
->get('X_FORWARDED_HOST')) {
698 $elements = explode(',', $host);
700 $host = trim($elements[count($elements) - 1]);
702 if (!$host = $this->headers
->get('HOST')) {
703 if (!$host = $this->server
->get('SERVER_NAME')) {
704 $host = $this->server
->get('SERVER_ADDR', '');
709 // Remove port number from host
710 $host = preg_replace('/:\d+$/', '', $host);
716 * Sets the request method.
718 * @param string $method
722 public
function setMethod($method)
724 $this->method
= null
;
725 $this->server
->set('REQUEST_METHOD', $method);
729 * Gets the request method.
731 * The method is always an uppercased string.
733 * @return string The request method
737 public
function getMethod()
739 if (null
=== $this->method
) {
740 $this->method
= strtoupper($this->server
->get('REQUEST_METHOD', 'GET'));
741 if ('POST' === $this->method
) {
742 $this->method
= strtoupper($this->headers
->get('X-HTTP-METHOD-OVERRIDE', $this->request
->get('_method', 'POST')));
746 return $this->method
;
750 * Gets the mime type associated with the format.
752 * @param string $format The format
754 * @return string The associated mime type (null if not found)
758 public
function getMimeType($format)
760 if (null
=== static
::$formats) {
761 static
::initializeFormats();
764 return isset(static
::$formats[$format]) ? static
::$formats[$format][0] : null
;
768 * Gets the format associated with the mime type.
770 * @param string $mimeType The associated mime type
772 * @return string The format (null if not found)
776 public
function getFormat($mimeType)
778 if (false
!== $pos = strpos($mimeType, ';')) {
779 $mimeType = substr($mimeType, 0, $pos);
782 if (null
=== static
::$formats) {
783 static
::initializeFormats();
786 foreach (static
::$formats as
$format => $mimeTypes) {
787 if (in_array($mimeType, (array) $mimeTypes)) {
796 * Associates a format with mime types.
798 * @param string $format The format
799 * @param string|array $mimeTypes The associated mime types (the preferred one must be the first as it will be used as the content type)
803 public
function setFormat($format, $mimeTypes)
805 if (null
=== static
::$formats) {
806 static
::initializeFormats();
809 static
::$formats[$format] = is_array($mimeTypes) ?
$mimeTypes : array($mimeTypes);
813 * Gets the request format.
815 * Here is the process to determine the format:
817 * * format defined by the user (with setRequestFormat())
818 * * _format request parameter
821 * @param string $default The default format
823 * @return string The request format
827 public
function getRequestFormat($default = 'html')
829 if (null
=== $this->format
) {
830 $this->format
= $this->get('_format', $default);
833 return $this->format
;
837 * Sets the request format.
839 * @param string $format The request format.
843 public
function setRequestFormat($format)
845 $this->format
= $format;
849 * Checks whether the method is safe or not.
855 public
function isMethodSafe()
857 return in_array($this->getMethod(), array('GET', 'HEAD'));
861 * Returns the request body content.
863 * @param Boolean $asResource If true, a resource will be returned
865 * @return string|resource The request body content or a resource to read the body stream.
867 public
function getContent($asResource = false
)
869 if (false
=== $this->content
|| (true
=== $asResource && null
!== $this->content
)) {
870 throw new \
LogicException('getContent() can only be called once when using the resource return type.');
873 if (true
=== $asResource) {
874 $this->content
= false
;
876 return fopen('php://input', 'rb');
879 if (null
=== $this->content
) {
880 $this->content
= file_get_contents('php://input');
883 return $this->content
;
889 * @return array The entity tags
891 public
function getETags()
893 return preg_split('/\s*,\s*/', $this->headers
->get('if_none_match'), null
, PREG_SPLIT_NO_EMPTY
);
896 public
function isNoCache()
898 return $this->headers
->hasCacheControlDirective('no-cache') || 'no-cache' == $this->headers
->get('Pragma');
902 * Returns the preferred language.
904 * @param array $locales An array of ordered available locales
906 * @return string The preferred locale
910 public
function getPreferredLanguage(array $locales = null
)
912 $preferredLanguages = $this->getLanguages();
914 if (null
=== $locales) {
915 return isset($preferredLanguages[0]) ?
$preferredLanguages[0] : null
;
918 if (!$preferredLanguages) {
922 $preferredLanguages = array_values(array_intersect($preferredLanguages, $locales));
924 return isset($preferredLanguages[0]) ?
$preferredLanguages[0] : $locales[0];
928 * Gets a list of languages acceptable by the client browser.
930 * @return array Languages ordered in the user browser preferences
934 public
function getLanguages()
936 if (null
!== $this->languages
) {
937 return $this->languages
;
940 $languages = $this->splitHttpAcceptHeader($this->headers
->get('Accept-Language'));
941 $this->languages
= array();
942 foreach ($languages as
$lang => $q) {
943 if (strstr($lang, '-')) {
944 $codes = explode('-', $lang);
945 if ($codes[0] == 'i') {
946 // Language not listed in ISO 639 that are not variants
947 // of any listed language, which can be registered with the
948 // i-prefix, such as i-cherokee
949 if (count($codes) > 1) {
953 for ($i = 0, $max = count($codes); $i < $max; $i++) {
955 $lang = strtolower($codes[0]);
957 $lang .
= '_'.
strtoupper($codes[$i]);
963 $this->languages
[] = $lang;
966 return $this->languages
;
970 * Gets a list of charsets acceptable by the client browser.
972 * @return array List of charsets in preferable order
976 public
function getCharsets()
978 if (null
!== $this->charsets
) {
979 return $this->charsets
;
982 return $this->charsets
= array_keys($this->splitHttpAcceptHeader($this->headers
->get('Accept-Charset')));
986 * Gets a list of content types acceptable by the client browser
988 * @return array List of content types in preferable order
992 public
function getAcceptableContentTypes()
994 if (null
!== $this->acceptableContentTypes
) {
995 return $this->acceptableContentTypes
;
998 return $this->acceptableContentTypes
= array_keys($this->splitHttpAcceptHeader($this->headers
->get('Accept')));
1002 * Returns true if the request is a XMLHttpRequest.
1004 * It works if your JavaScript library set an X-Requested-With HTTP header.
1005 * It is known to work with Prototype, Mootools, jQuery.
1007 * @return Boolean true if the request is an XMLHttpRequest, false otherwise
1011 public
function isXmlHttpRequest()
1013 return 'XMLHttpRequest' == $this->headers
->get('X-Requested-With');
1017 * Splits an Accept-* HTTP header.
1019 * @param string $header Header to split
1021 public
function splitHttpAcceptHeader($header)
1028 foreach (array_filter(explode(',', $header)) as
$value) {
1029 // Cut off any q-value that might come after a semi-colon
1030 if ($pos = strpos($value, ';')) {
1031 $q = (float) trim(substr($value, strpos($value, '=') + 1));
1032 $value = trim(substr($value, 0, $pos));
1038 $values[trim($value)] = $q;
1049 * The following methods are derived from code of the Zend Framework (1.10dev - 2010-01-24)
1051 * Code subject to the new BSD license (http://framework.zend.com/license/new-bsd).
1053 * Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
1056 protected
function prepareRequestUri()
1060 if ($this->headers
->has('X_REWRITE_URL')) {
1061 // check this first so IIS will catch
1062 $requestUri = $this->headers
->get('X_REWRITE_URL');
1063 } elseif ($this->server
->get('IIS_WasUrlRewritten') == '1' && $this->server
->get('UNENCODED_URL') != '') {
1064 // IIS7 with URL Rewrite: make sure we get the unencoded url (double slash problem)
1065 $requestUri = $this->server
->get('UNENCODED_URL');
1066 } elseif ($this->server
->has('REQUEST_URI')) {
1067 $requestUri = $this->server
->get('REQUEST_URI');
1068 // HTTP proxy reqs setup request uri with scheme and host [and port] + the url path, only use url path
1069 $schemeAndHttpHost = $this->getScheme().
'://'.
$this->getHttpHost();
1070 if (strpos($requestUri, $schemeAndHttpHost) === 0) {
1071 $requestUri = substr($requestUri, strlen($schemeAndHttpHost));
1073 } elseif ($this->server
->has('ORIG_PATH_INFO')) {
1074 // IIS 5.0, PHP as CGI
1075 $requestUri = $this->server
->get('ORIG_PATH_INFO');
1076 if ($this->server
->get('QUERY_STRING')) {
1077 $requestUri .
= '?'.
$this->server
->get('QUERY_STRING');
1084 protected
function prepareBaseUrl()
1086 $filename = basename($this->server
->get('SCRIPT_FILENAME'));
1088 if (basename($this->server
->get('SCRIPT_NAME')) === $filename) {
1089 $baseUrl = $this->server
->get('SCRIPT_NAME');
1090 } elseif (basename($this->server
->get('PHP_SELF')) === $filename) {
1091 $baseUrl = $this->server
->get('PHP_SELF');
1092 } elseif (basename($this->server
->get('ORIG_SCRIPT_NAME')) === $filename) {
1093 $baseUrl = $this->server
->get('ORIG_SCRIPT_NAME'); // 1and1 shared hosting compatibility
1095 // Backtrack up the script_filename to find the portion matching
1097 $path = $this->server
->get('PHP_SELF', '');
1098 $file = $this->server
->get('SCRIPT_FILENAME', '');
1099 $segs = explode('/', trim($file, '/'));
1100 $segs = array_reverse($segs);
1102 $last = count($segs);
1105 $seg = $segs[$index];
1106 $baseUrl = '/'.
$seg.
$baseUrl;
1108 } while (($last > $index) && (false
!== ($pos = strpos($path, $baseUrl))) && (0 != $pos));
1111 // Does the baseUrl have anything in common with the request_uri?
1112 $requestUri = $this->getRequestUri();
1114 if ($baseUrl && 0 === strpos($requestUri, $baseUrl)) {
1115 // full $baseUrl matches
1119 if ($baseUrl && 0 === strpos($requestUri, dirname($baseUrl))) {
1120 // directory portion of $baseUrl matches
1121 return rtrim(dirname($baseUrl), '/');
1124 $truncatedRequestUri = $requestUri;
1125 if (($pos = strpos($requestUri, '?')) !== false
) {
1126 $truncatedRequestUri = substr($requestUri, 0, $pos);
1129 $basename = basename($baseUrl);
1130 if (empty($basename) || !strpos($truncatedRequestUri, $basename)) {
1131 // no match whatsoever; set it blank
1135 // If using mod_rewrite or ISAPI_Rewrite strip the script filename
1136 // out of baseUrl. $pos !== 0 makes sure it is not matching a value
1137 // from PATH_INFO or QUERY_STRING
1138 if ((strlen($requestUri) >= strlen($baseUrl)) && ((false
!== ($pos = strpos($requestUri, $baseUrl))) && ($pos !== 0))) {
1139 $baseUrl = substr($requestUri, 0, $pos + strlen($baseUrl));
1142 return rtrim($baseUrl, '/');
1146 * Prepares base path.
1148 * @return string base path
1150 protected
function prepareBasePath()
1152 $filename = basename($this->server
->get('SCRIPT_FILENAME'));
1153 $baseUrl = $this->getBaseUrl();
1154 if (empty($baseUrl)) {
1158 if (basename($baseUrl) === $filename) {
1159 $basePath = dirname($baseUrl);
1161 $basePath = $baseUrl;
1164 if ('\\' === DIRECTORY_SEPARATOR
) {
1165 $basePath = str_replace('\\', '/', $basePath);
1168 return rtrim($basePath, '/');
1172 * Prepares path info.
1174 * @return string path info
1176 protected
function preparePathInfo()
1178 $baseUrl = $this->getBaseUrl();
1180 if (null
=== ($requestUri = $this->getRequestUri())) {
1186 // Remove the query string from REQUEST_URI
1187 if ($pos = strpos($requestUri, '?')) {
1188 $requestUri = substr($requestUri, 0, $pos);
1191 if ((null
!== $baseUrl) && (false
=== ($pathInfo = substr(urldecode($requestUri), strlen(urldecode($baseUrl)))))) {
1192 // If substr() returns false then PATH_INFO is set to an empty string
1194 } elseif (null
=== $baseUrl) {
1198 return (string) $pathInfo;
1202 * Initializes HTTP request formats.
1204 static protected
function initializeFormats()
1206 static
::$formats = array(
1207 'html' => array('text/html', 'application/xhtml+xml'),
1208 'txt' => array('text/plain'),
1209 'js' => array('application/javascript', 'application/x-javascript', 'text/javascript'),
1210 'css' => array('text/css'),
1211 'json' => array('application/json', 'application/x-json'),
1212 'xml' => array('text/xml', 'application/xml', 'application/x-xml'),
1213 'rdf' => array('application/rdf+xml'),
1214 'atom' => array('application/atom+xml'),