1: <?php
2: /*
3: * Copyright (c) 2015 @trashtoy
4: * https://github.com/trashtoy/
5: *
6: * Permission is hereby granted, free of charge, to any person obtaining a copy of
7: * this software and associated documentation files (the "Software"), to deal in
8: * the Software without restriction, including without limitation the rights to use,
9: * copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
10: * Software, and to permit persons to whom the Software is furnished to do so,
11: * subject to the following conditions:
12: *
13: * The above copyright notice and this permission notice shall be included in all
14: * copies or substantial portions of the Software.
15: *
16: * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17: * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
18: * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
19: * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
20: * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
21: * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22: */
23: /**
24: * PHP class file.
25: * @auhtor trashtoy
26: * @since 2.2.0
27: */
28: namespace Peach\Http;
29:
30: use Peach\Http\Header\NoField;
31: use Peach\Util\ArrayMap;
32:
33: /**
34: * HTTP リクエストをあらわすクラスです.
35: */
36: class Request
37: {
38: /**
39: * クエリ部分を除いたパス文字列です.
40: * @var string
41: */
42: private $path;
43:
44: /**
45: * PHP の $_GET に相当するパラメータです.
46: * @var ArrayMap
47: */
48: private $queryParameters;
49:
50: /**
51: * PHP の $_POST に相当するパラメータです.
52: * @var ArrayMap
53: */
54: private $postParameters;
55:
56: /**
57: * HeaderField 型オブジェクトの配列です.
58: * @var ArrayMap
59: */
60: private $headerList;
61:
62: /**
63: * 空の Request インスタンスを構築します.
64: */
65: public function __construct()
66: {
67: $this->path = null;
68: $this->queryParameters = new ArrayMap();
69: $this->postParameters = new ArrayMap();
70: $this->headerList = new ArrayMap();
71: }
72:
73: /**
74: * この Request のパス (URL のうち, クエリ・フラグメントを除いた部分) を設定します.
75: *
76: * @param string $path セットするパス
77: */
78: public function setPath($path)
79: {
80: $this->path = $path;
81: }
82:
83: /**
84: * この Request のパス (URL のうち, クエリ・フラグメントを除いた部分) を返します.
85: *
86: * @return string この Request のパス
87: */
88: public function getPath()
89: {
90: return $this->path;
91: }
92:
93: /**
94: * 指定された名前のヘッダーを取得します.
95: * 存在しない場合は NoField オブジェクトを返します.
96: *
97: * @param string $name ヘッダー名
98: * @return HeaderField 指定されたヘッダーに該当する HeaderField オブジェクト
99: */
100: public function getHeader($name)
101: {
102: $lName = strtolower($name);
103: if ($lName === "host") {
104: return $this->getHeader(":authority");
105: }
106:
107: $header = $this->headerList->get($lName);
108: return ($header instanceof HeaderField) ? $header : NoField::getInstance();
109: }
110:
111: /**
112: * この Request が持つヘッダーの一覧を取得します.
113: *
114: * @return HeaderField[] この Request に定義されている HeaderField のリスト
115: * @todo 実装する
116: */
117: public function getHeaderList()
118: {
119: return $this->headerList->asArray();
120: }
121:
122: /**
123: * 指定されたヘッダーをこの Request に設定します.
124: *
125: * @param HeaderField $item
126: */
127: public function setHeader(HeaderField $item)
128: {
129: $name = strtolower($item->getName());
130: $key = ($name === "host") ? ":authority" : $name;
131: $this->headerList->put($key, $item);
132: }
133:
134: /**
135: * 指定された名前の HeaderField が存在するかどうか調べます.
136: * @param string $name ヘッダー名
137: * @return bool 指定された名前の HeaderField が存在する場合のみ true
138: */
139: public function hasHeader($name)
140: {
141: return $this->headerList->containsKey(strtolower($name));
142: }
143:
144: /**
145: * 指定された値を GET パラメータとしてセットします.
146: * 引数には配列または ArrayMap オブジェクトを指定することができます.
147: * 配列または ArrayMap のキーをパラメータ名, 値をそのパラメータの値とします.
148: *
149: * @param array|ArrayMap $params
150: */
151: public function setQuery($params)
152: {
153: if (is_array($params)) {
154: $this->setQuery(new ArrayMap($params));
155: return;
156: }
157: $this->queryParameters->putAll($params);
158: }
159:
160: /**
161: * 指定された名前の GET パラメータを返します.
162: * 第 2 引数に, そのパラメータが存在しなかった場合に返される代替値を指定することができます.
163: * 第 2 引数を指定しない場合は null を返します.
164: *
165: * @param string $name パラメータ名
166: * @param string|array $defaultValue そのパラメータが存在しない場合の代替値. 未指定の場合は null
167: * @return string|array パラメータの値
168: */
169: public function getQuery($name, $defaultValue = null)
170: {
171: return $this->queryParameters->get($name, $defaultValue);
172: }
173:
174: /**
175: * 指定された値を POST パラメータとしてセットします.
176: * 引数には配列または ArrayMap オブジェクトを指定することができます.
177: * 配列または ArrayMap のキーをパラメータ名, 値をそのパラメータの値とします.
178: *
179: * @param array|ArrayMap $params
180: */
181: public function setPost($params)
182: {
183: if (is_array($params)) {
184: $this->setPost(new ArrayMap($params));
185: return;
186: }
187: $this->postParameters->putAll($params);
188: }
189:
190: /**
191: * 指定された名前の POST パラメータを返します.
192: * 第 2 引数に, そのパラメータが存在しなかった場合に返される代替値を指定することができます.
193: * 第 2 引数を指定しない場合は null を返します.
194: *
195: * @param string $name パラメータ名
196: * @param string|array $defaultValue そのパラメータが存在しない場合の代替値. 未指定の場合は null
197: * @return string|array パラメータの値
198: */
199: public function getPost($name, $defaultValue = null)
200: {
201: return $this->postParameters->get($name, $defaultValue);
202: }
203:
204: /**
205: * この Request が malformed (不正な形式) かどうかを判断します.
206: * 以下に挙げるヘッダーのうち, 1 つでも欠けているものがあった場合に malformed と判定します.
207: *
208: * - :method
209: * - :scheme
210: * - :path
211: * - :authority (または Host)
212: *
213: * @return bool この Request が malformed と判定された場合のみ true
214: */
215: public function isMalformed()
216: {
217: $headerNames = array(":method", ":scheme", ":path", ":authority");
218: foreach ($headerNames as $h) {
219: if (!$this->hasHeader($h)) {
220: return true;
221: }
222: }
223: return false;
224: }
225: }
226: