1: <?php
2: 3: 4: 5: 6: 7:
8:
9: namespace Wei;
10:
11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26:
27: class Request extends Base implements \ArrayAccess, \Countable, \IteratorAggregate
28: {
29: 30: 31: 32: 33:
34: protected $data = array();
35:
36: 37: 38: 39: 40:
41: protected $gets = array();
42:
43: 44: 45: 46: 47:
48: protected $posts = array();
49:
50: 51: 52: 53: 54:
55: protected $cookies = array();
56:
57: 58: 59: 60: 61:
62: protected $servers = array();
63:
64: 65: 66: 67: 68:
69: protected $files = array();
70:
71: 72: 73: 74: 75:
76: protected $content;
77:
78: 79: 80: 81: 82:
83: protected $fromGlobal = true;
84:
85: 86: 87: 88: 89:
90: protected $overwriteMethod = true;
91:
92: 93: 94: 95: 96:
97: protected $overwriteAjax = true;
98:
99: 100: 101:
102: protected $baseUrl;
103:
104: 105: 106:
107: protected $pathInfo;
108:
109: 110: 111:
112: protected $requestUri;
113:
114: 115: 116: 117: 118:
119: protected $method;
120:
121: 122: 123: 124: 125:
126: public function __construct(array $options = array())
127: {
128: parent::__construct($options);
129:
130:
131: if ($this->fromGlobal) {
132: $this->gets = &$_GET;
133: $this->posts = &$_POST;
134: $this->cookies = &$_COOKIE;
135: $this->servers = &$_SERVER;
136: $this->files = &$_FILES;
137: $this->data = &$_REQUEST;
138: }
139:
140: if ($this->overwriteMethod && $method = $this->get('_method')) {
141: $this->setMethod($method);
142: }
143:
144: if ($this->overwriteAjax && $this->get('_ajax')) {
145: $this->setServer('HTTP_X_REQUESTED_WITH', 'XMLHttpRequest');
146: }
147: }
148:
149: 150: 151: 152: 153: 154: 155:
156: public function __invoke($name, $default = '')
157: {
158: return isset($this->data[$name]) ? (string)$this->data[$name] : $default;
159: }
160:
161: 162: 163: 164: 165: 166: 167:
168: public function get($name, $default = null)
169: {
170: return $this->__invoke($name, $default);
171: }
172:
173: 174: 175: 176: 177: 178: 179: 180:
181: public function getInt($name, $min = null, $max = null)
182: {
183: $value = (int) $this($name);
184:
185: if (!is_null($min) && $value < $min) {
186: return $min;
187: } elseif (!is_null($max) && $value > $max) {
188: return $max;
189: }
190:
191: return $value;
192: }
193:
194: 195: 196: 197: 198: 199: 200: 201:
202: public function getInArray($name, array $array)
203: {
204: $value = $this->get($name);
205: return in_array($value, $array) ? $value : $array[key($array)];
206: }
207:
208: 209: 210: 211: 212: 213: 214:
215: public function set($name, $value = null)
216: {
217: if (!is_array($name)) {
218: $this->data[$name] = $value;
219: } else {
220: foreach ($name as $key => $value) {
221: $this->data[$key] = $value;
222: }
223: }
224: return $this;
225: }
226:
227: 228: 229: 230: 231: 232:
233: public function remove($name)
234: {
235: unset($this->data[$name]);
236: return $this;
237: }
238:
239: 240: 241: 242: 243:
244: public function clear()
245: {
246: $this->data = array();
247: return $this;
248: }
249:
250: 251: 252: 253: 254: 255:
256: public function offsetExists($offset)
257: {
258: return isset($this->data[$offset]);
259: }
260:
261: 262: 263: 264: 265: 266:
267: public function offsetGet($offset)
268: {
269: return isset($this->data[$offset]) ? $this->data[$offset] : null;
270: }
271:
272: 273: 274: 275: 276: 277: 278:
279: public function offsetSet($offset, $value)
280: {
281: return $this->data[$offset] = $value;
282: }
283:
284: 285: 286: 287: 288:
289: public function offsetUnset($offset)
290: {
291: unset($this->data[$offset]);
292: }
293:
294: 295: 296: 297: 298: 299:
300: public function fromArray(array $array = array())
301: {
302: $this->data = $array;
303: return $this;
304: }
305:
306: 307: 308: 309: 310:
311: public function toArray()
312: {
313: return $this->data;
314: }
315:
316: 317: 318: 319: 320:
321: public function count()
322: {
323: return count($this->data);
324: }
325:
326: 327: 328: 329: 330:
331: public function getScheme()
332: {
333: if ('on' === strtolower($this->getServer('HTTPS')) || 1 == $this->getServer('HTTPS')) {
334: return 'https';
335: } else {
336: return 'http';
337: }
338: }
339:
340: 341: 342: 343: 344:
345: public function getHost()
346: {
347: return $this->getServer('HTTP_HOST')
348: ?: $this->getServer('SERVER_NAME')
349: ?: $this->getServer('REMOTE_ADDR');
350: }
351:
352: 353: 354: 355: 356: 357:
358: public function setRequestUri($requestUri)
359: {
360: $this->requestUri = $requestUri;
361: return $this;
362: }
363:
364: 365: 366: 367: 368:
369: public function getRequestUri()
370: {
371: if ($this->requestUri === null) {
372: $this->requestUri = $this->detectRequestUri();
373: }
374: return $this->requestUri;
375: }
376:
377: 378: 379: 380: 381: 382:
383: public function setBaseUrl($baseUrl)
384: {
385: $this->baseUrl = rtrim($baseUrl, '/');
386: return $this;
387: }
388:
389: 390: 391: 392: 393:
394: public function getBaseUrl()
395: {
396: if ($this->baseUrl === null) {
397: $this->setBaseUrl($this->detectBaseUrl());
398: }
399: return $this->baseUrl;
400: }
401:
402: 403: 404: 405: 406: 407:
408: public function setPathInfo($pathInfo)
409: {
410: $this->pathInfo = $pathInfo;
411: return $this;
412: }
413:
414: 415: 416: 417: 418:
419: public function getPathInfo()
420: {
421: if ($this->pathInfo === null) {
422: $this->pathInfo = $this->detectPathInfo();
423: }
424: return $this->pathInfo;
425: }
426:
427: 428: 429: 430: 431: 432: 433:
434: public function getUrl()
435: {
436: return $this->getSchemeAndHost() . $this->getRequestUri();
437: }
438:
439: 440: 441: 442: 443:
444: public function getSchemeAndHost()
445: {
446: $port = $this->getServer('SERVER_PORT');
447: if ($port == 80 || $port == 433 || empty($port)) {
448: $port = '';
449: } else {
450: $port = ':' . $port;
451: }
452: return $this->getScheme() . '://' . $this->getHost() . $port;
453: }
454:
455: 456: 457: 458: 459: 460:
461: public function getUrlFor($path)
462: {
463: return $this->getSchemeAndHost() . $path;
464: }
465:
466: 467: 468: 469: 470: 471: 472: 473: 474: 475:
476: public function getIp($default = '0.0.0.0')
477: {
478: $ip = $this->getServer('HTTP_X_FORWARDED_FOR')
479: ? current(explode(',', $this->getServer('HTTP_X_FORWARDED_FOR'))) : $this->getServer('HTTP_CLIENT_IP')
480: ?: $this->getServer('REMOTE_ADDR');
481:
482: return filter_var($ip, FILTER_VALIDATE_IP) ? $ip : $default;
483: }
484:
485: 486: 487: 488: 489:
490: public function getMethod()
491: {
492: if (null === $this->method) {
493: $this->method = $this->getServer('REQUEST_METHOD', 'GET');
494: }
495: return $this->method;
496: }
497:
498: 499: 500: 501: 502: 503:
504: public function setMethod($method)
505: {
506: $this->method = $method;
507: return $this;
508: }
509:
510: 511: 512: 513: 514: 515:
516: public function isMethod($method)
517: {
518: return !strcasecmp($method, $this->getMethod());
519: }
520:
521: 522: 523: 524: 525:
526: public function isGet()
527: {
528: return $this->isMethod('GET');
529: }
530:
531: 532: 533: 534: 535:
536: public function isPost()
537: {
538: return $this->isMethod('POST');
539: }
540:
541: 542: 543: 544: 545:
546: public function isAjax()
547: {
548: return 'xmlhttprequest' == strtolower($this->getServer('HTTP_X_REQUESTED_WITH'));
549: }
550:
551: 552: 553: 554: 555: 556: 557:
558: public function &getParameterReference($type)
559: {
560: if (in_array($type, array('get', 'post', 'cookie', 'server', 'file'))) {
561: return $this->{$type . 's'};
562: }
563:
564: throw new \InvalidArgumentException(sprintf('Unknown parameter type "%s"', $type));
565: }
566:
567: 568: 569: 570: 571:
572: public function getContent()
573: {
574: if (null === $this->content && $this->fromGlobal) {
575: $this->content = file_get_contents('php://input');
576: }
577: return $this->content;
578: }
579:
580: 581: 582: 583: 584: 585:
586: public function setContent($content)
587: {
588: $this->content = $content;
589: return $this;
590: }
591:
592: 593: 594: 595: 596:
597: public function __toString()
598: {
599: $header = '';
600: foreach ($this->getHeaders() as $name => $value) {
601: $name = implode('-', array_map('ucfirst', explode('_', strtolower($name))));
602: $header .= $name . ': ' . $value . "\r\n";
603: }
604: return $this->getServer('REQUEST_METHOD') . ' ' . $this->getUrl() . ' ' . $this->getServer('SERVER_PROTOCOL') . "\r\n"
605: . $header
606: . $this->getContent();
607: }
608:
609: 610: 611: 612: 613: 614: 615:
616: public function getServer($name, $default = null)
617: {
618: return isset($this->servers[$name]) ? $this->servers[$name] : $default;
619: }
620:
621: 622: 623: 624: 625: 626: 627:
628: public function setServer($name, $value)
629: {
630: $this->servers[$name] = $value;
631: return $this;
632: }
633:
634: 635: 636: 637: 638: 639: 640:
641: public function getQuery($name, $default = null)
642: {
643: return isset($this->gets[$name]) ? $this->gets[$name] : $default;
644: }
645:
646: 647: 648: 649: 650: 651: 652:
653: public function setQuery($name, $value)
654: {
655: $this->gets[$name] = $value;
656: return $this;
657: }
658:
659: 660: 661: 662: 663:
664: public function &getQueries()
665: {
666: return $this->gets;
667: }
668:
669: 670: 671: 672: 673: 674: 675:
676: public function getPost($name, $default = null)
677: {
678: return isset($this->posts[$name]) ? $this->posts[$name] : $default;
679: }
680:
681: 682: 683: 684: 685: 686: 687:
688: public function setPost($name, $value)
689: {
690: $this->posts[$name] = $value;
691: return $this;
692: }
693:
694: 695: 696: 697: 698:
699: public function ()
700: {
701: $headers = array();
702: foreach ($this->servers as $name => $value) {
703: if (0 === strpos($name, 'HTTP_')) {
704: $headers[substr($name, 5)] = $value;
705: }
706: }
707: return $headers;
708: }
709:
710: 711: 712: 713: 714: 715:
716: public function isPage($page)
717: {
718: return ltrim($this->getPathInfo()) === $page;
719: }
720:
721: 722: 723: 724: 725: 726: 727: 728:
729: protected function detectRequestUri()
730: {
731: $requestUri = null;
732:
733:
734: $httpXRewriteUrl = $this->getServer('HTTP_X_REWRITE_URL');
735: if ($httpXRewriteUrl !== null) {
736: $requestUri = $httpXRewriteUrl;
737: }
738:
739:
740: $httpXOriginalUrl = $this->getServer('HTTP_X_ORIGINAL_URL');
741: if ($httpXOriginalUrl !== null) {
742: $requestUri = $httpXOriginalUrl;
743: }
744:
745:
746:
747: $iisUrlRewritten = $this->getServer('IIS_WasUrlRewritten');
748: $unencodedUrl = $this->getServer('UNENCODED_URL', '');
749: if ('1' == $iisUrlRewritten && '' !== $unencodedUrl) {
750: return $unencodedUrl;
751: }
752:
753:
754:
755: if (!$httpXRewriteUrl) {
756: $requestUri = $this->getServer('REQUEST_URI');
757: }
758:
759: if ($requestUri !== null) {
760: return preg_replace('#^[^/:]+://[^/]+#', '', $requestUri);
761: }
762:
763:
764: $origPathInfo = $this->getServer('ORIG_PATH_INFO');
765: if ($origPathInfo !== null) {
766: $queryString = $this->getServer('QUERY_STRING', '');
767: if ($queryString !== '') {
768: $origPathInfo .= '?' . $queryString;
769: }
770: return $origPathInfo;
771: }
772:
773: return '/';
774: }
775:
776: 777: 778: 779: 780: 781: 782: 783: 784: 785:
786: protected function detectBaseUrl()
787: {
788: $baseUrl = null;
789: $filename = $this->getServer('SCRIPT_FILENAME', '');
790: $scriptName = $this->getServer('SCRIPT_NAME');
791: $phpSelf = $this->getServer('PHP_SELF');
792: $origScriptName = $this->getServer('ORIG_SCRIPT_NAME');
793:
794: if ($scriptName !== null && basename($scriptName) === $filename) {
795: $baseUrl = $scriptName;
796: } elseif ($phpSelf !== null && basename($phpSelf) === $filename) {
797: $baseUrl = $phpSelf;
798: } elseif ($origScriptName !== null && basename($origScriptName) === $filename) {
799:
800: $baseUrl = $origScriptName;
801: } else {
802:
803:
804:
805: $baseUrl = '/';
806: $basename = basename($filename);
807: if ($basename) {
808: $path = ($phpSelf ? trim($phpSelf, '/') : '');
809: $baseUrl .= substr($path, 0, strpos($path, $basename)) . $basename;
810: }
811: }
812:
813:
814: $requestUri = $this->getRequestUri();
815:
816:
817: if (0 === strpos($requestUri, $baseUrl)) {
818: return $baseUrl;
819: }
820:
821:
822: $baseDir = str_replace('\\', '/', dirname($baseUrl));
823: if (0 === strpos($requestUri, $baseDir)) {
824: return $baseDir;
825: }
826:
827: $truncatedRequestUri = $requestUri;
828:
829: if (false !== ($pos = strpos($requestUri, '?'))) {
830: $truncatedRequestUri = substr($requestUri, 0, $pos);
831: }
832:
833: $basename = basename($baseUrl);
834:
835:
836: if (empty($basename) || false === strpos($truncatedRequestUri, $basename)) {
837: return '';
838: }
839:
840:
841:
842:
843: if (strlen($requestUri) >= strlen($baseUrl)
844: && (false !== ($pos = strpos($requestUri, $baseUrl)) && $pos !== 0)
845: ) {
846: $baseUrl = substr($requestUri, 0, $pos + strlen($baseUrl));
847: }
848:
849: return $baseUrl;
850: }
851:
852: 853: 854: 855: 856:
857: protected function detectPathInfo()
858: {
859: $uri = $this->getRequestUri();
860:
861: $pathInfo = '/' . trim(substr($uri, strlen($this->getBaseUrl())), '/');
862:
863: if (false !== $pos = strpos($pathInfo, '?')) {
864: $pathInfo = substr($pathInfo, 0, $pos);
865: }
866: return $pathInfo;
867: }
868:
869: 870: 871: 872: 873:
874: public function getIterator()
875: {
876: return new \ArrayIterator($this->data);
877: }
878: }
879: