55 const VERSION =
'3.11.0';
104 public function add($callable)
119 if ($this->container->has($method)) {
120 $obj = $this->container->get($method);
121 if (is_callable($obj)) {
122 return call_user_func_array($obj, $args);
126 throw new \BadMethodCallException(
"Method $method is not a valid method");
141 public function get($pattern, $callable)
143 return $this->map([
'GET'], $pattern, $callable);
154 public function post($pattern, $callable)
156 return $this->map([
'POST'], $pattern, $callable);
167 public function put($pattern, $callable)
169 return $this->map([
'PUT'], $pattern, $callable);
180 public function patch($pattern, $callable)
182 return $this->map([
'PATCH'], $pattern, $callable);
193 public function delete($pattern, $callable)
195 return $this->map([
'DELETE'], $pattern, $callable);
208 return $this->map([
'OPTIONS'], $pattern, $callable);
219 public function any($pattern, $callable)
221 return $this->map([
'GET',
'POST',
'PUT',
'PATCH',
'DELETE',
'OPTIONS'], $pattern, $callable);
233 public function map(array $methods, $pattern, $callable)
235 if ($callable instanceof
Closure) {
236 $callable = $callable->bindTo($this->container);
239 $route = $this->container->get(
'router')->map($methods, $pattern, $callable);
240 if (is_callable([$route,
'setContainer'])) {
241 $route->setContainer($this->container);
244 if (is_callable([$route,
'setOutputBuffering'])) {
245 $route->setOutputBuffering($this->container->get(
'settings')[
'outputBuffering']);
263 return $response->withHeader(
'Location', (
string)$to)->withStatus($status);
281 public function group($pattern, $callable)
284 $group = $this->container->get(
'router')->pushGroup($pattern, $callable);
285 $group->setContainer($this->container);
287 $this->container->get(
'router')->popGroup();
308 public function run($silent =
false)
310 $response = $this->container->get(
'response');
322 $outputBuffering = $this->container->get(
'settings')[
'outputBuffering'];
323 if ($outputBuffering ===
'prepend') {
328 } elseif ($outputBuffering ===
'append') {
357 $router = $this->container->get(
'router');
358 if (is_callable([$request->
getUri(),
'getBasePath']) && is_callable([$router,
'setBasePath'])) {
359 $router->setBasePath($request->
getUri()->getBasePath());
362 $request = $this->dispatchRouterAndPrepareRoute($request, $router);
363 $routeInfo = $request->
getAttribute(
'routeInfo', [RouterInterface::DISPATCH_STATUS => Dispatcher::NOT_FOUND]);
365 if ($routeInfo[RouterInterface::DISPATCH_STATUS] === Dispatcher::METHOD_NOT_ALLOWED) {
366 return $this->handleException(
373 return $this->handleException(
new NotFoundException($request, $response), $request, $response);
393 $router = $this->container->get(
'router');
394 if (is_callable([$request->
getUri(),
'getBasePath']) && is_callable([$router,
'setBasePath'])) {
395 $router->setBasePath($request->
getUri()->getBasePath());
399 if ($this->container->get(
'settings')[
'determineRouteBeforeAppMiddleware'] ===
true) {
401 $request = $this->dispatchRouterAndPrepareRoute($request, $router);
406 $response = $this->callMiddlewareStack($request, $response);
408 $response = $this->handleException($e, $request, $response);
410 $response = $this->handlePhpError($e, $request, $response);
424 if (!headers_sent()) {
427 $first = stripos($name,
'Set-Cookie') === 0 ? false :
true;
429 header(sprintf(
'%s: %s', $name, $value), $first);
447 if (!$this->isEmptyResponse($response)) {
449 if ($body->isSeekable()) {
452 $settings = $this->container->get(
'settings');
453 $chunkSize = $settings[
'responseChunkSize'];
463 while ($amountToRead > 0 && !$body->eof()) {
464 $data = $body->read(min($chunkSize, $amountToRead));
467 $amountToRead -= strlen($data);
469 if (connection_status() != CONNECTION_NORMAL) {
474 while (!$body->eof()) {
475 echo $body->read($chunkSize);
476 if (connection_status() != CONNECTION_NORMAL) {
505 $router = $this->container->get(
'router');
508 if (null === $routeInfo || ($routeInfo[
'request'] !== [$request->
getMethod(), (string) $request->
getUri()])) {
509 $request = $this->dispatchRouterAndPrepareRoute($request, $router);
513 if ($routeInfo[0] === Dispatcher::FOUND) {
514 $route = $router->lookupRoute($routeInfo[1]);
515 return $route->run($request, $response);
516 } elseif ($routeInfo[0] === Dispatcher::METHOD_NOT_ALLOWED) {
517 if (!$this->container->has(
'notAllowedHandler')) {
521 $notAllowedHandler = $this->container->get(
'notAllowedHandler');
522 return $notAllowedHandler($request, $response, $routeInfo[1]);
525 if (!$this->container->has(
'notFoundHandler')) {
529 $notFoundHandler = $this->container->get(
'notFoundHandler');
530 return $notFoundHandler($request, $response);
560 $env = $this->container->get(
'environment');
561 $uri = Uri::createFromEnvironment(
$env)->withPath(
$path)->withQuery(
$query);
562 $headers =
new Headers($headers);
563 $serverParams =
$env->all();
564 $body =
new Body(
fopen(
'php://temp',
'r+'));
565 $body->write($bodyContent);
567 $request =
new Request($method, $uri, $headers, $cookies, $serverParams, $body);
570 $response = $this->container->get(
'response');
573 return $this($request, $response);
585 $routeInfo = $router->
dispatch($request);
587 if ($routeInfo[0] === Dispatcher::FOUND) {
588 $routeArguments = [];
589 foreach ($routeInfo[2] as $k => $v) {
590 $routeArguments[$k] = urldecode($v);
594 $route->prepare($request, $routeArguments);
600 $routeInfo[
'request'] = [$request->
getMethod(), (string) $request->
getUri()];
614 ini_set(
'default_mimetype',
'');
616 if ($this->isEmptyResponse($response)) {
617 return $response->
withoutHeader(
'Content-Type')->withoutHeader(
'Content-Length');
621 if (isset($this->container->get(
'settings')[
'addContentLengthHeader']) &&
622 $this->container->get(
'settings')[
'addContentLengthHeader'] ==
true) {
623 if (ob_get_length() > 0) {
624 throw new \RuntimeException(
"Unexpected data in output buffer. " .
625 "Maybe you have characters before an opening <?php tag?");
647 if (method_exists($response,
'isEmpty')) {
648 return $response->isEmpty();
651 return in_array($response->
getStatusCode(), [204, 205, 304]);
669 $params = [$e->getRequest(), $e->getResponse(), $e->getAllowedMethods()];
672 $params = [$e->getRequest(), $e->getResponse(), $e];
675 return $e->getResponse();
682 if ($this->container->has(
$handler)) {
683 $callable = $this->container->get(
$handler);
685 return call_user_func_array($callable,
$params);
707 if ($this->container->has(
$handler)) {
708 $callable = $this->container->get(
$handler);
710 return call_user_func_array($callable,
$params);
getMethod()
Retrieves the HTTP method of the request.
map(array $methods, $pattern, $callable)
Add route with multiple methods.
getProtocolVersion()
Retrieves the HTTP protocol version as a string.
patch($pattern, $callable)
Add PATCH route.
any($pattern, $callable)
Add route for any HTTP method.
Representation of an incoming, server-side HTTP request.
process(ServerRequestInterface $request, ResponseInterface $response)
Process a request.
withoutHeader($name)
Return an instance without the specified header.
trait MiddlewareAwareTrait
Middleware.
put($pattern, $callable)
Add PUT route.
getReasonPhrase()
Gets the response reason phrase associated with the status code.
foreach($paths as $path) $request
handleException(Exception $e, ServerRequestInterface $request, ResponseInterface $response)
Call relevant handler from the Container if needed.
run($silent=false)
Run application.
post($pattern, $callable)
Add POST route.
withHeader($name, $value)
Return an instance with the provided value replacing the specified header.
getStatusCode()
Gets the response status code.
dispatchRouterAndPrepareRoute(ServerRequestInterface $request, RouterInterface $router)
Dispatch the router to find the route.
Describes the interface of a container that exposes methods to read its entries.
__call($method, $args)
Calling a non-existant method on App checks to see if there's an item in the container that is callab...
getUri()
Retrieves the URI instance.
if(preg_match('#\.( $contentLength[^/\.]+)$#D', $path, $type)) if($contentType===null)
options($pattern, $callable)
Add OPTIONS route.
addMiddleware(callable $callable)
Add middleware.
getContainer()
Enable access to the DI container by consumers of $app.
getBody()
Gets the body of the message.
add($callable)
Add middleware.
Representation of an outgoing, server-side response.
withAttribute($name, $value)
Return an instance with the specified derived request attribute.
__construct($container=[])
Create new application.
getAttribute($name, $default=null)
Retrieve a single derived request attribute.
isEmptyResponse(ResponseInterface $response)
Helper method, which returns true if the provided response must not output a body and false if the re...
finalize(ResponseInterface $response)
Finalize response.
respond(ResponseInterface $response)
Send the response to the client.
Slim Framework (https://slimframework.com)
subRequest( $method, $path, $query='', array $headers=[], array $cookies=[], $bodyContent='', ResponseInterface $response=null)
Perform a sub-request from within an application route.
hasHeader($name)
Checks if a header exists by the given case-insensitive name.
processInvalidMethod(ServerRequestInterface $request, ResponseInterface $response)
Pull route info for a request with a bad method to decide whether to return a not-found error (defaul...
redirect($from, $to, $status=302)
Add a route that sends an HTTP redirect.
handlePhpError(Throwable $e, ServerRequestInterface $request, ResponseInterface $response)
Call relevant handler from the Container if needed.
getHeaders()
Retrieves all message header values.
getHeaderLine($name)
Retrieves a comma-separated string of the values for a single header.
dispatch(ServerRequestInterface $request)
Dispatch router for HTTP request.