1: <?php
2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32:
33: namespace Slim\Http;
34:
35: 36: 37: 38: 39: 40: 41: 42: 43: 44:
45: class Request
46: {
47: const METHOD_HEAD = 'HEAD';
48: const METHOD_GET = 'GET';
49: const METHOD_POST = 'POST';
50: const METHOD_PUT = 'PUT';
51: const METHOD_DELETE = 'DELETE';
52: const METHOD_OPTIONS = 'OPTIONS';
53: const METHOD_OVERRIDE = '_METHOD';
54:
55: 56: 57:
58: protected static $formDataMediaTypes = array('application/x-www-form-urlencoded');
59:
60: 61: 62:
63: protected $env;
64:
65: 66: 67: 68: 69:
70: public function __construct($env)
71: {
72: $this->env = $env;
73: }
74:
75: 76: 77: 78:
79: public function getMethod()
80: {
81: return $this->env['REQUEST_METHOD'];
82: }
83:
84: 85: 86: 87:
88: public function isGet()
89: {
90: return $this->getMethod() === self::METHOD_GET;
91: }
92:
93: 94: 95: 96:
97: public function isPost()
98: {
99: return $this->getMethod() === self::METHOD_POST;
100: }
101:
102: 103: 104: 105:
106: public function isPut()
107: {
108: return $this->getMethod() === self::METHOD_PUT;
109: }
110:
111: 112: 113: 114:
115: public function isDelete()
116: {
117: return $this->getMethod() === self::METHOD_DELETE;
118: }
119:
120: 121: 122: 123:
124: public function isHead()
125: {
126: return $this->getMethod() === self::METHOD_HEAD;
127: }
128:
129: 130: 131: 132:
133: public function isOptions()
134: {
135: return $this->getMethod() === self::METHOD_OPTIONS;
136: }
137:
138: 139: 140: 141:
142: public function isAjax()
143: {
144: if ($this->params('isajax')) {
145: return true;
146: } elseif (isset($this->env['X_REQUESTED_WITH']) && $this->env['X_REQUESTED_WITH'] === 'XMLHttpRequest') {
147: return true;
148: } else {
149: return false;
150: }
151: }
152:
153: 154: 155: 156:
157: public function isXhr()
158: {
159: return $this->isAjax();
160: }
161:
162: 163: 164: 165: 166: 167: 168: 169: 170:
171: public function params($key = null)
172: {
173: $union = array_merge($this->get(), $this->post());
174: if ($key) {
175: if (isset($union[$key])) {
176: return $union[$key];
177: } else {
178: return null;
179: }
180: } else {
181: return $union;
182: }
183: }
184:
185: 186: 187: 188: 189: 190: 191: 192: 193:
194: public function get($key = null)
195: {
196: if (!isset($this->env['slim.request.query_hash'])) {
197: $output = array();
198: if (function_exists('mb_parse_str') && !isset($this->env['slim.tests.ignore_multibyte'])) {
199: mb_parse_str($this->env['QUERY_STRING'], $output);
200: } else {
201: parse_str($this->env['QUERY_STRING'], $output);
202: }
203: $this->env['slim.request.query_hash'] = Util::stripSlashesIfMagicQuotes($output);
204: }
205: if ($key) {
206: if (isset($this->env['slim.request.query_hash'][$key])) {
207: return $this->env['slim.request.query_hash'][$key];
208: } else {
209: return null;
210: }
211: } else {
212: return $this->env['slim.request.query_hash'];
213: }
214: }
215:
216: 217: 218: 219: 220: 221: 222: 223: 224: 225:
226: public function post($key = null)
227: {
228: if (!isset($this->env['slim.input'])) {
229: throw new \RuntimeException('Missing slim.input in environment variables');
230: }
231: if (!isset($this->env['slim.request.form_hash'])) {
232: $this->env['slim.request.form_hash'] = array();
233: if ($this->isFormData() && is_string($this->env['slim.input'])) {
234: $output = array();
235: if (function_exists('mb_parse_str') && !isset($this->env['slim.tests.ignore_multibyte'])) {
236: mb_parse_str($this->env['slim.input'], $output);
237: } else {
238: parse_str($this->env['slim.input'], $output);
239: }
240: $this->env['slim.request.form_hash'] = Util::stripSlashesIfMagicQuotes($output);
241: } else {
242: $this->env['slim.request.form_hash'] = Util::stripSlashesIfMagicQuotes($_POST);
243: }
244: }
245: if ($key) {
246: if (isset($this->env['slim.request.form_hash'][$key])) {
247: return $this->env['slim.request.form_hash'][$key];
248: } else {
249: return null;
250: }
251: } else {
252: return $this->env['slim.request.form_hash'];
253: }
254: }
255:
256: 257: 258: 259: 260:
261: public function put($key = null)
262: {
263: return $this->post($key);
264: }
265:
266: 267: 268: 269: 270:
271: public function delete($key = null)
272: {
273: return $this->post($key);
274: }
275:
276: 277: 278: 279: 280: 281: 282: 283: 284:
285: public function cookies($key = null)
286: {
287: if (!isset($this->env['slim.request.cookie_hash'])) {
288: $cookieHeader = isset($this->env['COOKIE']) ? $this->env['COOKIE'] : '';
289: $this->env['slim.request.cookie_hash'] = Util::parseCookieHeader($cookieHeader);
290: }
291: if ($key) {
292: if (isset($this->env['slim.request.cookie_hash'][$key])) {
293: return $this->env['slim.request.cookie_hash'][$key];
294: } else {
295: return null;
296: }
297: } else {
298: return $this->env['slim.request.cookie_hash'];
299: }
300: }
301:
302: 303: 304: 305:
306: public function isFormData()
307: {
308: $method = isset($this->env['slim.method_override.original_method']) ? $this->env['slim.method_override.original_method'] : $this->getMethod();
309:
310: return ($method === self::METHOD_POST && is_null($this->getContentType())) || in_array($this->getMediaType(), self::$formDataMediaTypes);
311: }
312:
313: 314: 315: 316: 317: 318: 319: 320: 321: 322:
323: public function ($key = null, $default = null)
324: {
325: if ($key) {
326: $key = strtoupper($key);
327: $key = str_replace('-', '_', $key);
328: $key = preg_replace('@^HTTP_@', '', $key);
329: if (isset($this->env[$key])) {
330: return $this->env[$key];
331: } else {
332: return $default;
333: }
334: } else {
335: $headers = array();
336: foreach ($this->env as $key => $value) {
337: if (strpos($key, 'slim.') !== 0) {
338: $headers[$key] = $value;
339: }
340: }
341:
342: return $headers;
343: }
344: }
345:
346: 347: 348: 349:
350: public function getBody()
351: {
352: return $this->env['slim.input'];
353: }
354:
355: 356: 357: 358:
359: public function getContentType()
360: {
361: if (isset($this->env['CONTENT_TYPE'])) {
362: return $this->env['CONTENT_TYPE'];
363: } else {
364: return null;
365: }
366: }
367:
368: 369: 370: 371:
372: public function getMediaType()
373: {
374: $contentType = $this->getContentType();
375: if ($contentType) {
376: $contentTypeParts = preg_split('/\s*[;,]\s*/', $contentType);
377:
378: return strtolower($contentTypeParts[0]);
379: } else {
380: return null;
381: }
382: }
383:
384: 385: 386: 387:
388: public function getMediaTypeParams()
389: {
390: $contentType = $this->getContentType();
391: $contentTypeParams = array();
392: if ($contentType) {
393: $contentTypeParts = preg_split('/\s*[;,]\s*/', $contentType);
394: $contentTypePartsLength = count($contentTypeParts);
395: for ($i = 1; $i < $contentTypePartsLength; $i++) {
396: $paramParts = explode('=', $contentTypeParts[$i]);
397: $contentTypeParams[strtolower($paramParts[0])] = $paramParts[1];
398: }
399: }
400:
401: return $contentTypeParams;
402: }
403:
404: 405: 406: 407:
408: public function getContentCharset()
409: {
410: $mediaTypeParams = $this->getMediaTypeParams();
411: if (isset($mediaTypeParams['charset'])) {
412: return $mediaTypeParams['charset'];
413: } else {
414: return null;
415: }
416: }
417:
418: 419: 420: 421:
422: public function getContentLength()
423: {
424: if (isset($this->env['CONTENT_LENGTH'])) {
425: return (int) $this->env['CONTENT_LENGTH'];
426: } else {
427: return 0;
428: }
429: }
430:
431: 432: 433: 434:
435: public function getHost()
436: {
437: if (isset($this->env['HOST'])) {
438: if (strpos($this->env['HOST'], ':') !== false) {
439: $hostParts = explode(':', $this->env['HOST']);
440:
441: return $hostParts[0];
442: }
443:
444: return $this->env['HOST'];
445: } else {
446: return $this->env['SERVER_NAME'];
447: }
448: }
449:
450: 451: 452: 453:
454: public function getHostWithPort()
455: {
456: return sprintf('%s:%s', $this->getHost(), $this->getPort());
457: }
458:
459: 460: 461: 462:
463: public function getPort()
464: {
465: return (int) $this->env['SERVER_PORT'];
466: }
467:
468: 469: 470: 471:
472: public function getScheme()
473: {
474: return $this->env['slim.url_scheme'];
475: }
476:
477: 478: 479: 480:
481: public function getScriptName()
482: {
483: return $this->env['SCRIPT_NAME'];
484: }
485:
486: 487: 488: 489:
490: public function getRootUri()
491: {
492: return $this->getScriptName();
493: }
494:
495: 496: 497: 498:
499: public function getPath()
500: {
501: return $this->getScriptName() . $this->getPathInfo();
502: }
503:
504: 505: 506: 507:
508: public function getPathInfo()
509: {
510: return $this->env['PATH_INFO'];
511: }
512:
513: 514: 515: 516:
517: public function getResourceUri()
518: {
519: return $this->getPathInfo();
520: }
521:
522: 523: 524: 525:
526: public function getUrl()
527: {
528: $url = $this->getScheme() . '://' . $this->getHost();
529: if (($this->getScheme() === 'https' && $this->getPort() !== 443) || ($this->getScheme() === 'http' && $this->getPort() !== 80)) {
530: $url .= sprintf(':%s', $this->getPort());
531: }
532:
533: return $url;
534: }
535:
536: 537: 538: 539:
540: public function getIp()
541: {
542: if (isset($this->env['X_FORWARDED_FOR'])) {
543: return $this->env['X_FORWARDED_FOR'];
544: } elseif (isset($this->env['CLIENT_IP'])) {
545: return $this->env['CLIENT_IP'];
546: }
547:
548: return $this->env['REMOTE_ADDR'];
549: }
550:
551: 552: 553: 554:
555: public function getReferrer()
556: {
557: if (isset($this->env['REFERER'])) {
558: return $this->env['REFERER'];
559: } else {
560: return null;
561: }
562: }
563:
564: 565: 566: 567:
568: public function getReferer()
569: {
570: return $this->getReferrer();
571: }
572:
573: 574: 575: 576:
577: public function getUserAgent()
578: {
579: if (isset($this->env['USER_AGENT'])) {
580: return $this->env['USER_AGENT'];
581: } else {
582: return null;
583: }
584: }
585: }
586: