1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
namespace Zaphpa; |
4
|
|
|
|
5
|
|
|
/** |
6
|
|
|
* HTTP Request class |
7
|
|
|
*/ |
8
|
|
|
class Request { |
9
|
|
|
public $params; |
10
|
|
|
public $data; |
11
|
|
|
public $format; |
12
|
|
|
public $accepted_formats; |
13
|
|
|
public $encodings; |
14
|
|
|
public $charsets; |
15
|
|
|
public $languages; |
16
|
|
|
public $version; |
17
|
|
|
public $method; |
18
|
|
|
public $clientIP; |
19
|
|
|
public $userAgent; |
20
|
|
|
public $protocol; |
21
|
|
|
|
22
|
|
|
function __construct() { |
23
|
|
|
|
24
|
|
|
$this->method = Router::getRequestMethod(); |
25
|
|
|
$this->grabRequestMetadata(); |
26
|
|
|
|
27
|
|
|
// Caution: this piece of code assumes that both $_GET and $_POST are empty arrays when the request type is not GET or POST |
28
|
|
|
// This is true for current versions of PHP, but it is PHP so it's subject to change |
29
|
|
|
switch ($this->method) { |
30
|
|
|
case "GET": |
31
|
|
|
$this->data = $_GET; |
32
|
|
|
break; |
33
|
|
|
default: |
34
|
|
|
$contents = file_get_contents('php://input'); |
35
|
|
|
$parsed_contents = null; |
36
|
|
|
// @TODO: considering $_SERVER['HTTP_CONTENT_TYPE'] == 'application/x-www-form-urlencoded' could help here |
37
|
|
|
parse_str($contents, $parsed_contents); |
38
|
|
|
$this->data = $_GET + $_POST + $parsed_contents; // people do use query params with POST, PUT, and DELETE |
39
|
|
|
$this->data['_RAW_HTTP_DATA'] = $contents; |
40
|
|
|
} |
41
|
|
|
|
42
|
|
|
} |
43
|
|
|
|
44
|
|
|
protected function grabRequestMetadata() { |
45
|
|
|
$this->clientIP = !empty($_SERVER['HTTP_X_FORWARDED_FOR']) ? $_SERVER['HTTP_X_FORWARDED_FOR'] : ''; |
46
|
|
|
$this->clientIP = (empty($this->clientIP) && !empty($_SERVER['REMOTE_ADDR'])) ? $_SERVER['REMOTE_ADDR'] : ''; |
47
|
|
|
|
48
|
|
|
$this->userAgent = empty($_SERVER['HTTP_USER_AGENT']) ? '' : $_SERVER['HTTP_USER_AGENT']; |
49
|
|
|
$this->protocol = !empty($_SERVER['SERVER_PROTOCOL']) ? $_SERVER['SERVER_PROTOCOL'] : null; |
50
|
|
|
|
51
|
|
|
$this->parse_special('encodings', 'HTTP_ACCEPT_ENCODING', array('utf-8')); |
52
|
|
|
$this->parse_special('charsets', 'HTTP_ACCEPT_CHARSET', array('text/html')); |
53
|
|
|
$this->parse_special('accepted_formats', 'HTTP_ACCEPT'); |
54
|
|
|
$this->parse_special('languages', 'HTTP_ACCEPT_LANGUAGE', array('en-US')); |
55
|
|
|
} |
56
|
|
|
|
57
|
|
|
/** |
58
|
|
|
* Requested output format, if any. |
59
|
|
|
* Format in the URL request string takes priority over the one in HTTP headers, defaults to HTML. |
60
|
|
|
*/ |
61
|
|
|
protected function contentNego() { |
62
|
|
|
if (!empty($this->data['format'])) { |
63
|
|
|
$this->format = $this->data['format']; |
64
|
|
|
$aliases = $this->common_aliases(); |
65
|
|
|
if (array_key_exists($this->format, $aliases)) { |
66
|
|
|
$this->format = $aliases[$this->format]; |
67
|
|
|
} |
68
|
|
|
unset($this->data['format']); |
69
|
|
|
} elseif (!empty($this->accepted_formats[0])) { |
70
|
|
|
$this->format = $this->accepted_formats[0]; |
71
|
|
|
unset ($this->data['format']); |
72
|
|
|
} |
73
|
|
|
} |
74
|
|
|
|
75
|
|
|
/** |
76
|
|
|
* Covenience method that checks is data item is empty to avoid notice-level warnings |
77
|
|
|
* |
78
|
|
|
* @param $idx |
79
|
|
|
* name o the data variable (either request var or HTTP body var). |
80
|
|
|
*/ |
81
|
|
|
public function get_var($idx) { |
82
|
|
|
return (is_array($this->data) && isset($this->data[$idx])) ? $this->data[$idx] : null; |
83
|
|
|
} |
84
|
|
|
|
85
|
|
|
/** |
86
|
|
|
* Subclass this function if you need a different set! |
87
|
|
|
*/ |
88
|
|
|
public function common_aliases() { |
89
|
|
|
return array( |
90
|
|
|
'html' => 'text/html', |
91
|
|
|
'txt' => 'text/plain', |
92
|
|
|
'css' => 'text/css', |
93
|
|
|
'js' => 'application/x-javascript', |
94
|
|
|
'xml' => 'application/xml', |
95
|
|
|
'rss' => 'application/rss+xml', |
96
|
|
|
'atom' => 'application/atom+xml', |
97
|
|
|
'json' => 'application/json', |
98
|
|
|
'jsonp' => 'text/javascript', |
99
|
|
|
); |
100
|
|
|
} |
101
|
|
|
|
102
|
|
|
|
103
|
|
|
/** |
104
|
|
|
* Parses some packed $_SERVER variables (e.g. 'encoding', 'charsets' etc.) into more useful arrays. |
105
|
|
|
* |
106
|
|
|
* @param string $varname - alias under which the variable will be |
107
|
|
|
* attached to the current Request object |
108
|
|
|
* @param string $argname - the name of the argument in $_SERVER |
109
|
|
|
*/ |
110
|
|
|
private function parse_special($varname, $argname, $default=array()) { |
111
|
|
|
$this->$varname = $default; |
112
|
|
|
if (!empty($_SERVER[$argname])) { |
113
|
|
|
// parse before the first ";" character |
114
|
|
|
$truncated = substr($_SERVER[$argname], 0, strpos($_SERVER[$argname], ";", 0)); |
115
|
|
|
$truncated = !empty($truncated) ? $truncated : $_SERVER[$argname]; |
116
|
|
|
$this->$varname = explode(",", $truncated); |
117
|
|
|
} |
118
|
|
|
} |
119
|
|
|
|
120
|
|
|
} // end Request |