1 | <?php |
||
10 | class ServerRequestFactory |
||
11 | { |
||
12 | use HelperTrait; |
||
13 | |||
14 | /** @var \Wandu\Http\Factory\UploadedFileFactory */ |
||
15 | protected $fileFactory; |
||
16 | |||
17 | /** |
||
18 | * @param \Wandu\Http\Factory\UploadedFileFactory $fileFactory |
||
19 | */ |
||
20 | 17 | public function __construct(UploadedFileFactory $fileFactory) |
|
24 | |||
25 | /** |
||
26 | * @return \Psr\Http\Message\ServerRequestInterface |
||
27 | */ |
||
28 | 1 | public function createFromGlobals() |
|
29 | { |
||
30 | 1 | return $this->create($_SERVER, $_GET, $_POST, $_COOKIE, $_FILES, new PhpInputStream()); |
|
31 | } |
||
32 | |||
33 | /** |
||
34 | * @param string $body |
||
35 | * @return \Psr\Http\Message\ServerRequestInterface |
||
36 | */ |
||
37 | 1 | public function createFromSocketBody($body) |
|
46 | |||
47 | /** |
||
48 | * @param array $server |
||
49 | * @param array $get |
||
50 | * @param array $post |
||
51 | * @param array $cookies |
||
52 | * @param array $files |
||
53 | * @param \Psr\Http\Message\StreamInterface $stream |
||
54 | * @return \Psr\Http\Message\ServerRequestInterface |
||
55 | */ |
||
56 | 17 | public function create( |
|
57 | array $server, |
||
58 | array $get, |
||
59 | array $post, |
||
60 | array $cookies, |
||
61 | array $files, |
||
62 | StreamInterface $stream = null |
||
63 | ) { |
||
64 | 17 | if (!isset($stream)) { |
|
65 | 5 | $stream = new Stream('php://memory'); |
|
66 | } |
||
67 | 17 | $headers = $this->getPsrHeadersFromServerParams($server); |
|
68 | |||
69 | // exists body, but not exists posts |
||
70 | 17 | $bodyContent = $stream->__toString(); |
|
71 | 17 | if ($bodyContent !== '' && count($post) === 0) { |
|
72 | 10 | if (isset($headers['content-type'])) { |
|
73 | // do not define multipart/form-data |
||
74 | // because, it use only in POST method. |
||
75 | // ref. en: https://issues.apache.org/jira/browse/FILEUPLOAD-197#comment-13595136 |
||
76 | // ref. kr: https://blog.outsider.ne.kr/1001 |
||
77 | 10 | if (strpos($headers['content-type'], 'application/json') === 0) { |
|
78 | 6 | $jsonBody = json_decode($bodyContent, true); |
|
79 | 6 | $post = $jsonBody ? $jsonBody : $post; |
|
80 | 4 | } elseif (strpos($headers['content-type'], 'application/x-www-form-urlencoded') === 0) { |
|
81 | 4 | parse_str($bodyContent, $post); |
|
82 | } |
||
83 | } |
||
84 | } |
||
85 | 17 | return new ServerRequest( |
|
86 | 17 | $server, |
|
87 | 17 | $get, |
|
88 | 17 | $post, |
|
89 | 17 | $cookies, |
|
90 | 17 | $this->fileFactory->createFromFiles($files), |
|
91 | 17 | [], |
|
92 | 17 | isset($server['REQUEST_METHOD']) ? $server['REQUEST_METHOD'] : 'GET', |
|
93 | 17 | $this->getUri($server), |
|
94 | 17 | $stream, |
|
95 | 17 | $headers, |
|
96 | 17 | '1.1' |
|
97 | ); |
||
98 | } |
||
99 | |||
100 | /** |
||
101 | * Parse plain headers. |
||
102 | * |
||
103 | * @param array $plainHeaders |
||
104 | * @return array |
||
105 | */ |
||
106 | 1 | protected function getPhpServerValuesFromPlainHeader(array $plainHeaders) |
|
107 | { |
||
108 | 1 | $httpInformation = explode(' ', array_shift($plainHeaders)); |
|
109 | $servers = [ |
||
110 | 1 | 'REQUEST_METHOD' => $httpInformation[0], |
|
111 | 1 | 'REQUEST_URI' => $httpInformation[1], |
|
112 | 1 | 'SERVER_PROTOCOL' => $httpInformation[2], |
|
113 | ]; |
||
114 | 1 | foreach ($plainHeaders as $plainHeader) { |
|
115 | 1 | list($key, $value) = array_map('trim', explode(':', $plainHeader, 2)); |
|
116 | 1 | $servers['HTTP_' . strtoupper(str_replace('-', '_', $key))] = $value; |
|
117 | } |
||
118 | 1 | return $servers; |
|
119 | } |
||
120 | |||
121 | /** |
||
122 | * @param array $server |
||
123 | * @return \Wandu\Http\Psr\Uri |
||
124 | */ |
||
125 | 17 | protected function getUri(array $server) |
|
126 | { |
||
127 | 17 | $stringUri = $this->getHostAndPort($server); |
|
128 | 17 | if ($stringUri !== '') { |
|
129 | 5 | $stringUri = $this->getScheme($server) . '://' . $stringUri; |
|
130 | } |
||
131 | 17 | $stringUri .= $this->getRequestUri($server); |
|
132 | 17 | return new Uri($stringUri); |
|
133 | } |
||
134 | |||
135 | /** |
||
136 | * @param array $server |
||
137 | * @return string |
||
138 | */ |
||
139 | 5 | protected function getScheme(array $server) |
|
147 | |||
148 | /** |
||
149 | * @param array $server |
||
150 | * @return string |
||
151 | */ |
||
152 | 17 | protected function getHostAndPort(array $server) |
|
153 | { |
||
154 | 17 | if (isset($server['HTTP_HOST'])) { |
|
155 | 4 | return $server['HTTP_HOST']; |
|
156 | } |
||
157 | 13 | if (!isset($server['SERVER_NAME'])) { |
|
158 | 12 | return ''; |
|
159 | } |
||
160 | 1 | $host = $server['SERVER_NAME']; |
|
161 | 1 | if (isset($server['SERVER_PORT'])) { |
|
162 | 1 | $host .= ':' . $server['SERVER_PORT']; |
|
163 | } |
||
164 | 1 | return $host; |
|
165 | } |
||
166 | |||
167 | /** |
||
168 | * @param array $server |
||
169 | * @return string |
||
170 | */ |
||
171 | 17 | protected function getRequestUri(array $server) |
|
178 | } |
||
179 |
Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable: