Skip to content

Commit f54584c

Browse files
HZMaricohuangzhhui
authored andcommitted
Object argument of action bind with request parameters (swoft-cloud/swoft-component#101)
* [feature]more controller method param supported now ``` /** * Class DemoController * @Package App\Controllers * @controller(prefix="/demo") */ class DemoController { /** * @RequestMapping(route="/demo", method={RequestMethod::GET}) * @param Request $request * @param Response $response * @return array */ public function list(Request $request, Response $response) { return []; } } ``` feature ``` /** * Class DemoController * @Package App\Controllers * @controller(prefix="/demo") */ class DemoController { /** * @RequestMapping(route="/demo", method={RequestMethod::GET}) * @param EntityObject $model * @param OtherObject $object * @return array */ public function list(EntityObject $model, OtherObject $object) { return []; } } ```
1 parent e484ebe commit f54584c

File tree

1 file changed

+56
-16
lines changed

1 file changed

+56
-16
lines changed

src/Router/HandlerAdapter.php

Lines changed: 56 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,9 @@
77
use Swoft\Bean\Annotation\Bean;
88
use Swoft\Core\RequestContext;
99
use Swoft\Exception\InvalidArgumentException;
10+
use Swoft\Helper\JsonHelper;
1011
use Swoft\Helper\PhpHelper;
12+
use Swoft\Helper\StringHelper;
1113
use Swoft\Http\Message\Router\HandlerAdapterInterface;
1214
use Swoft\Http\Message\Server\Request;
1315
use Swoft\Http\Message\Server\Response;
@@ -17,15 +19,13 @@
1719
use Swoft\Http\Server\Payload;
1820

1921
/**
20-
* http handler adapter
21-
*
2222
* @Bean("httpHandlerAdapter")
23-
* @author stelin <[email protected]>
2423
*/
2524
class HandlerAdapter implements HandlerAdapterInterface
2625
{
2726
/**
28-
* execute handler with controller and action
27+
* Execute handler with controller and action
28+
*
2929
* @param ServerRequestInterface $request request object
3030
* @param array $routeInfo handler info
3131
* @return Response
@@ -89,11 +89,10 @@ public function doHandler(ServerRequestInterface $request, array $routeInfo)
8989
}
9090

9191
/**
92-
* create handler
92+
* Create handler
9393
*
9494
* @param string $path url path
9595
* @param array $info path info
96-
*
9796
* @return array
9897
* @throws \InvalidArgumentException
9998
*/
@@ -142,10 +141,7 @@ public function createHandler(string $path, array $info): array
142141
}
143142

144143
/**
145-
* default handler
146-
*
147144
* @param array $handler handler info
148-
*
149145
* @return array
150146
* @throws \Swoft\Exception\InvalidArgumentException
151147
*/
@@ -163,12 +159,11 @@ private function defaultHandler(array $handler): array
163159
}
164160

165161
/**
166-
* binding params of action method
162+
* Binding params of action method
167163
*
168164
* @param ServerRequestInterface $request request object
169165
* @param mixed $handler handler
170166
* @param array $matches route params info
171-
*
172167
* @return array
173168
* @throws \ReflectionException
174169
*/
@@ -184,10 +179,8 @@ private function bindParams(ServerRequestInterface $request, $handler, array $ma
184179
}
185180

186181
$bindParams = [];
187-
// $matches = $info['matches'] ?? [];
188-
$response = RequestContext::getResponse();
189182

190-
// binding params
183+
// Binding params
191184
foreach ($reflectParams as $key => $reflectParam) {
192185
$reflectType = $reflectParam->getType();
193186
$name = $reflectParam->getName();
@@ -203,16 +196,25 @@ private function bindParams(ServerRequestInterface $request, $handler, array $ma
203196
}
204197

205198
/**
206-
* defined type of the param
199+
* Defined type of the param
207200
* @notice \ReflectType::getName() is not supported in PHP 7.0, that is why use __toString()
208201
*/
209202
$type = $reflectType->__toString();
210203
if ($type === Request::class) {
204+
// Current Request Object
211205
$bindParams[$key] = $request;
212206
} elseif ($type === Response::class) {
213-
$bindParams[$key] = $response;
207+
// Current Response Object
208+
$bindParams[$key] = RequestContext::getResponse();
214209
} elseif (isset($matches[$name])) {
210+
// Request parameters
215211
$bindParams[$key] = $this->parserParamType($type, $matches[$name]);
212+
} elseif (App::hasBean($type)) {
213+
// Bean
214+
$bindParams[$key] = App::getBean($type);
215+
} elseif (\class_exists($type)) {
216+
// Class
217+
$bindParams[$key] = $this->bindRequestParamsToClass($request, new \ReflectionClass($type));
216218
} else {
217219
$bindParams[$key] = $this->getDefaultValue($type);
218220
}
@@ -221,6 +223,44 @@ private function bindParams(ServerRequestInterface $request, $handler, array $ma
221223
return $bindParams;
222224
}
223225

226+
/**
227+
* Bind request parameters to instance of ReflectClass
228+
*
229+
* @param ServerRequestInterface $request
230+
* @param \ReflectionClass $reflectClass
231+
* @return Object
232+
*/
233+
private function bindRequestParamsToClass(ServerRequestInterface $request, \ReflectionClass $reflectClass)
234+
{
235+
try {
236+
$object = $reflectClass->newInstance();
237+
$queryParams = $request->getQueryParams();
238+
// Get request body, auto decode when content type is json format
239+
if (StringHelper::startsWith($request->getHeaderLine('Content-Type'), 'application/json')) {
240+
$requestBody = JsonHelper::decode($request->getBody()->getContents(), true);
241+
} else {
242+
$requestBody = $request->getParsedBody();
243+
}
244+
// Merge query params and request body
245+
$requestParams = array_merge($queryParams, $requestBody);
246+
// Binding request params to target object
247+
$properties = $reflectClass->getProperties();
248+
foreach ($properties as $property) {
249+
$name = $property->getName();
250+
if (!isset($requestParams[$name])) {
251+
continue;
252+
}
253+
if (!$property->isPublic()) {
254+
$property->setAccessible(true);
255+
}
256+
$property->setValue($object, $requestParams[$name]);
257+
}
258+
} catch (\Exception $e) {
259+
$object = null;
260+
}
261+
return $object;
262+
}
263+
224264
/**
225265
* parser the type of binding param
226266
*

0 commit comments

Comments
 (0)