Showing preview only (617K chars total). Download the full file or copy to clipboard to get everything.
Repository: slimphp/Slim
Branch: 4.x
Commit: 025043ec303c
Files: 145
Total size: 576.9 KB
Directory structure:
gitextract_5dpb6hp9/
├── .coveralls.yml
├── .editorconfig
├── .gitattributes
├── .github/
│ ├── FUNDING.yml
│ ├── dependabot.yml
│ └── workflows/
│ └── tests.yml
├── .gitignore
├── CHANGELOG.md
├── CODE_OF_CONDUCT.md
├── CONTRIBUTING.md
├── LICENSE.md
├── MAINTAINERS.md
├── README.md
├── SECURITY.md
├── Slim/
│ ├── App.php
│ ├── CallableResolver.php
│ ├── Error/
│ │ ├── AbstractErrorRenderer.php
│ │ └── Renderers/
│ │ ├── HtmlErrorRenderer.php
│ │ ├── JsonErrorRenderer.php
│ │ ├── PlainTextErrorRenderer.php
│ │ └── XmlErrorRenderer.php
│ ├── Exception/
│ │ ├── HttpBadRequestException.php
│ │ ├── HttpException.php
│ │ ├── HttpForbiddenException.php
│ │ ├── HttpGoneException.php
│ │ ├── HttpInternalServerErrorException.php
│ │ ├── HttpMethodNotAllowedException.php
│ │ ├── HttpNotFoundException.php
│ │ ├── HttpNotImplementedException.php
│ │ ├── HttpSpecializedException.php
│ │ ├── HttpTooManyRequestsException.php
│ │ └── HttpUnauthorizedException.php
│ ├── Factory/
│ │ ├── AppFactory.php
│ │ ├── Psr17/
│ │ │ ├── GuzzlePsr17Factory.php
│ │ │ ├── HttpSoftPsr17Factory.php
│ │ │ ├── LaminasDiactorosPsr17Factory.php
│ │ │ ├── NyholmPsr17Factory.php
│ │ │ ├── Psr17Factory.php
│ │ │ ├── Psr17FactoryProvider.php
│ │ │ ├── ServerRequestCreator.php
│ │ │ ├── SlimHttpPsr17Factory.php
│ │ │ ├── SlimHttpServerRequestCreator.php
│ │ │ └── SlimPsr17Factory.php
│ │ └── ServerRequestCreatorFactory.php
│ ├── Handlers/
│ │ ├── ErrorHandler.php
│ │ └── Strategies/
│ │ ├── RequestHandler.php
│ │ ├── RequestResponse.php
│ │ ├── RequestResponseArgs.php
│ │ └── RequestResponseNamedArgs.php
│ ├── Interfaces/
│ │ ├── AdvancedCallableResolverInterface.php
│ │ ├── CallableResolverInterface.php
│ │ ├── DispatcherInterface.php
│ │ ├── ErrorHandlerInterface.php
│ │ ├── ErrorRendererInterface.php
│ │ ├── InvocationStrategyInterface.php
│ │ ├── MiddlewareDispatcherInterface.php
│ │ ├── Psr17FactoryInterface.php
│ │ ├── Psr17FactoryProviderInterface.php
│ │ ├── RequestHandlerInvocationStrategyInterface.php
│ │ ├── RouteCollectorInterface.php
│ │ ├── RouteCollectorProxyInterface.php
│ │ ├── RouteGroupInterface.php
│ │ ├── RouteInterface.php
│ │ ├── RouteParserInterface.php
│ │ ├── RouteResolverInterface.php
│ │ └── ServerRequestCreatorInterface.php
│ ├── Logger.php
│ ├── Middleware/
│ │ ├── BodyParsingMiddleware.php
│ │ ├── ContentLengthMiddleware.php
│ │ ├── ErrorMiddleware.php
│ │ ├── MethodOverrideMiddleware.php
│ │ ├── OutputBufferingMiddleware.php
│ │ └── RoutingMiddleware.php
│ ├── MiddlewareDispatcher.php
│ ├── ResponseEmitter.php
│ └── Routing/
│ ├── Dispatcher.php
│ ├── FastRouteDispatcher.php
│ ├── Route.php
│ ├── RouteCollector.php
│ ├── RouteCollectorProxy.php
│ ├── RouteContext.php
│ ├── RouteGroup.php
│ ├── RouteParser.php
│ ├── RouteResolver.php
│ ├── RouteRunner.php
│ └── RoutingResults.php
├── UPGRADING.md
├── composer.json
├── phpcs.xml.dist
├── phpstan.neon.dist
├── phpunit.xml.dist
├── psalm.xml
└── tests/
├── AppTest.php
├── Assets/
│ └── HeaderStack.php
├── CallableResolverTest.php
├── Error/
│ └── AbstractErrorRendererTest.php
├── Exception/
│ ├── HttpExceptionTest.php
│ └── HttpUnauthorizedExceptionTest.php
├── Factory/
│ ├── AppFactoryTest.php
│ ├── Psr17/
│ │ ├── Psr17FactoryProviderTest.php
│ │ ├── Psr17FactoryTest.php
│ │ └── SlimHttpServerRequestCreatorTest.php
│ └── ServerRequestCreatorFactoryTest.php
├── Handlers/
│ ├── ErrorHandlerTest.php
│ └── Strategies/
│ └── RequestResponseNamedArgsTest.php
├── Middleware/
│ ├── BodyParsingMiddlewareTest.php
│ ├── ContentLengthMiddlewareTest.php
│ ├── ErrorMiddlewareTest.php
│ ├── MethodOverrideMiddlewareTest.php
│ ├── OutputBufferingMiddlewareTest.php
│ └── RoutingMiddlewareTest.php
├── MiddlewareDispatcherTest.php
├── Mocks/
│ ├── CallableTest.php
│ ├── InvocationStrategyTest.php
│ ├── InvokableTest.php
│ ├── MiddlewareTest.php
│ ├── MockAction.php
│ ├── MockCustomException.php
│ ├── MockCustomRequestHandlerInvocationStrategy.php
│ ├── MockMiddlewareSlimCallable.php
│ ├── MockMiddlewareWithConstructor.php
│ ├── MockMiddlewareWithoutConstructor.php
│ ├── MockMiddlewareWithoutInterface.php
│ ├── MockPsr17Factory.php
│ ├── MockPsr17FactoryWithoutStreamFactory.php
│ ├── MockRequestHandler.php
│ ├── MockSequenceMiddleware.php
│ ├── MockStream.php
│ ├── RequestHandlerTest.php
│ ├── SlowPokeStream.php
│ └── SmallChunksStream.php
├── Providers/
│ ├── PSR7ObjectProvider.php
│ └── PSR7ObjectProviderInterface.php
├── ResponseEmitterTest.php
├── Routing/
│ ├── DispatcherTest.php
│ ├── FastRouteDispatcherTest.php
│ ├── RouteCollectorProxyTest.php
│ ├── RouteCollectorTest.php
│ ├── RouteContextTest.php
│ ├── RouteParserTest.php
│ ├── RouteResolverTest.php
│ ├── RouteRunnerTest.php
│ └── RouteTest.php
├── TestCase.php
└── bootstrap.php
================================================
FILE CONTENTS
================================================
================================================
FILE: .coveralls.yml
================================================
json_path: coveralls-upload.json
================================================
FILE: .editorconfig
================================================
root = true
[*]
charset = utf-8
end_of_line = lf
insert_final_newline = true
indent_style = space
indent_size = 4
trim_trailing_whitespace = true
[*.md]
trim_trailing_whitespace = false
[*.{yml,yaml}]
indent_size = 2
================================================
FILE: .gitattributes
================================================
# Enforce Unix newlines
* text=auto eol=lf
# Exclude unused files
# see: https://redd.it/2jzp6k
/.coveralls.yml export-ignore
/.editorconfig export-ignore
/.gitattributes export-ignore
/.github export-ignore
/.gitignore export-ignore
/CODE_OF_CONDUCT.md export-ignore
/CONTRIBUTING.md export-ignore
/MAINTAINERS.md export-ignore
/README.md export-ignore
/UPGRADING.md export-ignore
/phpcs.xml.dist export-ignore
/phpstan.neon.dist export-ignore
/phpunit.xml.dist export-ignore
/psalm.xml export-ignore
/tests export-ignore
================================================
FILE: .github/FUNDING.yml
================================================
open_collective: slimphp
tidelift: "packagist/slim/slim"
================================================
FILE: .github/dependabot.yml
================================================
version: 2
updates:
- package-ecosystem: "github-actions"
directory: "/"
schedule:
interval: "monthly"
- package-ecosystem: composer
directory: "/"
schedule:
interval: monthly
open-pull-requests-limit: 10
versioning-strategy: increase
================================================
FILE: .github/workflows/tests.yml
================================================
name: Tests
permissions:
contents: read
on: [push, pull_request]
jobs:
tests:
name: Tests PHP ${{ matrix.php }}
runs-on: ubuntu-latest
continue-on-error: ${{ matrix.experimental }}
strategy:
fail-fast: false
matrix:
php: [7.4, 8.0, 8.1, 8.2, 8.3, 8.4]
experimental: [false]
composer-options: ['']
include:
- php: 8.2
analysis: true
- php: 8.5
experimental: true
composer-options: '--ignore-platform-req=php+'
- php: nightly
experimental: true
composer-options: '--ignore-platform-req=php+'
steps:
- name: Checkout
uses: actions/checkout@v6
- name: Set up PHP ${{ matrix.php }}
uses: shivammathur/setup-php@v2
with:
php-version: ${{ matrix.php }}
coverage: xdebug
tools: composer:2.8
- name: Install dependencies with Composer
run: composer update --prefer-dist --no-progress --no-interaction --ansi ${{ matrix.composer-options }}
- name: Coding standards
if: matrix.analysis
run: vendor/bin/phpcs
- name: Static analysis
if: matrix.analysis
run: vendor/bin/phpstan
- name: Tests
run: vendor/bin/phpunit ${{ matrix.analysis && '--coverage-clover clover.xml' || '--no-coverage' }}
- name: Upload coverage results to Coveralls
if: matrix.analysis
uses: coverallsapp/github-action@v2
with:
flag-name: php-${{ matrix.php }}
files: clover.xml
================================================
FILE: .gitignore
================================================
.DS_Store
.idea
.phpunit.result.cache
.phpunit.cache/
composer.lock
phpunit.xml
clover.xml
vendor
coverage
================================================
FILE: CHANGELOG.md
================================================
# Changelog
## [Unreleased]
### Fixed
### Added
### Changed
### Removed
## 4.15.1 - 2025-11-21
## Fixed
- Allow PHPUnit 10, 11 and 12 when testing Slim itself (#3411)
### Added
- Add support for PHP 8.5 (#3415)
**Full Changelog**: https://github.com/slimphp/Slim/compare/4.15.0...4.15.1
## 4.15.0 - 2025-08-24
### Fixed
- Fix DocBlocks for callable route handlers (#3389)
- Change class keyword to lowercase (#3346)
- Fix tests for PHP 8.3
- Fixes the build status badge in Readme (#3331)
- Fix text and eol attributes for * selector in .gitattributes (#3391)
- Deprecate setArgument/s (#3383)
### Added
- Add support for PHP 8.4
- Add phpstan v2
### Changed
- Update http urls in composer.json (#3399)
**Full Changelog**: https://github.com/slimphp/Slim/compare/4.14.0...4.15.0
## 4.14.0 - 2024-06-13
### Changed
- Do not HTML entity encode in PlainTextErrorRenderer by @akrabat in https://github.com/slimphp/Slim/pull/3319
- Only render tip to error log if plain text renderer is used by @akrabat in https://github.com/slimphp/Slim/pull/3321
- Add template generics for PSR-11 implementations in PHPStan and Psalm by @limarkxx in https://github.com/slimphp/Slim/pull/3322
- Update squizlabs/php_codesniffer requirement from ^3.9 to ^3.10 by @dependabot in https://github.com/slimphp/Slim/pull/3324
- Update phpstan/phpstan requirement from ^1.10 to ^1.11 by @dependabot in https://github.com/slimphp/Slim/pull/3325
- Update psr/http-factory requirement from ^1.0 to ^1.1 by @dependabot in https://github.com/slimphp/Slim/pull/3326
#### Type hinting with template generics
With the introduction of template generics, if you type-hint `Slim\App` instance variable using `/** @var \Slim\App $app */`, then you will need to change it to either:
* `/** @var \Slim\App<null> $app */` if you are not using a DI container, or
* `/** @var \Slim\App<\Psr\Container\ContainerInterface> $app */` if you are
You can also type-hint to the concrete instance of the container you are using too. For example, if you are using [PHP-DI](https://php-di.org), then you can use: `/** @var \Slim\App<DI\Container> $app */`.
### New Contributors
* @limarkxx made their first contribution in https://github.com/slimphp/Slim/pull/3322
**Full Changelog**: https://github.com/slimphp/Slim/compare/4.13.0...4.14.0
# 4.13.0 - 2024-03-03
- [3277: Create HttpTooManyRequestsException.php](https://github.com/slimphp/Slim/pull/3277) thanks to @flavioheleno
- [3278: Remove HttpGoneException executable flag](https://github.com/slimphp/Slim/pull/3278) thanks to @flavioheleno
- [3285: Update guzzlehttp/psr7 requirement from ^2.5 to ^2.6](https://github.com/slimphp/Slim/pull/3285) thanks to @dependabot[bot]
- [3290: Bump actions/checkout from 3 to 4](https://github.com/slimphp/Slim/pull/3290) thanks to @dependabot[bot]
- [3291: Fix line length](https://github.com/slimphp/Slim/pull/3291) thanks to @l0gicgate
- [3296: PSR 7 http-message version requirement](https://github.com/slimphp/Slim/issues/3296) thanks to @rotexdegba
- [3297: Allow Diactoros 3](https://github.com/slimphp/Slim/pull/3297) thanks to @derrabus
- [3299: Update tests and add PHP 8.3 to the CI matrix](https://github.com/slimphp/Slim/pull/3299) thanks to @akrabat
- [3301: Update nyholm/psr7-server requirement from ^1.0 to ^1.1](https://github.com/slimphp/Slim/pull/3301) thanks to @dependabot[bot]
- [3302: Add support for psr/http-message ^2.0](https://github.com/slimphp/Slim/pull/3302) thanks to @rotexdegba
- [3305: Update phpspec/prophecy-phpunit requirement from ^2.0 to ^2.1](https://github.com/slimphp/Slim/pull/3305) thanks to @dependabot[bot]
- [3306: Update phpspec/prophecy requirement from ^1.17 to ^1.18](https://github.com/slimphp/Slim/pull/3306) thanks to @dependabot[bot]
- [3308: Update squizlabs/php_codesniffer requirement from ^3.7 to ^3.8](https://github.com/slimphp/Slim/pull/3308) thanks to @dependabot[bot]
- [3313: Bump ramsey/composer-install from 2 to 3](https://github.com/slimphp/Slim/pull/3313) thanks to @dependabot[bot]
- [3314: Update phpspec/prophecy requirement from ^1.18 to ^1.19](https://github.com/slimphp/Slim/pull/3314) thanks to @dependabot[bot]
- [3315: Update squizlabs/php_codesniffer requirement from ^3.8 to ^3.9](https://github.com/slimphp/Slim/pull/3315) thanks to @dependabot[bot]
# 4.12.0 - 2023-07-23
- [3220: Refactor](https://github.com/slimphp/Slim/pull/3220) thanks to @amirkhodabande
- [3237: Update phpstan/phpstan requirement from ^1.8 to ^1.9](https://github.com/slimphp/Slim/pull/3237) thanks to @dependabot[bot]
- [3238: Update slim/http requirement from ^1.2 to ^1.3](https://github.com/slimphp/Slim/pull/3238) thanks to @dependabot[bot]
- [3239: Update slim/psr7 requirement from ^1.5 to ^1.6](https://github.com/slimphp/Slim/pull/3239) thanks to @dependabot[bot]
- [3240: Update phpspec/prophecy requirement from ^1.15 to ^1.16](https://github.com/slimphp/Slim/pull/3240) thanks to @dependabot[bot]
- [3241: Update adriansuter/php-autoload-override requirement from ^1.3 to ^1.4](https://github.com/slimphp/Slim/pull/3241) thanks to @dependabot[bot]
- [3245: New ability to override RouteGroupInterface in the Route class](https://github.com/slimphp/Slim/pull/3245) thanks to @githubjeka
- [3253: Fix HttpBadRequestException description](https://github.com/slimphp/Slim/pull/3253) thanks to @jsanahuja
- [3254: Update phpunit/phpunit requirement from ^9.5 to ^9.6](https://github.com/slimphp/Slim/pull/3254) thanks to @dependabot[bot]
- [3255: Update phpstan/phpstan requirement from ^1.9 to ^1.10](https://github.com/slimphp/Slim/pull/3255) thanks to @dependabot[bot]
- [3256: Update phpspec/prophecy requirement from ^1.16 to ^1.17](https://github.com/slimphp/Slim/pull/3256) thanks to @dependabot[bot]
- [3264: Update psr/http-message requirement from ^1.0 to ^1.1](https://github.com/slimphp/Slim/pull/3264) thanks to @dependabot[bot]
- [3265: Update nyholm/psr7 requirement from ^1.5 to ^1.7](https://github.com/slimphp/Slim/pull/3265) thanks to @dependabot[bot]
- [3266: Update guzzlehttp/psr7 requirement from ^2.4 to ^2.5](https://github.com/slimphp/Slim/pull/3266) thanks to @dependabot[bot]
- [3267: Update nyholm/psr7 requirement from ^1.7 to ^1.8](https://github.com/slimphp/Slim/pull/3267) thanks to @dependabot[bot]
- [3269: Update httpsoft/http-server-request requirement from ^1.0 to ^1.1](https://github.com/slimphp/Slim/pull/3269) thanks to @dependabot[bot]
- [3270: Update httpsoft/http-message requirement from ^1.0 to ^1.1](https://github.com/slimphp/Slim/pull/3270) thanks to @dependabot[bot]
- [3271: prevent multiple entries of same methode in FastRouteDispatcher](https://github.com/slimphp/Slim/pull/3271) thanks to @papparazzo
## 4.11.0 - 2022-11-06
- [3180: Declare types](https://github.com/slimphp/Slim/pull/3180) thanks to @nbayramberdiyev
- [3181: Update laminas/laminas-diactoros requirement from ^2.8 to ^2.9](https://github.com/slimphp/Slim/pull/3181) thanks to @dependabot[bot]
- [3182: Update guzzlehttp/psr7 requirement from ^2.1 to ^2.2](https://github.com/slimphp/Slim/pull/3182) thanks to @dependabot[bot]
- [3183: Update phpstan/phpstan requirement from ^1.4 to ^1.5](https://github.com/slimphp/Slim/pull/3183) thanks to @dependabot[bot]
- [3184: Update adriansuter/php-autoload-override requirement from ^1.2 to ^1.3](https://github.com/slimphp/Slim/pull/3184) thanks to @dependabot[bot]
- [3189: Update phpstan/phpstan requirement from ^1.5 to ^1.6](https://github.com/slimphp/Slim/pull/3189) thanks to @dependabot[bot]
- [3191: Adding property types to Middleware classes](https://github.com/slimphp/Slim/pull/3191) thanks to @ashleycoles
- [3193: Handlers types](https://github.com/slimphp/Slim/pull/3193) thanks to @ashleycoles
- [3194: Adding types to AbstractErrorRenderer](https://github.com/slimphp/Slim/pull/3194) thanks to @ashleycoles
- [3195: Adding prop types for Exception classes](https://github.com/slimphp/Slim/pull/3195) thanks to @ashleycoles
- [3196: Adding property type declarations for Factory classes](https://github.com/slimphp/Slim/pull/3196) thanks to @ashleycoles
- [3197: Remove redundant docblock types](https://github.com/slimphp/Slim/pull/3197) thanks to @theodorejb
- [3199: Update laminas/laminas-diactoros requirement from ^2.9 to ^2.11](https://github.com/slimphp/Slim/pull/3199) thanks to @dependabot[bot]
- [3200: Update phpstan/phpstan requirement from ^1.6 to ^1.7](https://github.com/slimphp/Slim/pull/3200) thanks to @dependabot[bot]
- [3205: Update guzzlehttp/psr7 requirement from ^2.2 to ^2.4](https://github.com/slimphp/Slim/pull/3205) thanks to @dependabot[bot]
- [3206: Update squizlabs/php_codesniffer requirement from ^3.6 to ^3.7](https://github.com/slimphp/Slim/pull/3206) thanks to @dependabot[bot]
- [3207: Update phpstan/phpstan requirement from ^1.7 to ^1.8](https://github.com/slimphp/Slim/pull/3207) thanks to @dependabot[bot]
- [3211: Assign null coalescing to coalesce equal](https://github.com/slimphp/Slim/pull/3211) thanks to @MathiasReker
- [3213: Void return](https://github.com/slimphp/Slim/pull/3213) thanks to @MathiasReker
- [3214: Is null](https://github.com/slimphp/Slim/pull/3214) thanks to @MathiasReker
- [3216: Refactor](https://github.com/slimphp/Slim/pull/3216) thanks to @mehdihasanpour
- [3218: Refactor some code](https://github.com/slimphp/Slim/pull/3218) thanks to @mehdihasanpour
- [3221: Cleanup](https://github.com/slimphp/Slim/pull/3221) thanks to @mehdihasanpour
- [3225: Update laminas/laminas-diactoros requirement from ^2.11 to ^2.14](https://github.com/slimphp/Slim/pull/3225) thanks to @dependabot[bot]
- [3228: Using assertSame to let assert equal be restricted](https://github.com/slimphp/Slim/pull/3228) thanks to @peter279k
- [3229: Update laminas/laminas-diactoros requirement from ^2.14 to ^2.17](https://github.com/slimphp/Slim/pull/3229) thanks to @dependabot[bot]
- [3235: Persist routes indexed by name in RouteCollector for improved performance.](https://github.com/slimphp/Slim/pull/3235) thanks to @BusterNeece
## 4.10.0 - 2022-03-14
- [3120: Add a new PSR-17 factory to Psr17FactoryProvider](https://github.com/slimphp/Slim/pull/3120) thanks to @solventt
- [3123: Replace deprecated setMethods() in tests](https://github.com/slimphp/Slim/pull/3123) thanks to @solventt
- [3126: Update guzzlehttp/psr7 requirement from ^2.0 to ^2.1](https://github.com/slimphp/Slim/pull/3126) thanks to @dependabot[bot]
- [3127: PHPStan v1.0](https://github.com/slimphp/Slim/pull/3127) thanks to @t0mmy742
- [3128: Update phpstan/phpstan requirement from ^1.0 to ^1.2](https://github.com/slimphp/Slim/pull/3128) thanks to @dependabot[bot]
- [3129: Deprecate PHP 7.3](https://github.com/slimphp/Slim/pull/3129) thanks to @l0gicgate
- [3130: Removed double defined PHP 7.4](https://github.com/slimphp/Slim/pull/3130) thanks to @flangofas
- [3132: Add new `RequestResponseNamedArgs` route strategy](https://github.com/slimphp/Slim/pull/3132) thanks to @adoy
- [3133: Improve typehinting for `RouteParserInterface`](https://github.com/slimphp/Slim/pull/3133) thanks to @jerowork
- [3135: Update phpstan/phpstan requirement from ^1.2 to ^1.3](https://github.com/slimphp/Slim/pull/3135) thanks to @dependabot[bot]
- [3137: Update phpspec/prophecy requirement from ^1.14 to ^1.15](https://github.com/slimphp/Slim/pull/3137) thanks to @dependabot[bot]
- [3138: Update license year](https://github.com/slimphp/Slim/pull/3138) thanks to @Awilum
- [3139: Fixed #1730 (reintroduced in 4.x)](https://github.com/slimphp/Slim/pull/3139) thanks to @adoy
- [3145: Update phpstan/phpstan requirement from ^1.3 to ^1.4](https://github.com/slimphp/Slim/pull/3145) thanks to @dependabot[bot]
- [3146: Inherit HttpException from RuntimeException](https://github.com/slimphp/Slim/pull/3146) thanks to @nbayramberdiyev
- [3148: Upgrade to HTML5](https://github.com/slimphp/Slim/pull/3148) thanks to @nbayramberdiyev
- [3172: Update nyholm/psr7 requirement from ^1.4 to ^1.5](https://github.com/slimphp/Slim/pull/3172) thanks to @dependabot[bot]
## 4.9.0 - 2021-10-05
- [3058: Implement exception class for Gone Http error](https://github.com/slimphp/Slim/pull/3058) thanks to @TheKernelPanic
- [3086: Update slim/psr7 requirement from ^1.3 to ^1.4](https://github.com/slimphp/Slim/pull/3086) thanks to @dependabot[bot]
- [3087: Update nyholm/psr7-server requirement from ^1.0.1 to ^1.0.2](https://github.com/slimphp/Slim/pull/3087) thanks to @dependabot[bot]
- [3093: Update phpstan/phpstan requirement from ^0.12.85 to ^0.12.90](https://github.com/slimphp/Slim/pull/3093) thanks to @dependabot[bot]
- [3099: Allow updated psr log](https://github.com/slimphp/Slim/pull/3099) thanks to @t0mmy742
- [3104: Drop php7.2](https://github.com/slimphp/Slim/pull/3104) thanks to @t0mmy742
- [3106: Use PSR-17 factory from Guzzle/psr7 2.0](https://github.com/slimphp/Slim/pull/3106) thanks to @t0mmy742
- [3108: Update README file](https://github.com/slimphp/Slim/pull/3108) thanks to @t0mmy742
- [3112: Update laminas/laminas-diactoros requirement from ^2.6 to ^2.8](https://github.com/slimphp/Slim/pull/3112) thanks to @dependabot[bot]
- [3114: Update slim/psr7 requirement from ^1.4 to ^1.5](https://github.com/slimphp/Slim/pull/3114) thanks to @dependabot[bot]
- [3115: Update phpstan/phpstan requirement from ^0.12.96 to ^0.12.99](https://github.com/slimphp/Slim/pull/3115) thanks to @dependabot[bot]
- [3116: Remove Zend Diactoros references](https://github.com/slimphp/Slim/pull/3116) thanks to @l0gicgate
## 4.8.0 - 2021-05-19
- [3034: Fix phpunit dependency version](https://github.com/slimphp/Slim/pull/3034) thanks to @l0gicgate
- [3037: Replace Travis by GitHub Actions](https://github.com/slimphp/Slim/pull/3037) thanks to @t0mmy742
- [3043: Cover App creation from AppFactory with empty Container](https://github.com/slimphp/Slim/pull/3043) thanks to @t0mmy742
- [3045: Update phpstan/phpstan requirement from ^0.12.58 to ^0.12.64](https://github.com/slimphp/Slim/pull/3045) thanks to @dependabot-preview[bot]
- [3047: documentation: min php 7.2 required](https://github.com/slimphp/Slim/pull/3047) thanks to @Rotzbua
- [3054: Update phpstan/phpstan requirement from ^0.12.64 to ^0.12.70](https://github.com/slimphp/Slim/pull/3054) thanks to @dependabot-preview[bot]
- [3056: Fix docblock in ErrorMiddleware](https://github.com/slimphp/Slim/pull/3056) thanks to @piotr-cz
- [3060: Update phpstan/phpstan requirement from ^0.12.70 to ^0.12.80](https://github.com/slimphp/Slim/pull/3060) thanks to @dependabot-preview[bot]
- [3061: Update nyholm/psr7 requirement from ^1.3 to ^1.4](https://github.com/slimphp/Slim/pull/3061) thanks to @dependabot-preview[bot]
- [3063: Allow ^1.0 || ^2.0 in psr/container](https://github.com/slimphp/Slim/pull/3063) thanks to @Ayesh
- [3069: Classname/Method Callable Arrays](https://github.com/slimphp/Slim/pull/3069) thanks to @ddrv
- [3078: Update squizlabs/php_codesniffer requirement from ^3.5 to ^3.6](https://github.com/slimphp/Slim/pull/3078) thanks to @dependabot[bot]
- [3079: Update phpspec/prophecy requirement from ^1.12 to ^1.13](https://github.com/slimphp/Slim/pull/3079) thanks to @dependabot[bot]
- [3080: Update guzzlehttp/psr7 requirement from ^1.7 to ^1.8](https://github.com/slimphp/Slim/pull/3080) thanks to @dependabot[bot]
- [3082: Update phpstan/phpstan requirement from ^0.12.80 to ^0.12.85](https://github.com/slimphp/Slim/pull/3082) thanks to @dependabot[bot]
## 4.7.0 - 2020-11-30
### Fixed
- [3027: Fix: FastRoute dispatcher and data generator should match](https://github.com/slimphp/Slim/pull/3027) thanks to @edudobay
### Added
- [3015: PHP 8 support](https://github.com/slimphp/Slim/pull/3015) thanks to @edudobay
### Optimizations
- [3024: Randomize tests](https://github.com/slimphp/Slim/pull/3024) thanks to @pawel-slowik
## 4.6.0 - 2020-11-15
### Fixed
- [2942: Fix PHPdoc for error handlers in ErrorMiddleware ](https://github.com/slimphp/Slim/pull/2942) thanks to @TiMESPLiNTER
- [2944: Remove unused function in ErrorHandler](https://github.com/slimphp/Slim/pull/2944) thanks to @l0gicgate
- [2960: Fix phpstan 0.12 errors](https://github.com/slimphp/Slim/pull/2960) thanks to @adriansuter
- [2982: Removing cloning statements in tests](https://github.com/slimphp/Slim/pull/2982) thanks to @l0gicgate
- [3017: Fix request creator factory test](https://github.com/slimphp/Slim/pull/3017) thanks to @pawel-slowik
- [3022: Ensure RouteParser Always Present After Routing](https://github.com/slimphp/Slim/pull/3022) thanks to @l0gicgate
### Added
- [2949: Add the support in composer.json](https://github.com/slimphp/Slim/pull/2949) thanks to @ddrv
- [2958: Strict empty string content type checking in BodyParsingMiddleware::getMediaType](https://github.com/slimphp/Slim/pull/2958) thanks to @Ayesh
- [2997: Add hints to methods](https://github.com/slimphp/Slim/pull/2997) thanks to @evgsavosin - [3000: Fix route controller test](https://github.com/slimphp/Slim/pull/3000) thanks to @pawel-slowik
- [3001: Add missing `$strategy` parameter in a Route test](https://github.com/slimphp/Slim/pull/3001) thanks to @pawel-slowik
### Optimizations
- [2951: Minor optimizations in if() blocks](https://github.com/slimphp/Slim/pull/2951) thanks to @Ayesh
- [2959: Micro optimization: Declare closures in BodyParsingMiddleware as static](https://github.com/slimphp/Slim/pull/2959) thanks to @Ayesh
- [2978: Split the routing results to its own function.](https://github.com/slimphp/Slim/pull/2978) thanks to @dlundgren
### Dependencies Updated
- [2953: Update nyholm/psr7-server requirement from ^0.4.1](https://github.com/slimphp/Slim/pull/2953) thanks to @dependabot-preview[bot]
- [2954: Update laminas/laminas-diactoros requirement from ^2.1 to ^2.3](https://github.com/slimphp/Slim/pull/2954) thanks to @dependabot-preview[bot]
- [2955: Update guzzlehttp/psr7 requirement from ^1.5 to ^1.6](https://github.com/slimphp/Slim/pull/2955) thanks to @dependabot-preview[bot]
- [2956: Update slim/psr7 requirement from ^1.0 to ^1.1](https://github.com/slimphp/Slim/pull/2956) thanks to @dependabot-preview[bot]
- [2957: Update nyholm/psr7 requirement from ^1.1 to ^1.2](https://github.com/slimphp/Slim/pull/2957) thanks to @dependabot-preview[bot]
- [2963: Update phpstan/phpstan requirement from ^0.12.23 to ^0.12.25](https://github.com/slimphp/Slim/pull/2963) thanks to @dependabot-preview[bot]
- [2965: Update adriansuter/php-autoload-override requirement from ^1.0 to ^1.1](https://github.com/slimphp/Slim/pull/2965) thanks to @dependabot-preview[bot]
- [2967: Update nyholm/psr7 requirement from ^1.2 to ^1.3](https://github.com/slimphp/Slim/pull/2967) thanks to @dependabot-preview[bot]
- [2969: Update nyholm/psr7-server requirement from ^0.4.1 to ^1.0.0](https://github.com/slimphp/Slim/pull/2969) thanks to @dependabot-preview[bot]
- [2970: Update phpstan/phpstan requirement from ^0.12.25 to ^0.12.26](https://github.com/slimphp/Slim/pull/2970) thanks to @dependabot-preview[bot]
- [2971: Update phpstan/phpstan requirement from ^0.12.26 to ^0.12.27](https://github.com/slimphp/Slim/pull/2971) thanks to @dependabot-preview[bot]
- [2972: Update phpstan/phpstan requirement from ^0.12.27 to ^0.12.28](https://github.com/slimphp/Slim/pull/2972) thanks to @dependabot-preview[bot]
- [2973: Update phpstan/phpstan requirement from ^0.12.28 to ^0.12.29](https://github.com/slimphp/Slim/pull/2973) thanks to @dependabot-preview[bot]
- [2975: Update phpstan/phpstan requirement from ^0.12.29 to ^0.12.30](https://github.com/slimphp/Slim/pull/2975) thanks to @dependabot-preview[bot]
- [2976: Update phpstan/phpstan requirement from ^0.12.30 to ^0.12.31](https://github.com/slimphp/Slim/pull/2976) thanks to @dependabot-preview[bot]
- [2980: Update phpstan/phpstan requirement from ^0.12.31 to ^0.12.32](https://github.com/slimphp/Slim/pull/2980) thanks to @dependabot-preview[bot]
- [2981: Update phpspec/prophecy requirement from ^1.10 to ^1.11](https://github.com/slimphp/Slim/pull/2981) thanks to @dependabot-preview[bot]
- [2986: Update phpstan/phpstan requirement from ^0.12.32 to ^0.12.33](https://github.com/slimphp/Slim/pull/2986) thanks to @dependabot-preview[bot]
- [2990: Update phpstan/phpstan requirement from ^0.12.33 to ^0.12.34](https://github.com/slimphp/Slim/pull/2990) thanks to @dependabot-preview[bot]
- [2991: Update phpstan/phpstan requirement from ^0.12.34 to ^0.12.35](https://github.com/slimphp/Slim/pull/2991) thanks to @dependabot-preview[bot]
- [2993: Update phpstan/phpstan requirement from ^0.12.35 to ^0.12.36](https://github.com/slimphp/Slim/pull/2993) thanks to @dependabot-preview[bot]
- [2995: Update phpstan/phpstan requirement from ^0.12.36 to ^0.12.37](https://github.com/slimphp/Slim/pull/2995) thanks to @dependabot-preview[bot]
- [3010: Update guzzlehttp/psr7 requirement from ^1.6 to ^1.7](https://github.com/slimphp/Slim/pull/3010) thanks to @dependabot-preview[bot]
- [3011: Update phpspec/prophecy requirement from ^1.11 to ^1.12](https://github.com/slimphp/Slim/pull/3011) thanks to @dependabot-preview[bot]
- [3012: Update slim/http requirement from ^1.0 to ^1.1](https://github.com/slimphp/Slim/pull/3012) thanks to @dependabot-preview[bot]
- [3013: Update slim/psr7 requirement from ^1.1 to ^1.2](https://github.com/slimphp/Slim/pull/3013) thanks to @dependabot-preview[bot]
- [3014: Update laminas/laminas-diactoros requirement from ^2.3 to ^2.4](https://github.com/slimphp/Slim/pull/3014) thanks to @dependabot-preview[bot]
- [3018: Update phpstan/phpstan requirement from ^0.12.37 to ^0.12.54](https://github.com/slimphp/Slim/pull/3018) thanks to @dependabot-preview[bot]
## 4.5.0 - 2020-04-14
### Added
- [2928](https://github.com/slimphp/Slim/pull/2928) Test against PHP 7.4
- [2937](https://github.com/slimphp/Slim/pull/2937) Add support for PSR-3
### Fixed
- [2916](https://github.com/slimphp/Slim/pull/2916) Rename phpcs.xml to phpcs.xml.dist
- [2917](https://github.com/slimphp/Slim/pull/2917) Update .editorconfig
- [2925](https://github.com/slimphp/Slim/pull/2925) ResponseEmitter: Don't remove Content-Type and Content-Length when body is empt
- [2932](https://github.com/slimphp/Slim/pull/2932) Update the Tidelift enterprise language
- [2938](https://github.com/slimphp/Slim/pull/2938) Modify usage of deprecated expectExceptionMessageRegExp() method
## 4.4.0 - 2020-01-04
### Added
- [2862](https://github.com/slimphp/Slim/pull/2862) Optionally handle subclasses of exceptions in custom error handler
- [2869](https://github.com/slimphp/Slim/pull/2869) php-di/php-di added in composer suggestion
- [2874](https://github.com/slimphp/Slim/pull/2874) Add `null` to param type-hints
- [2889](https://github.com/slimphp/Slim/pull/2889) Make `RouteContext` attributes customizable and change default to use private names
- [2907](https://github.com/slimphp/Slim/pull/2907) Migrate to PSR-12 convention
- [2910](https://github.com/slimphp/Slim/pull/2910) Migrate Zend to Laminas
- [2912](https://github.com/slimphp/Slim/pull/2912) Add Laminas PSR17 Factory
- [2913](https://github.com/slimphp/Slim/pull/2913) Update php-autoload-override version
- [2914](https://github.com/slimphp/Slim/pull/2914) Added ability to add handled exceptions as an array
### Fixed
- [2864](https://github.com/slimphp/Slim/pull/2864) Optimize error message in error handling if displayErrorDetails was not set
- [2876](https://github.com/slimphp/Slim/pull/2876) Update links from http to https
- [2877](https://github.com/slimphp/Slim/pull/2877) Fix docblock for `Slim\Routing\RouteCollector::cacheFile`
- [2878](https://github.com/slimphp/Slim/pull/2878) check body is writable only on ouput buffering append
- [2896](https://github.com/slimphp/Slim/pull/2896) Render errors uniformly
- [2902](https://github.com/slimphp/Slim/pull/2902) Fix prophecies
- [2908](https://github.com/slimphp/Slim/pull/2908) Use autoload-dev for `Slim\Tests` namespace
### Removed
- [2871](https://github.com/slimphp/Slim/pull/2871) Remove explicit type-hint
- [2872](https://github.com/slimphp/Slim/pull/2872) Remove type-hint
## 4.3.0 - 2019-10-05
### Added
- [2819](https://github.com/slimphp/Slim/pull/2819) Added description to addRoutingMiddleware()
- [2820](https://github.com/slimphp/Slim/pull/2820) Update link to homepage in composer.json
- [2828](https://github.com/slimphp/Slim/pull/2828) Allow URIs with leading multi-slashes
- [2832](https://github.com/slimphp/Slim/pull/2832) Refactor `FastRouteDispatcher`
- [2835](https://github.com/slimphp/Slim/pull/2835) Rename `pathFor` to `urlFor` in docblock
- [2846](https://github.com/slimphp/Slim/pull/2846) Correcting the branch name as per issue-2843
- [2849](https://github.com/slimphp/Slim/pull/2849) Create class alias for FastRoute\RouteCollector
- [2855](https://github.com/slimphp/Slim/pull/2855) Add list of allowed methods to HttpMethodNotAllowedException
- [2860](https://github.com/slimphp/Slim/pull/2860) Add base path to `$request` and use `RouteContext` to read
### Fixed
- [2839](https://github.com/slimphp/Slim/pull/2839) Fix description for handler signature in phpdocs
- [2844](https://github.com/slimphp/Slim/pull/2844) Handle base path by routeCollector instead of RouteCollectorProxy
- [2845](https://github.com/slimphp/Slim/pull/2845) Fix composer scripts
- [2851](https://github.com/slimphp/Slim/pull/2851) Fix example of 'Hello World' app
- [2854](https://github.com/slimphp/Slim/pull/2854) Fix undefined property in tests
### Removed
- [2853](https://github.com/slimphp/Slim/pull/2853) Remove unused classes
## 4.2.0 - 2019-08-20
### Added
- [2787](https://github.com/slimphp/Slim/pull/2787) Add an advanced callable resolver
- [2791](https://github.com/slimphp/Slim/pull/2791) Add `inferPrivatePropertyTypeFromConstructor` to phpstan
- [2793](https://github.com/slimphp/Slim/pull/2793) Add ability to configure application via a container in `AppFactory`
- [2798](https://github.com/slimphp/Slim/pull/2798) Add PSR-7 Agnostic Body Parsing Middleware
- [2801](https://github.com/slimphp/Slim/pull/2801) Add `setLogErrorRenderer()` method to `ErrorHandler`
- [2807](https://github.com/slimphp/Slim/pull/2807) Add check for Slim callable notation if no resolver given
- [2803](https://github.com/slimphp/Slim/pull/2803) Add ability to emit non seekable streams in `ResponseEmitter`
- [2817](https://github.com/slimphp/Slim/pull/2817) Add the ability to pass in a custom `MiddlewareDispatcherInterface` to the `App`
### Fixed
- [2789](https://github.com/slimphp/Slim/pull/2789) Fix Cookie header detection in `ResponseEmitter`
- [2796](https://github.com/slimphp/Slim/pull/2796) Fix http message format
- [2800](https://github.com/slimphp/Slim/pull/2800) Fix null comparisons more clear in `ErrorHandler`
- [2802](https://github.com/slimphp/Slim/pull/2802) Fix incorrect search of a header in stack
- [2806](https://github.com/slimphp/Slim/pull/2806) Simplify `Route::prepare()` method argument preparation
- [2809](https://github.com/slimphp/Slim/pull/2809) Eliminate a duplicate code via HOF in `MiddlewareDispatcher`
- [2816](https://github.com/slimphp/Slim/pull/2816) Fix RouteCollectorProxy::redirect() bug
### Removed
- [2811](https://github.com/slimphp/Slim/pull/2811) Remove `DeferredCallable`
## 4.1.0 - 2019-08-06
### Added
- [#2779](https://github.com/slimphp/Slim/pull/2774) Add support for Slim callables `Class:method` resolution & Container Closure auto-binding in `MiddlewareDispatcher`
- [#2774](https://github.com/slimphp/Slim/pull/2774) Add possibility for custom `RequestHandler` invocation strategies
### Fixed
- [#2776](https://github.com/slimphp/Slim/pull/2774) Fix group middleware on multiple nested groups
================================================
FILE: CODE_OF_CONDUCT.md
================================================
# Code of Conduct
The Slim Framework code of conduct is derived from the Ruby code of conduct. This document provides community guidelines for a safe, respectful, productive, and collaborative place for any person who is willing to contribute to the Slim Framework community. It applies to all “collaborative space”, which is defined as community communications channels (such as mailing lists, IRC, Slack, forums, submitted patches, commit comments, etc.). Any violations of the code of conduct may be reported by contacting one or more of the project maintainers either directly or via email to maintainers@slimframework.com.
* Participants will be tolerant of opposing views.
* Participants must ensure that their language and actions are free of personal attacks and disparaging personal remarks.
* When interpreting the words and actions of others, participants should always assume good intentions.
* Behaviour that the project maintainers consider to be harassment will not be tolerated.
================================================
FILE: CONTRIBUTING.md
================================================
# How to Contribute
## Pull Requests
1. Fork the Slim Framework repository
2. Create a new branch for each feature or improvement
3. Send a pull request from each feature branch to the **4.x** branch
It is very important to separate new features or improvements into separate feature branches, and to send a
pull request for each branch. This allows me to review and pull in new features or improvements individually.
## Style Guide
All pull requests must adhere to the [PSR-12 standard](https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-12-extended-coding-style-guide.md).
## Unit Testing
All pull requests must be accompanied by passing unit tests and complete code coverage. The Slim Framework uses phpunit for testing.
[Learn about PHPUnit](https://github.com/sebastianbergmann/phpunit/)
================================================
FILE: LICENSE.md
================================================
Copyright (c) 2011-2022 Josh Lockhart
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is furnished
to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
================================================
FILE: MAINTAINERS.md
================================================
# Maintainers
There aren't many rules for maintainers of Slim to remember; what we have is listed here.
## We don't merge our own PRs
Our code is better if more than one set of eyes looks at it. Therefore we do not merge our own pull requests unless there is an exceptional circumstance. This helps to spot errors in the patch and also enables us to share information about the project around the maintainer team.
## PRs tagged `WIP` are not ready to be merged
Sometimes it's helpful to collaborate on a patch before it's ready to be merged. We use the text `WIP` (for _Work in Progress_) in the title to mark these PRs.
If a PR has `WIP` in its title, then it is not to be merged. The person who raised the PR will remove the `WIP` text when they are ready for a full review and merge.
## Assign a merged PR to a milestone
By ensuring that all merged PRs are assigned to a milestone, we can easily find which PRs were in which release.
================================================
FILE: README.md
================================================
# Slim Framework
[](https://github.com/slimphp/Slim/actions/workflows/tests.yml?query=branch:4.x)
[](https://coveralls.io/github/slimphp/Slim?branch=4.x)
[](https://packagist.org/packages/slim/slim)
[](https://packagist.org/packages/slim/slim)
Slim is a PHP micro-framework that helps you quickly write simple yet powerful web applications and APIs.
## Installation
It's recommended that you use [Composer](https://getcomposer.org/) to install Slim.
```bash
$ composer require slim/slim
```
This will install Slim and all required dependencies. Slim requires PHP 7.4 or newer.
## Choose a PSR-7 Implementation & ServerRequest Creator
Before you can get up and running with Slim you will need to choose a PSR-7 implementation that best fits your application. A few notable ones:
- [Slim-Psr7](https://github.com/slimphp/Slim-Psr7) - This is the Slim Framework PSR-7 implementation
- [httpsoft/http-message](https://github.com/httpsoft/http-message) & [httpsoft/http-server-request](https://github.com/httpsoft/http-server-request) - This is the fastest, strictest and most lightweight implementation available
- [Nyholm/psr7](https://github.com/Nyholm/psr7) & [Nyholm/psr7-server](https://github.com/Nyholm/psr7-server) - Performance is almost the same as the HttpSoft implementation
- [Guzzle/psr7](https://github.com/guzzle/psr7) - This is the implementation used by the Guzzle Client, featuring extra functionality for stream and file handling
- [laminas-diactoros](https://github.com/laminas/laminas-diactoros) - This is the Laminas (Zend) PSR-7 implementation
## Slim-Http Decorators
[Slim-Http](https://github.com/slimphp/Slim-Http) is a set of decorators for any PSR-7 implementation that we recommend is used with Slim Framework.
To install the Slim-Http library simply run the following command:
```bash
composer require slim/http
```
The `ServerRequest` and `Response` object decorators are automatically detected and applied by the internal factories. If you have installed Slim-Http and wish to turn off automatic object decoration then you can use the following statements:
```php
<?php
use Slim\Factory\AppFactory;
use Slim\Factory\ServerRequestCreatorFactory;
AppFactory::setSlimHttpDecoratorsAutomaticDetection(false);
ServerRequestCreatorFactory::setSlimHttpDecoratorsAutomaticDetection(false);
$app = AppFactory::create();
// ...
```
## Hello World using AppFactory with PSR-7 auto-detection
In order for auto-detection to work and enable you to use `AppFactory::create()` and `App::run()` without having to manually create a `ServerRequest` you need to install one of the following implementations:
- [Slim-Psr7](https://github.com/slimphp/Slim-Psr7) - Install using `composer require slim/psr7`
- [httpsoft/http-message](https://github.com/httpsoft/http-message) & [httpsoft/http-server-request](https://github.com/httpsoft/http-server-request) - Install using:
`composer require httpsoft/http-message httpsoft/http-server-request`
- [Nyholm/psr7](https://github.com/Nyholm/psr7) & [Nyholm/psr7-server](https://github.com/Nyholm/psr7-server) - Install using `composer require nyholm/psr7 nyholm/psr7-server`
- [Guzzle/psr7](https://github.com/guzzle/psr7) - Install using `composer require guzzlehttp/psr7`
- [laminas-diactoros](https://github.com/laminas/laminas-diactoros) - Install using `composer require laminas/laminas-diactoros`
Then create file _public/index.php_.
```php
<?php
use Psr\Http\Message\ResponseInterface as Response;
use Psr\Http\Message\ServerRequestInterface as Request;
use Slim\Factory\AppFactory;
require __DIR__ . '/../vendor/autoload.php';
// Instantiate App
$app = AppFactory::create();
// Add error middleware
$app->addErrorMiddleware(true, true, true);
// Add routes
$app->get('/', function (Request $request, Response $response) {
$response->getBody()->write('<a href="/hello/world">Try /hello/world</a>');
return $response;
});
$app->get('/hello/{name}', function (Request $request, Response $response, $args) {
$name = $args['name'];
$response->getBody()->write("Hello, $name");
return $response;
});
$app->run();
```
You may quickly test this using the built-in PHP server:
```bash
$ php -S localhost:8000 -t public
```
Going to http://localhost:8000/hello/world will now display "Hello, world".
For more information on how to configure your web server, see the [Documentation](https://www.slimframework.com/docs/v4/start/web-servers.html).
## Tests
To execute the test suite, you'll need to install all development dependencies.
```bash
$ git clone https://github.com/slimphp/Slim
$ composer install
$ composer test
```
## Contributing
Please see [CONTRIBUTING](CONTRIBUTING.md) for details.
## Learn More
Learn more at these links:
- [Website](https://www.slimframework.com)
- [Documentation](https://www.slimframework.com/docs/v4/start/installation.html)
- [Slack](https://slimphp.slack.com)
- [Support Forum](https://discourse.slimframework.com)
- [Twitter](https://twitter.com/slimphp)
- [Resources](https://github.com/xssc/awesome-slim)
## Security
If you discover security related issues, please email security@slimframework.com instead of using the issue tracker.
## For enterprise
Available as part of the Tidelift Subscription.
The maintainers of `Slim` and thousands of other packages are working with Tidelift to deliver commercial support and maintenance for the open source dependencies you use to build your applications. Save time, reduce risk, and improve code health, while paying the maintainers of the exact dependencies you use. [Learn more.](https://tidelift.com/subscription/pkg/packagist-slim-slim?utm_source=packagist-slim-slim&utm_medium=referral&utm_campaign=enterprise&utm_term=repo)
## Contributors
### Code Contributors
This project exists thanks to all the people who contribute. [Contribute](CONTRIBUTING.md).
<a href="https://github.com/slimphp/Slim/graphs/contributors">
<img src="https://opencollective.com/slimphp/contributors.svg?width=890&button=false" />
</a>
### Financial Contributors
Become a financial contributor and help us sustain our community. [Contribute](https://opencollective.com/slimphp/contribute)
#### Individuals
<a href="https://opencollective.com/slimphp"><img src="https://opencollective.com/slimphp/individuals.svg?width=890"></a>
#### Organizations
Support this project with your organization. Your logo will show up here with a link to your website. [Contribute](https://opencollective.com/slimphp/contribute)
<a href="https://opencollective.com/slimphp/organization/0/website"><img src="https://opencollective.com/slimphp/organization/0/avatar.svg"></a>
<a href="https://opencollective.com/slimphp/organization/1/website"><img src="https://opencollective.com/slimphp/organization/1/avatar.svg"></a>
<a href="https://opencollective.com/slimphp/organization/2/website"><img src="https://opencollective.com/slimphp/organization/2/avatar.svg"></a>
<a href="https://opencollective.com/slimphp/organization/3/website"><img src="https://opencollective.com/slimphp/organization/3/avatar.svg"></a>
<a href="https://opencollective.com/slimphp/organization/4/website"><img src="https://opencollective.com/slimphp/organization/4/avatar.svg"></a>
<a href="https://opencollective.com/slimphp/organization/5/website"><img src="https://opencollective.com/slimphp/organization/5/avatar.svg"></a>
<a href="https://opencollective.com/slimphp/organization/6/website"><img src="https://opencollective.com/slimphp/organization/6/avatar.svg"></a>
<a href="https://opencollective.com/slimphp/organization/7/website"><img src="https://opencollective.com/slimphp/organization/7/avatar.svg"></a>
<a href="https://opencollective.com/slimphp/organization/8/website"><img src="https://opencollective.com/slimphp/organization/8/avatar.svg"></a>
<a href="https://opencollective.com/slimphp/organization/9/website"><img src="https://opencollective.com/slimphp/organization/9/avatar.svg"></a>
## License
The Slim Framework is licensed under the MIT license. See [License File](LICENSE.md) for more information.
================================================
FILE: SECURITY.md
================================================
# Security Policy
### Supported Versions
| Version | Supported |
| ------- | ------------------ |
| 3.x.x | :white_check_mark: |
| 4.x.x | :white_check_mark: |
### Reporting a Vulnerability
To report a vulnerability please send an email to security@slimframework.com
================================================
FILE: Slim/App.php
================================================
<?php
/**
* Slim Framework (https://slimframework.com)
*
* @license https://github.com/slimphp/Slim/blob/4.x/LICENSE.md (MIT License)
*/
declare(strict_types=1);
namespace Slim;
use Psr\Container\ContainerInterface;
use Psr\Http\Message\ResponseFactoryInterface;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Server\MiddlewareInterface;
use Psr\Http\Server\RequestHandlerInterface;
use Psr\Log\LoggerInterface;
use Slim\Factory\ServerRequestCreatorFactory;
use Slim\Interfaces\CallableResolverInterface;
use Slim\Interfaces\MiddlewareDispatcherInterface;
use Slim\Interfaces\RouteCollectorInterface;
use Slim\Interfaces\RouteResolverInterface;
use Slim\Middleware\BodyParsingMiddleware;
use Slim\Middleware\ErrorMiddleware;
use Slim\Middleware\RoutingMiddleware;
use Slim\Routing\RouteCollectorProxy;
use Slim\Routing\RouteResolver;
use Slim\Routing\RouteRunner;
use function strtoupper;
/**
* @api
* @template TContainerInterface of (ContainerInterface|null)
* @template-extends RouteCollectorProxy<TContainerInterface>
*/
class App extends RouteCollectorProxy implements RequestHandlerInterface
{
/**
* Current version
*
* @var string
*/
public const VERSION = '4.15.1';
protected RouteResolverInterface $routeResolver;
protected MiddlewareDispatcherInterface $middlewareDispatcher;
/**
* @param TContainerInterface $container
*/
public function __construct(
ResponseFactoryInterface $responseFactory,
?ContainerInterface $container = null,
?CallableResolverInterface $callableResolver = null,
?RouteCollectorInterface $routeCollector = null,
?RouteResolverInterface $routeResolver = null,
?MiddlewareDispatcherInterface $middlewareDispatcher = null
) {
parent::__construct(
$responseFactory,
$callableResolver ?? new CallableResolver($container),
$container,
$routeCollector
);
$this->routeResolver = $routeResolver ?? new RouteResolver($this->routeCollector);
$routeRunner = new RouteRunner($this->routeResolver, $this->routeCollector->getRouteParser(), $this);
if (!$middlewareDispatcher) {
$middlewareDispatcher = new MiddlewareDispatcher($routeRunner, $this->callableResolver, $container);
} else {
$middlewareDispatcher->seedMiddlewareStack($routeRunner);
}
$this->middlewareDispatcher = $middlewareDispatcher;
}
/**
* @return RouteResolverInterface
*/
public function getRouteResolver(): RouteResolverInterface
{
return $this->routeResolver;
}
/**
* @return MiddlewareDispatcherInterface
*/
public function getMiddlewareDispatcher(): MiddlewareDispatcherInterface
{
return $this->middlewareDispatcher;
}
/**
* @param MiddlewareInterface|string|callable $middleware
* @return App<TContainerInterface>
*/
public function add($middleware): self
{
$this->middlewareDispatcher->add($middleware);
return $this;
}
/**
* @param MiddlewareInterface $middleware
* @return App<TContainerInterface>
*/
public function addMiddleware(MiddlewareInterface $middleware): self
{
$this->middlewareDispatcher->addMiddleware($middleware);
return $this;
}
/**
* Add the Slim built-in routing middleware to the app middleware stack
*
* This method can be used to control middleware order and is not required for default routing operation.
*
* @return RoutingMiddleware
*/
public function addRoutingMiddleware(): RoutingMiddleware
{
$routingMiddleware = new RoutingMiddleware(
$this->getRouteResolver(),
$this->getRouteCollector()->getRouteParser()
);
$this->add($routingMiddleware);
return $routingMiddleware;
}
/**
* Add the Slim built-in error middleware to the app middleware stack
*
* @param bool $displayErrorDetails
* @param bool $logErrors
* @param bool $logErrorDetails
* @param LoggerInterface|null $logger
*
* @return ErrorMiddleware
*/
public function addErrorMiddleware(
bool $displayErrorDetails,
bool $logErrors,
bool $logErrorDetails,
?LoggerInterface $logger = null
): ErrorMiddleware {
$errorMiddleware = new ErrorMiddleware(
$this->getCallableResolver(),
$this->getResponseFactory(),
$displayErrorDetails,
$logErrors,
$logErrorDetails,
$logger
);
$this->add($errorMiddleware);
return $errorMiddleware;
}
/**
* Add the Slim body parsing middleware to the app middleware stack
*
* @param callable[] $bodyParsers
*
* @return BodyParsingMiddleware
*/
public function addBodyParsingMiddleware(array $bodyParsers = []): BodyParsingMiddleware
{
$bodyParsingMiddleware = new BodyParsingMiddleware($bodyParsers);
$this->add($bodyParsingMiddleware);
return $bodyParsingMiddleware;
}
/**
* Run application
*
* This method traverses the application middleware stack and then sends the
* resultant Response object to the HTTP client.
*
* @param ServerRequestInterface|null $request
* @return void
*/
public function run(?ServerRequestInterface $request = null): void
{
if (!$request) {
$serverRequestCreator = ServerRequestCreatorFactory::create();
$request = $serverRequestCreator->createServerRequestFromGlobals();
}
$response = $this->handle($request);
$responseEmitter = new ResponseEmitter();
$responseEmitter->emit($response);
}
/**
* Handle a request
*
* This method traverses the application middleware stack and then returns the
* resultant Response object.
*
* @param ServerRequestInterface $request
* @return ResponseInterface
*/
public function handle(ServerRequestInterface $request): ResponseInterface
{
$response = $this->middlewareDispatcher->handle($request);
/**
* This is to be in compliance with RFC 2616, Section 9.
* If the incoming request method is HEAD, we need to ensure that the response body
* is empty as the request may fall back on a GET route handler due to FastRoute's
* routing logic which could potentially append content to the response body
* https://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html#sec9.4
*/
$method = strtoupper($request->getMethod());
if ($method === 'HEAD') {
$emptyBody = $this->responseFactory->createResponse()->getBody();
return $response->withBody($emptyBody);
}
return $response;
}
}
================================================
FILE: Slim/CallableResolver.php
================================================
<?php
/**
* Slim Framework (https://slimframework.com)
*
* @license https://github.com/slimphp/Slim/blob/4.x/LICENSE.md (MIT License)
*/
declare(strict_types=1);
namespace Slim;
use Closure;
use Psr\Container\ContainerInterface;
use Psr\Http\Server\MiddlewareInterface;
use Psr\Http\Server\RequestHandlerInterface;
use RuntimeException;
use Slim\Interfaces\AdvancedCallableResolverInterface;
use function class_exists;
use function is_array;
use function is_callable;
use function is_object;
use function is_string;
use function json_encode;
use function preg_match;
use function sprintf;
/**
* @template TContainerInterface of (ContainerInterface|null)
*/
final class CallableResolver implements AdvancedCallableResolverInterface
{
public static string $callablePattern = '!^([^\:]+)\:([a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*)$!';
/** @var TContainerInterface $container */
private ?ContainerInterface $container;
/**
* @param TContainerInterface $container
*/
public function __construct(?ContainerInterface $container = null)
{
$this->container = $container;
}
/**
* {@inheritdoc}
*/
public function resolve($toResolve): callable
{
$toResolve = $this->prepareToResolve($toResolve);
if (is_callable($toResolve)) {
return $this->bindToContainer($toResolve);
}
$resolved = $toResolve;
if (is_string($toResolve)) {
$resolved = $this->resolveSlimNotation($toResolve);
$resolved[1] ??= '__invoke';
}
$callable = $this->assertCallable($resolved, $toResolve);
return $this->bindToContainer($callable);
}
/**
* {@inheritdoc}
*/
public function resolveRoute($toResolve): callable
{
return $this->resolveByPredicate($toResolve, [$this, 'isRoute'], 'handle');
}
/**
* {@inheritdoc}
*/
public function resolveMiddleware($toResolve): callable
{
return $this->resolveByPredicate($toResolve, [$this, 'isMiddleware'], 'process');
}
/**
* @param callable|array{class-string, string}|string $toResolve
*
* @throws RuntimeException
*/
private function resolveByPredicate($toResolve, callable $predicate, string $defaultMethod): callable
{
$toResolve = $this->prepareToResolve($toResolve);
if (is_callable($toResolve)) {
return $this->bindToContainer($toResolve);
}
$resolved = $toResolve;
if ($predicate($toResolve)) {
$resolved = [$toResolve, $defaultMethod];
}
if (is_string($toResolve)) {
[$instance, $method] = $this->resolveSlimNotation($toResolve);
if ($method === null && $predicate($instance)) {
$method = $defaultMethod;
}
$resolved = [$instance, $method ?? '__invoke'];
}
$callable = $this->assertCallable($resolved, $toResolve);
return $this->bindToContainer($callable);
}
/**
* @param mixed $toResolve
*/
private function isRoute($toResolve): bool
{
return $toResolve instanceof RequestHandlerInterface;
}
/**
* @param mixed $toResolve
*/
private function isMiddleware($toResolve): bool
{
return $toResolve instanceof MiddlewareInterface;
}
/**
* @throws RuntimeException
*
* @return array{object, string|null} [Instance, Method Name]
*/
private function resolveSlimNotation(string $toResolve): array
{
/** @psalm-suppress ArgumentTypeCoercion */
preg_match(CallableResolver::$callablePattern, $toResolve, $matches);
[$class, $method] = $matches ? [$matches[1], $matches[2]] : [$toResolve, null];
if ($this->container && $this->container->has($class)) {
$instance = $this->container->get($class);
if (!is_object($instance)) {
throw new RuntimeException(sprintf('%s container entry is not an object', $class));
}
} else {
if (!class_exists($class)) {
if ($method) {
$class .= '::' . $method . '()';
}
throw new RuntimeException(sprintf('Callable %s does not exist', $class));
}
$instance = new $class($this->container);
}
return [$instance, $method];
}
/**
* @param mixed $resolved
* @param mixed $toResolve
*
* @throws RuntimeException
*/
private function assertCallable($resolved, $toResolve): callable
{
if (!is_callable($resolved)) {
if (is_callable($toResolve) || is_object($toResolve) || is_array($toResolve)) {
$formatedToResolve = ($toResolveJson = json_encode($toResolve)) !== false ? $toResolveJson : '';
} else {
$formatedToResolve = is_string($toResolve) ? $toResolve : '';
}
throw new RuntimeException(sprintf('%s is not resolvable', $formatedToResolve));
}
return $resolved;
}
private function bindToContainer(callable $callable): callable
{
if (is_array($callable) && $callable[0] instanceof Closure) {
$callable = $callable[0];
}
if ($this->container && $callable instanceof Closure) {
/** @var Closure $callable */
$callable = $callable->bindTo($this->container);
}
return $callable;
}
/**
* @param callable|string|array{class-string, string}|mixed $toResolve
*
* @return callable|string|array{class-string, string}|mixed
*/
private function prepareToResolve($toResolve)
{
if (!is_array($toResolve)) {
return $toResolve;
}
$candidate = $toResolve;
$class = array_shift($candidate);
$method = array_shift($candidate);
if (is_string($class) && is_string($method)) {
return $class . ':' . $method;
}
return $toResolve;
}
}
================================================
FILE: Slim/Error/AbstractErrorRenderer.php
================================================
<?php
/**
* Slim Framework (https://slimframework.com)
*
* @license https://github.com/slimphp/Slim/blob/4.x/LICENSE.md (MIT License)
*/
declare(strict_types=1);
namespace Slim\Error;
use Slim\Exception\HttpException;
use Slim\Interfaces\ErrorRendererInterface;
use Throwable;
/**
* Abstract Slim application error renderer
*
* It outputs the error message and diagnostic information in one of the following formats:
* JSON, XML, Plain Text or HTML
*/
abstract class AbstractErrorRenderer implements ErrorRendererInterface
{
protected string $defaultErrorTitle = 'Slim Application Error';
protected string $defaultErrorDescription = 'A website error has occurred. Sorry for the temporary inconvenience.';
protected function getErrorTitle(Throwable $exception): string
{
if ($exception instanceof HttpException) {
return $exception->getTitle();
}
return $this->defaultErrorTitle;
}
protected function getErrorDescription(Throwable $exception): string
{
if ($exception instanceof HttpException) {
return $exception->getDescription();
}
return $this->defaultErrorDescription;
}
}
================================================
FILE: Slim/Error/Renderers/HtmlErrorRenderer.php
================================================
<?php
/**
* Slim Framework (https://slimframework.com)
*
* @license https://github.com/slimphp/Slim/blob/4.x/LICENSE.md (MIT License)
*/
declare(strict_types=1);
namespace Slim\Error\Renderers;
use Slim\Error\AbstractErrorRenderer;
use Throwable;
use function get_class;
use function htmlentities;
use function sprintf;
/**
* Default Slim application HTML Error Renderer
*/
class HtmlErrorRenderer extends AbstractErrorRenderer
{
public function __invoke(Throwable $exception, bool $displayErrorDetails): string
{
if ($displayErrorDetails) {
$html = '<p>The application could not run because of the following error:</p>';
$html .= '<h2>Details</h2>';
$html .= $this->renderExceptionFragment($exception);
} else {
$html = "<p>{$this->getErrorDescription($exception)}</p>";
}
return $this->renderHtmlBody($this->getErrorTitle($exception), $html);
}
private function renderExceptionFragment(Throwable $exception): string
{
$html = sprintf('<div><strong>Type:</strong> %s</div>', get_class($exception));
$code = $exception->getCode();
$html .= sprintf('<div><strong>Code:</strong> %s</div>', $code);
$html .= sprintf('<div><strong>Message:</strong> %s</div>', htmlentities($exception->getMessage()));
$html .= sprintf('<div><strong>File:</strong> %s</div>', $exception->getFile());
$html .= sprintf('<div><strong>Line:</strong> %s</div>', $exception->getLine());
$html .= '<h2>Trace</h2>';
$html .= sprintf('<pre>%s</pre>', htmlentities($exception->getTraceAsString()));
return $html;
}
public function renderHtmlBody(string $title = '', string $html = ''): string
{
return sprintf(
'<!doctype html>' .
'<html lang="en">' .
' <head>' .
' <meta charset="utf-8">' .
' <meta name="viewport" content="width=device-width, initial-scale=1">' .
' <title>%s</title>' .
' <style>' .
' body{margin:0;padding:30px;font:12px/1.5 Helvetica,Arial,Verdana,sans-serif}' .
' h1{margin:0;font-size:48px;font-weight:normal;line-height:48px}' .
' strong{display:inline-block;width:65px}' .
' </style>' .
' </head>' .
' <body>' .
' <h1>%s</h1>' .
' <div>%s</div>' .
' <a href="#" onclick="window.history.go(-1)">Go Back</a>' .
' </body>' .
'</html>',
$title,
$title,
$html
);
}
}
================================================
FILE: Slim/Error/Renderers/JsonErrorRenderer.php
================================================
<?php
/**
* Slim Framework (https://slimframework.com)
*
* @license https://github.com/slimphp/Slim/blob/4.x/LICENSE.md (MIT License)
*/
declare(strict_types=1);
namespace Slim\Error\Renderers;
use Slim\Error\AbstractErrorRenderer;
use Throwable;
use function get_class;
use function json_encode;
use const JSON_PRETTY_PRINT;
use const JSON_UNESCAPED_SLASHES;
/**
* Default Slim application JSON Error Renderer
*/
class JsonErrorRenderer extends AbstractErrorRenderer
{
public function __invoke(Throwable $exception, bool $displayErrorDetails): string
{
$error = ['message' => $this->getErrorTitle($exception)];
if ($displayErrorDetails) {
$error['exception'] = [];
do {
$error['exception'][] = $this->formatExceptionFragment($exception);
} while ($exception = $exception->getPrevious());
}
return (string) json_encode($error, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES);
}
/**
* @return array<string|int>
*/
private function formatExceptionFragment(Throwable $exception): array
{
$code = $exception->getCode();
return [
'type' => get_class($exception),
'code' => $code,
'message' => $exception->getMessage(),
'file' => $exception->getFile(),
'line' => $exception->getLine(),
];
}
}
================================================
FILE: Slim/Error/Renderers/PlainTextErrorRenderer.php
================================================
<?php
/**
* Slim Framework (https://slimframework.com)
*
* @license https://github.com/slimphp/Slim/blob/4.x/LICENSE.md (MIT License)
*/
declare(strict_types=1);
namespace Slim\Error\Renderers;
use Slim\Error\AbstractErrorRenderer;
use Throwable;
use function get_class;
use function htmlentities;
use function sprintf;
/**
* Default Slim application Plain Text Error Renderer
*/
class PlainTextErrorRenderer extends AbstractErrorRenderer
{
public function __invoke(Throwable $exception, bool $displayErrorDetails): string
{
$text = "{$this->getErrorTitle($exception)}\n";
if ($displayErrorDetails) {
$text .= $this->formatExceptionFragment($exception);
while ($exception = $exception->getPrevious()) {
$text .= "\nPrevious Error:\n";
$text .= $this->formatExceptionFragment($exception);
}
}
return $text;
}
private function formatExceptionFragment(Throwable $exception): string
{
$text = sprintf("Type: %s\n", get_class($exception));
$code = $exception->getCode();
$text .= sprintf("Code: %s\n", $code);
$text .= sprintf("Message: %s\n", $exception->getMessage());
$text .= sprintf("File: %s\n", $exception->getFile());
$text .= sprintf("Line: %s\n", $exception->getLine());
$text .= sprintf('Trace: %s', $exception->getTraceAsString());
return $text;
}
}
================================================
FILE: Slim/Error/Renderers/XmlErrorRenderer.php
================================================
<?php
/**
* Slim Framework (https://slimframework.com)
*
* @license https://github.com/slimphp/Slim/blob/4.x/LICENSE.md (MIT License)
*/
declare(strict_types=1);
namespace Slim\Error\Renderers;
use Slim\Error\AbstractErrorRenderer;
use Throwable;
use function get_class;
use function sprintf;
use function str_replace;
/**
* Default Slim application XML Error Renderer
*/
class XmlErrorRenderer extends AbstractErrorRenderer
{
public function __invoke(Throwable $exception, bool $displayErrorDetails): string
{
$xml = '<' . '?xml version="1.0" encoding="UTF-8" standalone="yes"?' . ">\n";
$xml .= "<error>\n <message>" . $this->createCdataSection($this->getErrorTitle($exception)) . "</message>\n";
if ($displayErrorDetails) {
do {
$xml .= " <exception>\n";
$xml .= ' <type>' . get_class($exception) . "</type>\n";
$xml .= ' <code>' . $exception->getCode() . "</code>\n";
$xml .= ' <message>' . $this->createCdataSection($exception->getMessage()) . "</message>\n";
$xml .= ' <file>' . $exception->getFile() . "</file>\n";
$xml .= ' <line>' . $exception->getLine() . "</line>\n";
$xml .= " </exception>\n";
} while ($exception = $exception->getPrevious());
}
$xml .= '</error>';
return $xml;
}
/**
* Returns a CDATA section with the given content.
*/
private function createCdataSection(string $content): string
{
return sprintf('<![CDATA[%s]]>', str_replace(']]>', ']]]]><![CDATA[>', $content));
}
}
================================================
FILE: Slim/Exception/HttpBadRequestException.php
================================================
<?php
/**
* Slim Framework (https://slimframework.com)
*
* @license https://github.com/slimphp/Slim/blob/4.x/LICENSE.md (MIT License)
*/
declare(strict_types=1);
namespace Slim\Exception;
/** @api */
class HttpBadRequestException extends HttpSpecializedException
{
/**
* @var int
*/
protected $code = 400;
/**
* @var string
*/
protected $message = 'Bad request.';
protected string $title = '400 Bad Request';
protected string $description = 'The server cannot or will not process ' .
'the request due to an apparent client error.';
}
================================================
FILE: Slim/Exception/HttpException.php
================================================
<?php
/**
* Slim Framework (https://slimframework.com)
*
* @license https://github.com/slimphp/Slim/blob/4.x/LICENSE.md (MIT License)
*/
declare(strict_types=1);
namespace Slim\Exception;
use Psr\Http\Message\ServerRequestInterface;
use RuntimeException;
use Throwable;
/**
* @api
* @method int getCode()
*/
class HttpException extends RuntimeException
{
protected ServerRequestInterface $request;
protected string $title = '';
protected string $description = '';
public function __construct(
ServerRequestInterface $request,
string $message = '',
int $code = 0,
?Throwable $previous = null
) {
parent::__construct($message, $code, $previous);
$this->request = $request;
}
public function getRequest(): ServerRequestInterface
{
return $this->request;
}
public function getTitle(): string
{
return $this->title;
}
public function setTitle(string $title): self
{
$this->title = $title;
return $this;
}
public function getDescription(): string
{
return $this->description;
}
public function setDescription(string $description): self
{
$this->description = $description;
return $this;
}
}
================================================
FILE: Slim/Exception/HttpForbiddenException.php
================================================
<?php
/**
* Slim Framework (https://slimframework.com)
*
* @license https://github.com/slimphp/Slim/blob/4.x/LICENSE.md (MIT License)
*/
declare(strict_types=1);
namespace Slim\Exception;
/** @api */
class HttpForbiddenException extends HttpSpecializedException
{
/**
* @var int
*/
protected $code = 403;
/**
* @var string
*/
protected $message = 'Forbidden.';
protected string $title = '403 Forbidden';
protected string $description = 'You are not permitted to perform the requested operation.';
}
================================================
FILE: Slim/Exception/HttpGoneException.php
================================================
<?php
/**
* Slim Framework (https://slimframework.com)
*
* @license https://github.com/slimphp/Slim/blob/4.x/LICENSE.md (MIT License)
*/
declare(strict_types=1);
namespace Slim\Exception;
/** @api */
class HttpGoneException extends HttpSpecializedException
{
/**
* @var int
*/
protected $code = 410;
/**
* @var string
*/
protected $message = 'Gone.';
protected string $title = '410 Gone';
protected string $description = 'The target resource is no longer available at the origin server.';
}
================================================
FILE: Slim/Exception/HttpInternalServerErrorException.php
================================================
<?php
/**
* Slim Framework (https://slimframework.com)
*
* @license https://github.com/slimphp/Slim/blob/4.x/LICENSE.md (MIT License)
*/
declare(strict_types=1);
namespace Slim\Exception;
/** @api */
class HttpInternalServerErrorException extends HttpSpecializedException
{
/**
* @var int
*/
protected $code = 500;
/**
* @var string
*/
protected $message = 'Internal server error.';
protected string $title = '500 Internal Server Error';
protected string $description = 'Unexpected condition encountered preventing server from fulfilling request.';
}
================================================
FILE: Slim/Exception/HttpMethodNotAllowedException.php
================================================
<?php
/**
* Slim Framework (https://slimframework.com)
*
* @license https://github.com/slimphp/Slim/blob/4.x/LICENSE.md (MIT License)
*/
declare(strict_types=1);
namespace Slim\Exception;
use function implode;
class HttpMethodNotAllowedException extends HttpSpecializedException
{
/**
* @var string[]
*/
protected array $allowedMethods = [];
/**
* @var int
*/
protected $code = 405;
/**
* @var string
*/
protected $message = 'Method not allowed.';
protected string $title = '405 Method Not Allowed';
protected string $description = 'The request method is not supported for the requested resource.';
/**
* @return string[]
*/
public function getAllowedMethods(): array
{
return $this->allowedMethods;
}
/**
* @param string[] $methods
*/
public function setAllowedMethods(array $methods): self
{
$this->allowedMethods = $methods;
$this->message = 'Method not allowed. Must be one of: ' . implode(', ', $methods);
return $this;
}
}
================================================
FILE: Slim/Exception/HttpNotFoundException.php
================================================
<?php
/**
* Slim Framework (https://slimframework.com)
*
* @license https://github.com/slimphp/Slim/blob/4.x/LICENSE.md (MIT License)
*/
declare(strict_types=1);
namespace Slim\Exception;
class HttpNotFoundException extends HttpSpecializedException
{
/**
* @var int
*/
protected $code = 404;
/**
* @var string
*/
protected $message = 'Not found.';
protected string $title = '404 Not Found';
protected string $description = 'The requested resource could not be found. Please verify the URI and try again.';
}
================================================
FILE: Slim/Exception/HttpNotImplementedException.php
================================================
<?php
/**
* Slim Framework (https://slimframework.com)
*
* @license https://github.com/slimphp/Slim/blob/4.x/LICENSE.md (MIT License)
*/
declare(strict_types=1);
namespace Slim\Exception;
/** @api */
class HttpNotImplementedException extends HttpSpecializedException
{
/**
* @var int
*/
protected $code = 501;
/**
* @var string
*/
protected $message = 'Not implemented.';
protected string $title = '501 Not Implemented';
protected string $description = 'The server does not support the functionality required to fulfill the request.';
}
================================================
FILE: Slim/Exception/HttpSpecializedException.php
================================================
<?php
/**
* Slim Framework (https://slimframework.com)
*
* @license https://github.com/slimphp/Slim/blob/4.x/LICENSE.md (MIT License)
*/
declare(strict_types=1);
namespace Slim\Exception;
use Psr\Http\Message\ServerRequestInterface;
use Throwable;
abstract class HttpSpecializedException extends HttpException
{
/**
* @param ServerRequestInterface $request
* @param string|null $message
* @param Throwable|null $previous
*/
public function __construct(ServerRequestInterface $request, ?string $message = null, ?Throwable $previous = null)
{
if ($message !== null) {
$this->message = $message;
}
// @phpstan-ignore-next-line
parent::__construct($request, $this->message, $this->code, $previous);
}
}
================================================
FILE: Slim/Exception/HttpTooManyRequestsException.php
================================================
<?php
/**
* Slim Framework (https://slimframework.com)
*
* @license https://github.com/slimphp/Slim/blob/4.x/LICENSE.md (MIT License)
*/
declare(strict_types=1);
namespace Slim\Exception;
/** @api */
class HttpTooManyRequestsException extends HttpSpecializedException
{
/**
* @var int
*/
protected $code = 429;
/**
* @var string
*/
protected $message = 'Too many requests.';
protected string $title = '429 Too Many Requests';
protected string $description = 'The client application has surpassed its rate limit, ' .
'or number of requests they can send in a given period of time.';
}
================================================
FILE: Slim/Exception/HttpUnauthorizedException.php
================================================
<?php
/**
* Slim Framework (https://slimframework.com)
*
* @license https://github.com/slimphp/Slim/blob/4.x/LICENSE.md (MIT License)
*/
declare(strict_types=1);
namespace Slim\Exception;
/** @api */
class HttpUnauthorizedException extends HttpSpecializedException
{
/**
* @var int
*/
protected $code = 401;
/**
* @var string
*/
protected $message = 'Unauthorized.';
protected string $title = '401 Unauthorized';
protected string $description = 'The request requires valid user authentication.';
}
================================================
FILE: Slim/Factory/AppFactory.php
================================================
<?php
/**
* Slim Framework (https://slimframework.com)
*
* @license https://github.com/slimphp/Slim/blob/4.x/LICENSE.md (MIT License)
*/
declare(strict_types=1);
namespace Slim\Factory;
use Psr\Container\ContainerInterface;
use Psr\Http\Message\ResponseFactoryInterface;
use Psr\Http\Message\StreamFactoryInterface;
use RuntimeException;
use Slim\App;
use Slim\Factory\Psr17\Psr17Factory;
use Slim\Factory\Psr17\Psr17FactoryProvider;
use Slim\Factory\Psr17\SlimHttpPsr17Factory;
use Slim\Interfaces\CallableResolverInterface;
use Slim\Interfaces\MiddlewareDispatcherInterface;
use Slim\Interfaces\Psr17FactoryProviderInterface;
use Slim\Interfaces\RouteCollectorInterface;
use Slim\Interfaces\RouteResolverInterface;
/** @api */
class AppFactory
{
protected static ?Psr17FactoryProviderInterface $psr17FactoryProvider = null;
protected static ?ResponseFactoryInterface $responseFactory = null;
protected static ?StreamFactoryInterface $streamFactory = null;
protected static ?ContainerInterface $container = null;
protected static ?CallableResolverInterface $callableResolver = null;
protected static ?RouteCollectorInterface $routeCollector = null;
protected static ?RouteResolverInterface $routeResolver = null;
protected static ?MiddlewareDispatcherInterface $middlewareDispatcher = null;
protected static bool $slimHttpDecoratorsAutomaticDetectionEnabled = true;
/**
* @template TContainerInterface of (ContainerInterface|null)
* @param TContainerInterface $container
* @return (TContainerInterface is ContainerInterface ? App<TContainerInterface> : App<ContainerInterface|null>)
*/
public static function create(
?ResponseFactoryInterface $responseFactory = null,
?ContainerInterface $container = null,
?CallableResolverInterface $callableResolver = null,
?RouteCollectorInterface $routeCollector = null,
?RouteResolverInterface $routeResolver = null,
?MiddlewareDispatcherInterface $middlewareDispatcher = null
): App {
static::$responseFactory = $responseFactory ?? static::$responseFactory;
return new App(
self::determineResponseFactory(),
$container ?? static::$container,
$callableResolver ?? static::$callableResolver,
$routeCollector ?? static::$routeCollector,
$routeResolver ?? static::$routeResolver,
$middlewareDispatcher ?? static::$middlewareDispatcher
);
}
/**
* @template TContainerInterface of (ContainerInterface)
* @param TContainerInterface $container
* @return App<TContainerInterface>
*/
public static function createFromContainer(ContainerInterface $container): App
{
$responseFactory = $container->has(ResponseFactoryInterface::class)
&& (
$responseFactoryFromContainer = $container->get(ResponseFactoryInterface::class)
) instanceof ResponseFactoryInterface
? $responseFactoryFromContainer
: self::determineResponseFactory();
$callableResolver = $container->has(CallableResolverInterface::class)
&& (
$callableResolverFromContainer = $container->get(CallableResolverInterface::class)
) instanceof CallableResolverInterface
? $callableResolverFromContainer
: null;
$routeCollector = $container->has(RouteCollectorInterface::class)
&& (
$routeCollectorFromContainer = $container->get(RouteCollectorInterface::class)
) instanceof RouteCollectorInterface
? $routeCollectorFromContainer
: null;
$routeResolver = $container->has(RouteResolverInterface::class)
&& (
$routeResolverFromContainer = $container->get(RouteResolverInterface::class)
) instanceof RouteResolverInterface
? $routeResolverFromContainer
: null;
$middlewareDispatcher = $container->has(MiddlewareDispatcherInterface::class)
&& (
$middlewareDispatcherFromContainer = $container->get(MiddlewareDispatcherInterface::class)
) instanceof MiddlewareDispatcherInterface
? $middlewareDispatcherFromContainer
: null;
return new App(
$responseFactory,
$container,
$callableResolver,
$routeCollector,
$routeResolver,
$middlewareDispatcher
);
}
/**
* @throws RuntimeException
*/
public static function determineResponseFactory(): ResponseFactoryInterface
{
if (static::$responseFactory) {
if (static::$streamFactory) {
return static::attemptResponseFactoryDecoration(static::$responseFactory, static::$streamFactory);
}
return static::$responseFactory;
}
$psr17FactoryProvider = static::$psr17FactoryProvider ?? new Psr17FactoryProvider();
/** @var Psr17Factory $psr17factory */
foreach ($psr17FactoryProvider->getFactories() as $psr17factory) {
if ($psr17factory::isResponseFactoryAvailable()) {
$responseFactory = $psr17factory::getResponseFactory();
if (static::$streamFactory || $psr17factory::isStreamFactoryAvailable()) {
$streamFactory = static::$streamFactory ?? $psr17factory::getStreamFactory();
return static::attemptResponseFactoryDecoration($responseFactory, $streamFactory);
}
return $responseFactory;
}
}
throw new RuntimeException(
"Could not detect any PSR-17 ResponseFactory implementations. " .
"Please install a supported implementation in order to use `AppFactory::create()`. " .
"See https://github.com/slimphp/Slim/blob/4.x/README.md for a list of supported implementations."
);
}
protected static function attemptResponseFactoryDecoration(
ResponseFactoryInterface $responseFactory,
StreamFactoryInterface $streamFactory
): ResponseFactoryInterface {
if (
static::$slimHttpDecoratorsAutomaticDetectionEnabled
&& SlimHttpPsr17Factory::isResponseFactoryAvailable()
) {
return SlimHttpPsr17Factory::createDecoratedResponseFactory($responseFactory, $streamFactory);
}
return $responseFactory;
}
public static function setPsr17FactoryProvider(Psr17FactoryProviderInterface $psr17FactoryProvider): void
{
static::$psr17FactoryProvider = $psr17FactoryProvider;
}
public static function setResponseFactory(ResponseFactoryInterface $responseFactory): void
{
static::$responseFactory = $responseFactory;
}
public static function setStreamFactory(StreamFactoryInterface $streamFactory): void
{
static::$streamFactory = $streamFactory;
}
public static function setContainer(ContainerInterface $container): void
{
static::$container = $container;
}
public static function setCallableResolver(CallableResolverInterface $callableResolver): void
{
static::$callableResolver = $callableResolver;
}
public static function setRouteCollector(RouteCollectorInterface $routeCollector): void
{
static::$routeCollector = $routeCollector;
}
public static function setRouteResolver(RouteResolverInterface $routeResolver): void
{
static::$routeResolver = $routeResolver;
}
public static function setMiddlewareDispatcher(MiddlewareDispatcherInterface $middlewareDispatcher): void
{
static::$middlewareDispatcher = $middlewareDispatcher;
}
public static function setSlimHttpDecoratorsAutomaticDetection(bool $enabled): void
{
static::$slimHttpDecoratorsAutomaticDetectionEnabled = $enabled;
}
}
================================================
FILE: Slim/Factory/Psr17/GuzzlePsr17Factory.php
================================================
<?php
/**
* Slim Framework (https://slimframework.com)
*
* @license https://github.com/slimphp/Slim/blob/4.x/LICENSE.md (MIT License)
*/
declare(strict_types=1);
namespace Slim\Factory\Psr17;
class GuzzlePsr17Factory extends Psr17Factory
{
protected static string $responseFactoryClass = 'GuzzleHttp\Psr7\HttpFactory';
protected static string $streamFactoryClass = 'GuzzleHttp\Psr7\HttpFactory';
protected static string $serverRequestCreatorClass = 'GuzzleHttp\Psr7\ServerRequest';
protected static string $serverRequestCreatorMethod = 'fromGlobals';
}
================================================
FILE: Slim/Factory/Psr17/HttpSoftPsr17Factory.php
================================================
<?php
/**
* Slim Framework (https://slimframework.com)
*
* @license https://github.com/slimphp/Slim/blob/4.x/LICENSE.md (MIT License)
*/
declare(strict_types=1);
namespace Slim\Factory\Psr17;
class HttpSoftPsr17Factory extends Psr17Factory
{
protected static string $responseFactoryClass = 'HttpSoft\Message\ResponseFactory';
protected static string $streamFactoryClass = 'HttpSoft\Message\StreamFactory';
protected static string $serverRequestCreatorClass = 'HttpSoft\ServerRequest\ServerRequestCreator';
protected static string $serverRequestCreatorMethod = 'createFromGlobals';
}
================================================
FILE: Slim/Factory/Psr17/LaminasDiactorosPsr17Factory.php
================================================
<?php
/**
* Slim Framework (https://slimframework.com)
*
* @license https://github.com/slimphp/Slim/blob/4.x/LICENSE.md (MIT License)
*/
declare(strict_types=1);
namespace Slim\Factory\Psr17;
class LaminasDiactorosPsr17Factory extends Psr17Factory
{
protected static string $responseFactoryClass = 'Laminas\Diactoros\ResponseFactory';
protected static string $streamFactoryClass = 'Laminas\Diactoros\StreamFactory';
protected static string $serverRequestCreatorClass = 'Laminas\Diactoros\ServerRequestFactory';
protected static string $serverRequestCreatorMethod = 'fromGlobals';
}
================================================
FILE: Slim/Factory/Psr17/NyholmPsr17Factory.php
================================================
<?php
declare(strict_types=1);
namespace Slim\Factory\Psr17;
use Slim\Interfaces\ServerRequestCreatorInterface;
class NyholmPsr17Factory extends Psr17Factory
{
protected static string $responseFactoryClass = 'Nyholm\Psr7\Factory\Psr17Factory';
protected static string $streamFactoryClass = 'Nyholm\Psr7\Factory\Psr17Factory';
protected static string $serverRequestCreatorClass = 'Nyholm\Psr7Server\ServerRequestCreator';
protected static string $serverRequestCreatorMethod = 'fromGlobals';
/**
* {@inheritdoc}
*/
public static function getServerRequestCreator(): ServerRequestCreatorInterface
{
/*
* Nyholm Psr17Factory implements all factories in one unified
* factory which implements all of the PSR-17 factory interfaces
*/
$psr17Factory = new static::$responseFactoryClass();
$serverRequestCreator = new static::$serverRequestCreatorClass(
$psr17Factory,
$psr17Factory,
$psr17Factory,
$psr17Factory
);
return new ServerRequestCreator($serverRequestCreator, static::$serverRequestCreatorMethod);
}
}
================================================
FILE: Slim/Factory/Psr17/Psr17Factory.php
================================================
<?php
/**
* Slim Framework (https://slimframework.com)
*
* @license https://github.com/slimphp/Slim/blob/4.x/LICENSE.md (MIT License)
*/
declare(strict_types=1);
namespace Slim\Factory\Psr17;
use Psr\Http\Message\ResponseFactoryInterface;
use Psr\Http\Message\StreamFactoryInterface;
use RuntimeException;
use Slim\Interfaces\Psr17FactoryInterface;
use Slim\Interfaces\ServerRequestCreatorInterface;
use function class_exists;
use function get_called_class;
abstract class Psr17Factory implements Psr17FactoryInterface
{
protected static string $responseFactoryClass;
protected static string $streamFactoryClass;
protected static string $serverRequestCreatorClass;
protected static string $serverRequestCreatorMethod;
/**
* {@inheritdoc}
*/
public static function getResponseFactory(): ResponseFactoryInterface
{
if (
!static::isResponseFactoryAvailable()
|| !(($responseFactory = new static::$responseFactoryClass()) instanceof ResponseFactoryInterface)
) {
throw new RuntimeException(get_called_class() . ' could not instantiate a response factory.');
}
return $responseFactory;
}
/**
* {@inheritdoc}
*/
public static function getStreamFactory(): StreamFactoryInterface
{
if (
!static::isStreamFactoryAvailable()
|| !(($streamFactory = new static::$streamFactoryClass()) instanceof StreamFactoryInterface)
) {
throw new RuntimeException(get_called_class() . ' could not instantiate a stream factory.');
}
return $streamFactory;
}
/**
* {@inheritdoc}
*/
public static function getServerRequestCreator(): ServerRequestCreatorInterface
{
if (!static::isServerRequestCreatorAvailable()) {
throw new RuntimeException(get_called_class() . ' could not instantiate a server request creator.');
}
return new ServerRequestCreator(static::$serverRequestCreatorClass, static::$serverRequestCreatorMethod);
}
/**
* {@inheritdoc}
*/
public static function isResponseFactoryAvailable(): bool
{
return static::$responseFactoryClass && class_exists(static::$responseFactoryClass);
}
/**
* {@inheritdoc}
*/
public static function isStreamFactoryAvailable(): bool
{
return static::$streamFactoryClass && class_exists(static::$streamFactoryClass);
}
/**
* {@inheritdoc}
*/
public static function isServerRequestCreatorAvailable(): bool
{
return (
static::$serverRequestCreatorClass
&& static::$serverRequestCreatorMethod
&& class_exists(static::$serverRequestCreatorClass)
);
}
}
================================================
FILE: Slim/Factory/Psr17/Psr17FactoryProvider.php
================================================
<?php
/**
* Slim Framework (https://slimframework.com)
*
* @license https://github.com/slimphp/Slim/blob/4.x/LICENSE.md (MIT License)
*/
declare(strict_types=1);
namespace Slim\Factory\Psr17;
use Slim\Interfaces\Psr17FactoryProviderInterface;
use function array_unshift;
class Psr17FactoryProvider implements Psr17FactoryProviderInterface
{
/**
* @var string[]
*/
protected static array $factories = [
SlimPsr17Factory::class,
HttpSoftPsr17Factory::class,
NyholmPsr17Factory::class,
LaminasDiactorosPsr17Factory::class,
GuzzlePsr17Factory::class,
];
/**
* {@inheritdoc}
*/
public static function getFactories(): array
{
return static::$factories;
}
/**
* {@inheritdoc}
*/
public static function setFactories(array $factories): void
{
static::$factories = $factories;
}
/**
* {@inheritdoc}
*/
public static function addFactory(string $factory): void
{
array_unshift(static::$factories, $factory);
}
}
================================================
FILE: Slim/Factory/Psr17/ServerRequestCreator.php
================================================
<?php
/**
* Slim Framework (https://slimframework.com)
*
* @license https://github.com/slimphp/Slim/blob/4.x/LICENSE.md (MIT License)
*/
declare(strict_types=1);
namespace Slim\Factory\Psr17;
use Closure;
use Psr\Http\Message\ServerRequestInterface;
use Slim\Interfaces\ServerRequestCreatorInterface;
class ServerRequestCreator implements ServerRequestCreatorInterface
{
/**
* @var object|string
*/
protected $serverRequestCreator;
protected string $serverRequestCreatorMethod;
/**
* @param object|string $serverRequestCreator
*/
public function __construct($serverRequestCreator, string $serverRequestCreatorMethod)
{
$this->serverRequestCreator = $serverRequestCreator;
$this->serverRequestCreatorMethod = $serverRequestCreatorMethod;
}
/**
* {@inheritdoc}
*/
public function createServerRequestFromGlobals(): ServerRequestInterface
{
/** @var callable $callable */
$callable = [$this->serverRequestCreator, $this->serverRequestCreatorMethod];
/** @var ServerRequestInterface */
return (Closure::fromCallable($callable))();
}
}
================================================
FILE: Slim/Factory/Psr17/SlimHttpPsr17Factory.php
================================================
<?php
/**
* Slim Framework (https://slimframework.com)
*
* @license https://github.com/slimphp/Slim/blob/4.x/LICENSE.md (MIT License)
*/
declare(strict_types=1);
namespace Slim\Factory\Psr17;
use Psr\Http\Message\ResponseFactoryInterface;
use Psr\Http\Message\StreamFactoryInterface;
use RuntimeException;
class SlimHttpPsr17Factory extends Psr17Factory
{
protected static string $responseFactoryClass = 'Slim\Http\Factory\DecoratedResponseFactory';
/**
* @throws RuntimeException when the factory could not be instantiated
*/
public static function createDecoratedResponseFactory(
ResponseFactoryInterface $responseFactory,
StreamFactoryInterface $streamFactory
): ResponseFactoryInterface {
if (
!((
$decoratedResponseFactory = new static::$responseFactoryClass($responseFactory, $streamFactory)
) instanceof ResponseFactoryInterface
)
) {
throw new RuntimeException(get_called_class() . ' could not instantiate a decorated response factory.');
}
return $decoratedResponseFactory;
}
}
================================================
FILE: Slim/Factory/Psr17/SlimHttpServerRequestCreator.php
================================================
<?php
/**
* Slim Framework (https://slimframework.com)
*
* @license https://github.com/slimphp/Slim/blob/4.x/LICENSE.md (MIT License)
*/
declare(strict_types=1);
namespace Slim\Factory\Psr17;
use Psr\Http\Message\ServerRequestInterface;
use RuntimeException;
use Slim\Interfaces\ServerRequestCreatorInterface;
use function class_exists;
class SlimHttpServerRequestCreator implements ServerRequestCreatorInterface
{
protected ServerRequestCreatorInterface $serverRequestCreator;
protected static string $serverRequestDecoratorClass = 'Slim\Http\ServerRequest';
public function __construct(ServerRequestCreatorInterface $serverRequestCreator)
{
$this->serverRequestCreator = $serverRequestCreator;
}
/**
* {@inheritdoc}
*/
public function createServerRequestFromGlobals(): ServerRequestInterface
{
if (!static::isServerRequestDecoratorAvailable()) {
throw new RuntimeException('The Slim-Http ServerRequest decorator is not available.');
}
$request = $this->serverRequestCreator->createServerRequestFromGlobals();
if (
!((
$decoratedServerRequest = new static::$serverRequestDecoratorClass($request)
) instanceof ServerRequestInterface)
) {
throw new RuntimeException(get_called_class() . ' could not instantiate a decorated server request.');
}
return $decoratedServerRequest;
}
public static function isServerRequestDecoratorAvailable(): bool
{
return class_exists(static::$serverRequestDecoratorClass);
}
}
================================================
FILE: Slim/Factory/Psr17/SlimPsr17Factory.php
================================================
<?php
/**
* Slim Framework (https://slimframework.com)
*
* @license https://github.com/slimphp/Slim/blob/4.x/LICENSE.md (MIT License)
*/
declare(strict_types=1);
namespace Slim\Factory\Psr17;
class SlimPsr17Factory extends Psr17Factory
{
protected static string $responseFactoryClass = 'Slim\Psr7\Factory\ResponseFactory';
protected static string $streamFactoryClass = 'Slim\Psr7\Factory\StreamFactory';
protected static string $serverRequestCreatorClass = 'Slim\Psr7\Factory\ServerRequestFactory';
protected static string $serverRequestCreatorMethod = 'createFromGlobals';
}
================================================
FILE: Slim/Factory/ServerRequestCreatorFactory.php
================================================
<?php
/**
* Slim Framework (https://slimframework.com)
*
* @license https://github.com/slimphp/Slim/blob/4.x/LICENSE.md (MIT License)
*/
declare(strict_types=1);
namespace Slim\Factory;
use RuntimeException;
use Slim\Factory\Psr17\Psr17Factory;
use Slim\Factory\Psr17\Psr17FactoryProvider;
use Slim\Factory\Psr17\SlimHttpServerRequestCreator;
use Slim\Interfaces\Psr17FactoryProviderInterface;
use Slim\Interfaces\ServerRequestCreatorInterface;
/** @api */
class ServerRequestCreatorFactory
{
protected static ?Psr17FactoryProviderInterface $psr17FactoryProvider = null;
protected static ?ServerRequestCreatorInterface $serverRequestCreator = null;
protected static bool $slimHttpDecoratorsAutomaticDetectionEnabled = true;
public static function create(): ServerRequestCreatorInterface
{
return static::determineServerRequestCreator();
}
/**
* @throws RuntimeException
*/
public static function determineServerRequestCreator(): ServerRequestCreatorInterface
{
if (static::$serverRequestCreator) {
return static::attemptServerRequestCreatorDecoration(static::$serverRequestCreator);
}
$psr17FactoryProvider = static::$psr17FactoryProvider ?? new Psr17FactoryProvider();
/** @var Psr17Factory $psr17Factory */
foreach ($psr17FactoryProvider->getFactories() as $psr17Factory) {
if ($psr17Factory::isServerRequestCreatorAvailable()) {
$serverRequestCreator = $psr17Factory::getServerRequestCreator();
return static::attemptServerRequestCreatorDecoration($serverRequestCreator);
}
}
throw new RuntimeException(
"Could not detect any ServerRequest creator implementations. " .
"Please install a supported implementation in order to use `App::run()` " .
"without having to pass in a `ServerRequest` object. " .
"See https://github.com/slimphp/Slim/blob/4.x/README.md for a list of supported implementations."
);
}
protected static function attemptServerRequestCreatorDecoration(
ServerRequestCreatorInterface $serverRequestCreator
): ServerRequestCreatorInterface {
if (
static::$slimHttpDecoratorsAutomaticDetectionEnabled
&& SlimHttpServerRequestCreator::isServerRequestDecoratorAvailable()
) {
return new SlimHttpServerRequestCreator($serverRequestCreator);
}
return $serverRequestCreator;
}
public static function setPsr17FactoryProvider(Psr17FactoryProviderInterface $psr17FactoryProvider): void
{
static::$psr17FactoryProvider = $psr17FactoryProvider;
}
public static function setServerRequestCreator(ServerRequestCreatorInterface $serverRequestCreator): void
{
self::$serverRequestCreator = $serverRequestCreator;
}
public static function setSlimHttpDecoratorsAutomaticDetection(bool $enabled): void
{
static::$slimHttpDecoratorsAutomaticDetectionEnabled = $enabled;
}
}
================================================
FILE: Slim/Handlers/ErrorHandler.php
================================================
<?php
/**
* Slim Framework (https://slimframework.com)
*
* @license https://github.com/slimphp/Slim/blob/4.x/LICENSE.md (MIT License)
*/
declare(strict_types=1);
namespace Slim\Handlers;
use Psr\Http\Message\ResponseFactoryInterface;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Log\LoggerInterface;
use RuntimeException;
use Slim\Error\Renderers\HtmlErrorRenderer;
use Slim\Error\Renderers\JsonErrorRenderer;
use Slim\Error\Renderers\PlainTextErrorRenderer;
use Slim\Error\Renderers\XmlErrorRenderer;
use Slim\Exception\HttpException;
use Slim\Exception\HttpMethodNotAllowedException;
use Slim\Interfaces\CallableResolverInterface;
use Slim\Interfaces\ErrorHandlerInterface;
use Slim\Interfaces\ErrorRendererInterface;
use Slim\Logger;
use Throwable;
use function array_intersect;
use function array_key_exists;
use function array_keys;
use function call_user_func;
use function count;
use function current;
use function explode;
use function implode;
use function next;
use function preg_match;
/**
* Default Slim application error handler
*
* It outputs the error message and diagnostic information in one of the following formats:
* JSON, XML, Plain Text or HTML based on the Accept header.
* @api
*/
class ErrorHandler implements ErrorHandlerInterface
{
protected string $defaultErrorRendererContentType = 'text/html';
/**
* @var ErrorRendererInterface|string|callable
*/
protected $defaultErrorRenderer = HtmlErrorRenderer::class;
/**
* @var ErrorRendererInterface|string|callable
*/
protected $logErrorRenderer = PlainTextErrorRenderer::class;
/**
* @var array<string|callable>
*/
protected array $errorRenderers = [
'application/json' => JsonErrorRenderer::class,
'application/xml' => XmlErrorRenderer::class,
'text/xml' => XmlErrorRenderer::class,
'text/html' => HtmlErrorRenderer::class,
'text/plain' => PlainTextErrorRenderer::class,
];
protected bool $displayErrorDetails = false;
protected bool $logErrors;
protected bool $logErrorDetails = false;
protected ?string $contentType = null;
protected ?string $method = null;
protected ServerRequestInterface $request;
protected Throwable $exception;
protected int $statusCode;
protected CallableResolverInterface $callableResolver;
protected ResponseFactoryInterface $responseFactory;
protected LoggerInterface $logger;
public function __construct(
CallableResolverInterface $callableResolver,
ResponseFactoryInterface $responseFactory,
?LoggerInterface $logger = null
) {
$this->callableResolver = $callableResolver;
$this->responseFactory = $responseFactory;
$this->logger = $logger ?: $this->getDefaultLogger();
}
/**
* Invoke error handler
*
* @param ServerRequestInterface $request The most recent Request object
* @param Throwable $exception The caught Exception object
* @param bool $displayErrorDetails Whether or not to display the error details
* @param bool $logErrors Whether or not to log errors
* @param bool $logErrorDetails Whether or not to log error details
*/
public function __invoke(
ServerRequestInterface $request,
Throwable $exception,
bool $displayErrorDetails,
bool $logErrors,
bool $logErrorDetails
): ResponseInterface {
$this->displayErrorDetails = $displayErrorDetails;
$this->logErrors = $logErrors;
$this->logErrorDetails = $logErrorDetails;
$this->request = $request;
$this->exception = $exception;
$this->method = $request->getMethod();
$this->statusCode = $this->determineStatusCode();
if ($this->contentType === null) {
$this->contentType = $this->determineContentType($request);
}
if ($logErrors) {
$this->writeToErrorLog();
}
return $this->respond();
}
/**
* Force the content type for all error handler responses.
*
* @param string|null $contentType The content type
*/
public function forceContentType(?string $contentType): void
{
$this->contentType = $contentType;
}
protected function determineStatusCode(): int
{
if ($this->method === 'OPTIONS') {
return 200;
}
if ($this->exception instanceof HttpException) {
return $this->exception->getCode();
}
return 500;
}
/**
* Determine which content type we know about is wanted using Accept header
*
* Note: This method is a bare-bones implementation designed specifically for
* Slim's error handling requirements. Consider a fully-feature solution such
* as willdurand/negotiation for any other situation.
*/
protected function determineContentType(ServerRequestInterface $request): ?string
{
$acceptHeader = $request->getHeaderLine('Accept');
$selectedContentTypes = array_intersect(
explode(',', $acceptHeader),
array_keys($this->errorRenderers)
);
$count = count($selectedContentTypes);
if ($count) {
$current = current($selectedContentTypes);
/**
* Ensure other supported content types take precedence over text/plain
* when multiple content types are provided via Accept header.
*/
if ($current === 'text/plain' && $count > 1) {
$next = next($selectedContentTypes);
if (is_string($next)) {
return $next;
}
}
// @phpstan-ignore-next-line
if (is_string($current)) {
return $current;
}
}
if (preg_match('/\+(json|xml)/', $acceptHeader, $matches)) {
$mediaType = 'application/' . $matches[1];
if (array_key_exists($mediaType, $this->errorRenderers)) {
return $mediaType;
}
}
return null;
}
/**
* Determine which renderer to use based on content type
*
* @throws RuntimeException
*/
protected function determineRenderer(): callable
{
if ($this->contentType !== null && array_key_exists($this->contentType, $this->errorRenderers)) {
$renderer = $this->errorRenderers[$this->contentType];
} else {
$renderer = $this->defaultErrorRenderer;
}
return $this->callableResolver->resolve($renderer);
}
/**
* Register an error renderer for a specific content-type
*
* @param string $contentType The content-type this renderer should be registered to
* @param ErrorRendererInterface|string|callable $errorRenderer The error renderer
*/
public function registerErrorRenderer(string $contentType, $errorRenderer): void
{
$this->errorRenderers[$contentType] = $errorRenderer;
}
/**
* Set the default error renderer
*
* @param string $contentType The content type of the default error renderer
* @param ErrorRendererInterface|string|callable $errorRenderer The default error renderer
*/
public function setDefaultErrorRenderer(string $contentType, $errorRenderer): void
{
$this->defaultErrorRendererContentType = $contentType;
$this->defaultErrorRenderer = $errorRenderer;
}
/**
* Set the renderer for the error logger
*
* @param ErrorRendererInterface|string|callable $logErrorRenderer
*/
public function setLogErrorRenderer($logErrorRenderer): void
{
$this->logErrorRenderer = $logErrorRenderer;
}
/**
* Write to the error log if $logErrors has been set to true
*/
protected function writeToErrorLog(): void
{
$renderer = $this->callableResolver->resolve($this->logErrorRenderer);
/** @var string $error */
$error = $renderer($this->exception, $this->logErrorDetails);
if ($this->logErrorRenderer === PlainTextErrorRenderer::class && !$this->displayErrorDetails) {
$error .= "\nTips: To display error details in HTTP response ";
$error .= 'set "displayErrorDetails" to true in the ErrorHandler constructor.';
}
$this->logError($error);
}
/**
* Wraps the error_log function so that this can be easily tested
*/
protected function logError(string $error): void
{
$this->logger->error($error);
}
/**
* Returns a default logger implementation.
*/
protected function getDefaultLogger(): LoggerInterface
{
return new Logger();
}
protected function respond(): ResponseInterface
{
$response = $this->responseFactory->createResponse($this->statusCode);
if ($this->contentType !== null && array_key_exists($this->contentType, $this->errorRenderers)) {
$response = $response->withHeader('Content-type', $this->contentType);
} else {
$response = $response->withHeader('Content-type', $this->defaultErrorRendererContentType);
}
if ($this->exception instanceof HttpMethodNotAllowedException) {
$allowedMethods = implode(', ', $this->exception->getAllowedMethods());
$response = $response->withHeader('Allow', $allowedMethods);
}
$renderer = $this->determineRenderer();
$body = call_user_func($renderer, $this->exception, $this->displayErrorDetails);
if ($body !== false) {
/** @var string $body */
$response->getBody()->write($body);
}
return $response;
}
}
================================================
FILE: Slim/Handlers/Strategies/RequestHandler.php
================================================
<?php
/**
* Slim Framework (https://slimframework.com)
*
* @license https://github.com/slimphp/Slim/blob/4.x/LICENSE.md (MIT License)
*/
declare(strict_types=1);
namespace Slim\Handlers\Strategies;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Slim\Interfaces\RequestHandlerInvocationStrategyInterface;
/**
* PSR-15 RequestHandler invocation strategy
*/
class RequestHandler implements RequestHandlerInvocationStrategyInterface
{
protected bool $appendRouteArgumentsToRequestAttributes;
public function __construct(bool $appendRouteArgumentsToRequestAttributes = false)
{
$this->appendRouteArgumentsToRequestAttributes = $appendRouteArgumentsToRequestAttributes;
}
/**
* Invoke a route callable that implements RequestHandlerInterface
*
* @param array<string, string> $routeArguments
*/
public function __invoke(
callable $callable,
ServerRequestInterface $request,
ResponseInterface $response,
array $routeArguments
): ResponseInterface {
if ($this->appendRouteArgumentsToRequestAttributes) {
foreach ($routeArguments as $k => $v) {
$request = $request->withAttribute($k, $v);
}
}
/** @var ResponseInterface */
return $callable($request);
}
}
================================================
FILE: Slim/Handlers/Strategies/RequestResponse.php
================================================
<?php
/**
* Slim Framework (https://slimframework.com)
*
* @license https://github.com/slimphp/Slim/blob/4.x/LICENSE.md (MIT License)
*/
declare(strict_types=1);
namespace Slim\Handlers\Strategies;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Slim\Interfaces\InvocationStrategyInterface;
/**
* Default route callback strategy with route parameters as an array of arguments.
*/
class RequestResponse implements InvocationStrategyInterface
{
/**
* Invoke a route callable with request, response, and all route parameters
* as an array of arguments.
*
* @param array<string, string> $routeArguments
*/
public function __invoke(
callable $callable,
ServerRequestInterface $request,
ResponseInterface $response,
array $routeArguments
): ResponseInterface {
foreach ($routeArguments as $k => $v) {
$request = $request->withAttribute($k, $v);
}
/** @var ResponseInterface */
return $callable($request, $response, $routeArguments);
}
}
================================================
FILE: Slim/Handlers/Strategies/RequestResponseArgs.php
================================================
<?php
/**
* Slim Framework (https://slimframework.com)
*
* @license https://github.com/slimphp/Slim/blob/4.x/LICENSE.md (MIT License)
*/
declare(strict_types=1);
namespace Slim\Handlers\Strategies;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Slim\Interfaces\InvocationStrategyInterface;
use function array_values;
/**
* Route callback strategy with route parameters as individual arguments.
* @api
*/
class RequestResponseArgs implements InvocationStrategyInterface
{
/**
* Invoke a route callable with request, response and all route parameters
* as individual arguments.
*
* @param array<string, string> $routeArguments
*/
public function __invoke(
callable $callable,
ServerRequestInterface $request,
ResponseInterface $response,
array $routeArguments
): ResponseInterface {
/** @var ResponseInterface */
return $callable($request, $response, ...array_values($routeArguments));
}
}
================================================
FILE: Slim/Handlers/Strategies/RequestResponseNamedArgs.php
================================================
<?php
/**
* Slim Framework (https://slimframework.com)
*
* @license https://github.com/slimphp/Slim/blob/4.x/LICENSE.md (MIT License)
*/
declare(strict_types=1);
namespace Slim\Handlers\Strategies;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Slim\Interfaces\InvocationStrategyInterface;
use RuntimeException;
/**
* Route callback strategy with route parameters as individual arguments.
* @api
*/
class RequestResponseNamedArgs implements InvocationStrategyInterface
{
/**
* Invoke a route callable with request, response and all route parameters
* as individual arguments.
*
* @param array<string, string> $routeArguments
*/
public function __invoke(
callable $callable,
ServerRequestInterface $request,
ResponseInterface $response,
array $routeArguments
): ResponseInterface {
/** @var ResponseInterface */
return $callable($request, $response, ...$routeArguments);
}
}
================================================
FILE: Slim/Interfaces/AdvancedCallableResolverInterface.php
================================================
<?php
/**
* Slim Framework (https://slimframework.com)
*
* @license https://github.com/slimphp/Slim/blob/4.x/LICENSE.md (MIT License)
*/
declare(strict_types=1);
namespace Slim\Interfaces;
interface AdvancedCallableResolverInterface extends CallableResolverInterface
{
/**
* Resolve $toResolve into a callable
*
* @param callable|array{class-string, string}|string $toResolve
*/
public function resolveRoute($toResolve): callable;
/**
* Resolve $toResolve into a callable
*
* @param callable|array{class-string, string}|string $toResolve
*/
public function resolveMiddleware($toResolve): callable;
}
================================================
FILE: Slim/Interfaces/CallableResolverInterface.php
================================================
<?php
/**
* Slim Framework (https://slimframework.com)
*
* @license https://github.com/slimphp/Slim/blob/4.x/LICENSE.md (MIT License)
*/
declare(strict_types=1);
namespace Slim\Interfaces;
interface CallableResolverInterface
{
/**
* Resolve $toResolve into a callable
*
* @param callable|array{class-string, string}|string $toResolve
*/
public function resolve($toResolve): callable;
}
================================================
FILE: Slim/Interfaces/DispatcherInterface.php
================================================
<?php
/**
* Slim Framework (https://slimframework.com)
*
* @license https://github.com/slimphp/Slim/blob/4.x/LICENSE.md (MIT License)
*/
declare(strict_types=1);
namespace Slim\Interfaces;
use Slim\Routing\RoutingResults;
interface DispatcherInterface
{
/**
* Get routing results for a given request method and uri
*/
public function dispatch(string $method, string $uri): RoutingResults;
/**
* Get allowed methods for a given uri
*
* @return string[]
*/
public function getAllowedMethods(string $uri): array;
}
================================================
FILE: Slim/Interfaces/ErrorHandlerInterface.php
================================================
<?php
/**
* Slim Framework (https://slimframework.com)
*
* @license https://github.com/slimphp/Slim/blob/4.x/LICENSE.md (MIT License)
*/
declare(strict_types=1);
namespace Slim\Interfaces;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Throwable;
interface ErrorHandlerInterface
{
public function __invoke(
ServerRequestInterface $request,
Throwable $exception,
bool $displayErrorDetails,
bool $logErrors,
bool $logErrorDetails
): ResponseInterface;
}
================================================
FILE: Slim/Interfaces/ErrorRendererInterface.php
================================================
<?php
/**
* Slim Framework (https://slimframework.com)
*
* @license https://github.com/slimphp/Slim/blob/4.x/LICENSE.md (MIT License)
*/
declare(strict_types=1);
namespace Slim\Interfaces;
use Throwable;
interface ErrorRendererInterface
{
public function __invoke(Throwable $exception, bool $displayErrorDetails): string;
}
================================================
FILE: Slim/Interfaces/InvocationStrategyInterface.php
================================================
<?php
/**
* Slim Framework (https://slimframework.com)
*
* @license https://github.com/slimphp/Slim/blob/4.x/LICENSE.md (MIT License)
*/
declare(strict_types=1);
namespace Slim\Interfaces;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
/**
* Defines a contract for invoking a route callable.
*/
interface InvocationStrategyInterface
{
/**
* Invoke a route callable.
*
* @param callable $callable The callable to invoke using the strategy.
* @param ServerRequestInterface $request The request object.
* @param ResponseInterface $response The response object.
* @param array<string, string> $routeArguments The route's placeholder arguments
*
* @return ResponseInterface The response from the callable.
*/
public function __invoke(
callable $callable,
ServerRequestInterface $request,
ResponseInterface $response,
array $routeArguments
): ResponseInterface;
}
================================================
FILE: Slim/Interfaces/MiddlewareDispatcherInterface.php
================================================
<?php
/**
* Slim Framework (https://slimframework.com)
*
* @license https://github.com/slimphp/Slim/blob/4.x/LICENSE.md (MIT License)
*/
declare(strict_types=1);
namespace Slim\Interfaces;
use Psr\Http\Server\MiddlewareInterface;
use Psr\Http\Server\RequestHandlerInterface;
/** @api */
interface MiddlewareDispatcherInterface extends RequestHandlerInterface
{
/**
* Add a new middleware to the stack
*
* Middleware are organized as a stack. That means middleware
* that have been added before will be executed after the newly
* added one (last in, first out).
*
* @param MiddlewareInterface|string|callable $middleware
*/
public function add($middleware): self;
/**
* Add a new middleware to the stack
*
* Middleware are organized as a stack. That means middleware
* that have been added before will be executed after the newly
* added one (last in, first out).
*/
public function addMiddleware(MiddlewareInterface $middleware): self;
/**
* Seed the middleware stack with the inner request handler
*/
public function seedMiddlewareStack(RequestHandlerInterface $kernel): void;
}
================================================
FILE: Slim/Interfaces/Psr17FactoryInterface.php
================================================
<?php
/**
* Slim Framework (https://slimframework.com)
*
* @license https://github.com/slimphp/Slim/blob/4.x/LICENSE.md (MIT License)
*/
declare(strict_types=1);
namespace Slim\Interfaces;
use Psr\Http\Message\ResponseFactoryInterface;
use Psr\Http\Message\StreamFactoryInterface;
use RuntimeException;
interface Psr17FactoryInterface
{
/**
* @throws RuntimeException when the factory could not be instantiated
*/
public static function getResponseFactory(): ResponseFactoryInterface;
/**
* @throws RuntimeException when the factory could not be instantiated
*/
public static function getStreamFactory(): StreamFactoryInterface;
/**
* @throws RuntimeException when the factory could not be instantiated
*/
public static function getServerRequestCreator(): ServerRequestCreatorInterface;
/**
* Is the PSR-17 ResponseFactory available
*/
public static function isResponseFactoryAvailable(): bool;
/**
* Is the PSR-17 StreamFactory available
*/
public static function isStreamFactoryAvailable(): bool;
/**
* Is the ServerRequest creator available
*/
public static function isServerRequestCreatorAvailable(): bool;
}
================================================
FILE: Slim/Interfaces/Psr17FactoryProviderInterface.php
================================================
<?php
/**
* Slim Framework (https://slimframework.com)
*
* @license https://github.com/slimphp/Slim/blob/4.x/LICENSE.md (MIT License)
*/
declare(strict_types=1);
namespace Slim\Interfaces;
/** @api */
interface Psr17FactoryProviderInterface
{
/**
* @return string[]
*/
public static function getFactories(): array;
/**
* @param string[] $factories
*/
public static function setFactories(array $factories): void;
public static function addFactory(string $factory): void;
}
================================================
FILE: Slim/Interfaces/RequestHandlerInvocationStrategyInterface.php
================================================
<?php
/**
* Slim Framework (https://slimframework.com)
*
* @license https://github.com/slimphp/Slim/blob/4.x/LICENSE.md (MIT License)
*/
declare(strict_types=1);
namespace Slim\Interfaces;
interface RequestHandlerInvocationStrategyInterface extends InvocationStrategyInterface
{
}
================================================
FILE: Slim/Interfaces/RouteCollectorInterface.php
================================================
<?php
/**
* Slim Framework (https://slimframework.com)
*
* @license https://github.com/slimphp/Slim/blob/4.x/LICENSE.md (MIT License)
*/
declare(strict_types=1);
namespace Slim\Interfaces;
use InvalidArgumentException;
use RuntimeException;
/** @api */
interface RouteCollectorInterface
{
/**
* Get the route parser
*/
public function getRouteParser(): RouteParserInterface;
/**
* Get default route invocation strategy
*/
public function getDefaultInvocationStrategy(): InvocationStrategyInterface;
/**
* Set default route invocation strategy
*/
public function setDefaultInvocationStrategy(InvocationStrategyInterface $strategy): RouteCollectorInterface;
/**
* Get path to FastRoute cache file
*/
public function getCacheFile(): ?string;
/**
* Set path to FastRoute cache file
*
* @throws InvalidArgumentException
* @throws RuntimeException
*/
public function setCacheFile(string $cacheFile): RouteCollectorInterface;
/**
* Get the base path used in pathFor()
*/
public function getBasePath(): string;
/**
* Set the base path used in pathFor()
*/
public function setBasePath(string $basePath): RouteCollectorInterface;
/**
* Get route objects
*
* @return RouteInterface[]
*/
public function getRoutes(): array;
/**
* Get named route object
*
* @param string $name Route name
*
* @throws RuntimeException If named route does not exist
*/
public function getNamedRoute(string $name): RouteInterface;
/**
* Remove named route
*
* @param string $name Route name
*
* @throws RuntimeException If named route does not exist
*/
public function removeNamedRoute(string $name): RouteCollectorInterface;
/**
* Lookup a route via the route's unique identifier
*
* @throws RuntimeException If route of identifier does not exist
*/
public function lookupRoute(string $identifier): RouteInterface;
/**
* Add route group
* @param string|callable $callable
*/
public function group(string $pattern, $callable): RouteGroupInterface;
/**
* Add route
*
* @param string[] $methods Array of HTTP methods
* @param string $pattern The route pattern
* @param callable|array{class-string, string}|string $handler The route callable
*/
public function map(array $methods, string $pattern, $handler): RouteInterface;
}
================================================
FILE: Slim/Interfaces/RouteCollectorProxyInterface.php
================================================
<?php
/**
* Slim Framework (https://slimframework.com)
*
* @license https://github.com/slimphp/Slim/blob/4.x/LICENSE.md (MIT License)
*/
declare(strict_types=1);
namespace Slim\Interfaces;
use Psr\Container\ContainerInterface;
use Psr\Http\Message\ResponseFactoryInterface;
use Psr\Http\Message\UriInterface;
/**
* @api
* @template TContainerInterface of (ContainerInterface|null)
*/
interface RouteCollectorProxyInterface
{
public function getResponseFactory(): ResponseFactoryInterface;
public function getCallableResolver(): CallableResolverInterface;
/**
* @return TContainerInterface
*/
public function getContainer(): ?ContainerInterface;
public function getRouteCollector(): RouteCollectorInterface;
/**
* Get the RouteCollectorProxy's base path
*/
public function getBasePath(): string;
/**
* Set the RouteCollectorProxy's base path
* @return RouteCollectorProxyInterface<TContainerInterface>
*/
public function setBasePath(string $basePath): RouteCollectorProxyInterface;
/**
* Add GET route
*
* @param string $pattern The route URI pattern
* @param callable|array{class-string, string}|string $callable The route callback routine
*/
public function get(string $pattern, $callable): RouteInterface;
/**
* Add POST route
*
* @param string $pattern The route URI pattern
* @param callable|array{class-string, string}|string $callable The route callback routine
*/
public function post(string $pattern, $callable): RouteInterface;
/**
* Add PUT route
*
* @param string $pattern The route URI pattern
* @param callable|array{class-string, string}|string $callable The route callback routine
*/
public function put(string $pattern, $callable): RouteInterface;
/**
* Add PATCH route
*
* @param string $pattern The route URI pattern
* @param callable|array{class-string, string}|string $callable The route callback routine
*/
public function patch(string $pattern, $callable): RouteInterface;
/**
* Add DELETE route
*
* @param string $pattern The route URI pattern
* @param callable|array{class-string, string}|string $callable The route callback routine
*/
public function delete(string $pattern, $callable): RouteInterface;
/**
* Add OPTIONS route
*
* @param string $pattern The route URI pattern
* @param callable|array{class-string, string}|string $callable The route callback routine
*/
public function options(string $pattern, $callable): RouteInterface;
/**
* Add route for any HTTP method
*
* @param string $pattern The route URI pattern
* @param callable|array{class-string, string}|string $callable The route callback routine
*/
public function any(string $pattern, $callable): RouteInterface;
/**
* Add route with multiple methods
*
* @param string[] $methods Numeric array of HTTP method names
* @param string $pattern The route URI pattern
* @param callable|array{class-string, string}|string $callable The route callback routine
*/
public function map(array $methods, string $pattern, $callable): RouteInterface;
/**
* Route Groups
*
* This method accepts a route pattern and a callback. All route
* declarations in the callback will be prepended by the group(s)
* that it is in.
* @param string|callable $callable
*/
public function group(string $pattern, $callable): RouteGroupInterface;
/**
* Add a route that sends an HTTP redirect
*
* @param string|UriInterface $to
*/
public function redirect(string $from, $to, int $status = 302): RouteInterface;
}
================================================
FILE: Slim/Interfaces/RouteGroupInterface.php
================================================
<?php
/**
* Slim Framework (https://slimframework.com)
*
* @license https://github.com/slimphp/Slim/blob/4.x/LICENSE.md (MIT License)
*/
declare(strict_types=1);
namespace Slim\Interfaces;
use Psr\Http\Server\MiddlewareInterface;
use Slim\MiddlewareDispatcher;
/** @api */
interface RouteGroupInterface
{
public function collectRoutes(): RouteGroupInterface;
/**
* Add middleware to the route group
*
* @param MiddlewareInterface|string|callable $middleware
*/
public function add($middleware): RouteGroupInterface;
/**
* Add middleware to the route group
*/
public function addMiddleware(MiddlewareInterface $middleware): RouteGroupInterface;
/**
* Append the group's middleware to the MiddlewareDispatcher
* @param MiddlewareDispatcher<\Psr\Container\ContainerInterface|null> $dispatcher
*/
public function appendMiddlewareToDispatcher(MiddlewareDispatcher $dispatcher): RouteGroupInterface;
/**
* Get the RouteGroup's pattern
*/
public function getPattern(): string;
}
================================================
FILE: Slim/Interfaces/RouteInterface.php
================================================
<?php
/**
* Slim Framework (https://slimframework.com)
*
* @license https://github.com/slimphp/Slim/blob/4.x/LICENSE.md (MIT License)
*/
declare(strict_types=1);
namespace Slim\Interfaces;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Server\MiddlewareInterface;
/** @api */
interface RouteInterface
{
/**
* Get route invocation strategy
*/
public function getInvocationStrategy(): InvocationStrategyInterface;
/**
* Set route invocation strategy
*/
public function setInvocationStrategy(InvocationStrategyInterface $invocationStrategy): RouteInterface;
/**
* Get route methods
*
* @return string[]
*/
public function getMethods(): array;
/**
* Get route pattern
*/
public function getPattern(): string;
/**
* Set route pattern
*/
public function setPattern(string $pattern): RouteInterface;
/**
* Get route callable
*
* @return callable|array{class-string, string}|string
*/
public function getCallable();
/**
* Set route callable
*
* @param callable|array{class-string, string}|string $callable
*/
public function setCallable($callable): RouteInterface;
/**
* Get route name
*/
public function getName(): ?string;
/**
* Set route name
*
* @return static
*/
public function setName(string $name): RouteInterface;
/**
* Get the route's unique identifier
*/
public function getIdentifier(): string;
/**
* Retrieve a specific route argument
*/
public function getArgument(string $name, ?string $default = null): ?string;
/**
* Get route arguments
*
* @return array<string, string>
*/
public function getArguments(): array;
/**
* Set a route argument
*
* @deprecated 4.14.1 Use a middleware for custom route arguments now.
*/
public function setArgument(string $name, string $value): RouteInterface;
/**
* Replace route arguments
*
* @param array<string, string> $arguments
*
* @deprecated 4.14.1 Use a middleware for custom route arguments now.
*/
public function setArguments(array $arguments): self;
/**
* @param MiddlewareInterface|string|callable $middleware
*/
public function add($middleware): self;
public function addMiddleware(MiddlewareInterface $middleware): self;
/**
* Prepare the route for use
*
* @param array<string, string> $arguments
*/
public function prepare(array $arguments): self;
/**
* Run route
*
* This method traverses the middleware stack, including the route's callable
* and captures the resultant HTTP response object. It then sends the response
* back to the Application.
*/
public function run(ServerRequestInterface $request): ResponseInterface;
}
================================================
FILE: Slim/Interfaces/RouteParserInterface.php
================================================
<?php
/**
* Slim Framework (https://slimframework.com)
*
* @license https://github.com/slimphp/Slim/blob/4.x/LICENSE.md (MIT License)
*/
declare(strict_types=1);
namespace Slim\Interfaces;
use InvalidArgumentException;
use Psr\Http\Message\UriInterface;
use RuntimeException;
/** @api */
interface RouteParserInterface
{
/**
* Build the path for a named route excluding the base path
*
* @param string $routeName Route name
* @param array<string, string> $data Named argument replacement data
* @param array<string, string | array<array-key, string>> $queryParams Optional query string parameters
*
* @throws RuntimeException If named route does not exist
* @throws InvalidArgumentException If required data not provided
*/
public function relativeUrlFor(string $routeName, array $data = [], array $queryParams = []): string;
/**
* Build the path for a named route including the base path
*
* @param string $routeName Route name
* @param array<string, string> $data Named argument replacement data
* @param array<string, string | array<array-key, string>> $queryParams Optional query string parameters
*
* @throws RuntimeException If named route does not exist
* @throws InvalidArgumentException If required data not provided
*/
public function urlFor(string $routeName, array $data = [], array $queryParams = []): string;
/**
* Get fully qualified URL for named route
*
* @param UriInterface $uri
* @param string $routeName Route name
* @param array<string, string> $data Named argument replacement data
* @param array<string, string | array<array-key, string>> $queryParams Optional query string parameters
*/
public function fullUrlFor(UriInterface $uri, string $routeName, array $data = [], array $queryParams = []): string;
}
================================================
FILE: Slim/Interfaces/RouteResolverInterface.php
================================================
<?php
declare(strict_types=1);
namespace Slim\Interfaces;
use Slim\Routing\RoutingResults;
interface RouteResolverInterface
{
/**
* @param string $uri Should be ServerRequestInterface::getUri()->getPath()
*/
public function computeRoutingResults(string $uri, string $method): RoutingResults;
public function resolveRoute(string $identifier): RouteInterface;
}
================================================
FILE: Slim/Interfaces/ServerRequestCreatorInterface.php
================================================
<?php
/**
* Slim Framework (https://slimframework.com)
*
* @license https://github.com/slimphp/Slim/blob/4.x/LICENSE.md (MIT License)
*/
declare(strict_types=1);
namespace Slim\Interfaces;
use Psr\Http\Message\ServerRequestInterface;
interface ServerRequestCreatorInterface
{
public function createServerRequestFromGlobals(): ServerRequestInterface;
}
================================================
FILE: Slim/Logger.php
================================================
<?php
/**
* Slim Framework (https://slimframework.com)
*
* @license https://github.com/slimphp/Slim/blob/4.x/LICENSE.md (MIT License)
*/
declare(strict_types=1);
namespace Slim;
use Psr\Log\AbstractLogger;
use Psr\Log\InvalidArgumentException;
use Stringable;
use function error_log;
class Logger extends AbstractLogger
{
/**
* @param mixed $level
* @param string|Stringable $message
* @param array<mixed> $context
*
* @throws InvalidArgumentException
*/
public function log($level, $message, array $context = []): void
{
error_log((string) $message);
}
}
================================================
FILE: Slim/Middleware/BodyParsingMiddleware.php
================================================
<?php
/**
* Slim Framework (https://slimframework.com)
*
* @license https://github.com/slimphp/Slim/blob/4.x/LICENSE.md (MIT License)
*/
declare(strict_types=1);
namespace Slim\Middleware;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Server\MiddlewareInterface;
use Psr\Http\Server\RequestHandlerInterface;
use RuntimeException;
use function count;
use function explode;
use function is_array;
use function is_object;
use function is_string;
use function json_decode;
use function libxml_clear_errors;
use function libxml_disable_entity_loader;
use function libxml_use_internal_errors;
use function parse_str;
use function simplexml_load_string;
use function strtolower;
use function trim;
use const LIBXML_VERSION;
/** @api */
class BodyParsingMiddleware implements MiddlewareInterface
{
/**
* @var callable[]
*/
protected array $bodyParsers;
/**
* @param callable[] $bodyParsers list of body parsers as an associative array of mediaType => callable
*/
public function __construct(array $bodyParsers = [])
{
$this->registerDefaultBodyParsers();
foreach ($bodyParsers as $mediaType => $parser) {
$this->registerBodyParser($mediaType, $parser);
}
}
public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
{
$parsedBody = $request->getParsedBody();
if (empty($parsedBody)) {
$parsedBody = $this->parseBody($request);
$request = $request->withParsedBody($parsedBody);
}
return $handler->handle($request);
}
/**
* @param string $mediaType A HTTP media type (excluding content-type params).
* @param callable $callable A callable that returns parsed contents for media type.
*/
public function registerBodyParser(string $mediaType, callable $callable): self
{
$this->bodyParsers[$mediaType] = $callable;
return $this;
}
/**
* @param string $mediaType A HTTP media type (excluding content-type params).
*/
public function hasBodyParser(string $mediaType): bool
{
return isset($this->bodyParsers[$mediaType]);
}
/**
* @param string $mediaType A HTTP media type (excluding content-type params).
* @throws RuntimeException
*/
public function getBodyParser(string $mediaType): callable
{
if (!isset($this->bodyParsers[$mediaType])) {
throw new RuntimeException('No parser for type ' . $mediaType);
}
return $this->bodyParsers[$mediaType];
}
protected function registerDefaultBodyParsers(): void
{
$this->registerBodyParser('application/json', static function ($input) {
/** @var string $input */
$result = json_decode($input, true);
if (!is_array($result)) {
return null;
}
return $result;
});
$this->registerBodyParser('application/x-www-form-urlencoded', static function ($input) {
/** @var string $input */
parse_str($input, $data);
return $data;
});
$xmlCallable = static function ($input) {
/** @var string $input */
$backup = self::disableXmlEntityLoader(true);
$backup_errors = libxml_use_internal_errors(true);
$result = simplexml_load_string($input);
self::disableXmlEntityLoader($backup);
libxml_clear_errors();
libxml_use_internal_errors($backup_errors);
if ($result === false) {
return null;
}
return $result;
};
$this->registerBodyParser('application/xml', $xmlCallable);
$this->registerBodyParser('text/xml', $xmlCallable);
}
/**
* @return null|array<mixed>|object
*/
protected function parseBody(ServerRequestInterface $request)
{
$mediaType = $this->getMediaType($request);
if ($mediaType === null) {
return null;
}
// Check if this specific media type has a parser registered first
if (!isset($this->bodyParsers[$mediaType])) {
// If not, look for a media type with a structured syntax suffix (RFC 6839)
$parts = explode('+', $mediaType);
if (count($parts) >= 2) {
$mediaType = 'application/' . $parts[count($parts) - 1];
}
}
if (isset($this->bodyParsers[$mediaType])) {
$body = (string)$request->getBody();
$parsed = $this->bodyParsers[$mediaType]($body);
if ($parsed !== null && !is_object($parsed) && !is_array($parsed)) {
throw new RuntimeException(
'Request body media type parser return value must be an array, an object, or null'
);
}
return $parsed;
}
return null;
}
/**
* @return string|null The serverRequest media type, minus content-type params
*/
protected function getMediaType(ServerRequestInterface $request): ?string
{
$contentType = $request->getHeader('Content-Type')[0] ?? null;
if (is_string($contentType) && trim($contentType) !== '') {
$contentTypeParts = explode(';', $contentType);
return strtolower(trim($contentTypeParts[0]));
}
return null;
}
protected static function disableXmlEntityLoader(bool $disable): bool
{
if (LIBXML_VERSION >= 20900) {
// libxml >= 2.9.0 disables entity loading by default, so it is
// safe to skip the real call (deprecated in PHP 8).
return true;
}
// @codeCoverageIgnoreStart
return libxml_disable_entity_loader($disable);
// @codeCoverageIgnoreEnd
}
}
================================================
FILE: Slim/Middleware/ContentLengthMiddleware.php
================================================
<?php
/**
* Slim Framework (https://slimframework.com)
*
* @license https://github.com/slimphp/Slim/blob/4.x/LICENSE.md (MIT License)
*/
declare(strict_types=1);
namespace Slim\Middleware;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Server\MiddlewareInterface;
use Psr\Http\Server\RequestHandlerInterface;
/** @api */
class ContentLengthMiddleware implements MiddlewareInterface
{
public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
{
$response = $handler->handle($request);
// Add Content-Length header if not already added
$size = $response->getBody()->getSize();
if ($size !== null && !$response->hasHeader('Content-Length')) {
$response = $response->withHeader('Content-Length', (string) $size);
}
return $response;
}
}
================================================
FILE: Slim/Middleware/ErrorMiddleware.php
================================================
<?php
/**
* Slim Framework (https://slimframework.com)
*
* @license https://github.com/slimphp/Slim/blob/4.x/LICENSE.md (MIT License)
*/
declare(strict_types=1);
namespace Slim\Middleware;
use Psr\Http\Message\ResponseFactoryInterface;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Server\MiddlewareInterface;
use Psr\Http\Server\RequestHandlerInterface;
use Psr\Log\LoggerInterface;
use Slim\Exception\HttpException;
use Slim\Handlers\ErrorHandler;
use Slim\Interfaces\CallableResolverInterface;
use Slim\Interfaces\ErrorHandlerInterface;
use Throwable;
use function get_class;
use function is_subclass_of;
/** @api */
class ErrorMiddleware implements MiddlewareInterface
{
protected CallableResolverInterface $callableResolver;
protected ResponseFactoryInterface $responseFactory;
protected bool $displayErrorDetails;
protected bool $logErrors;
protected bool $logErrorDetails;
protected ?LoggerInterface $logger = null;
/**
* @var ErrorHandlerInterface[]|callable[]|string[]
*/
protected array $handlers = [];
/**
* @var ErrorHandlerInterface[]|callable[]|string[]
*/
protected array $subClassHandlers = [];
/**
* @var ErrorHandlerInterface|callable|string|null
*/
protected $defaultErrorHandler;
public function __construct(
CallableResolverInterface $callableResolver,
ResponseFactoryInterface $responseFactory,
bool $displayErrorDetails,
bool $logErrors,
bool $logErrorDetails,
?LoggerInterface $logger = null
) {
$this->callableResolver = $callableResolver;
$this->responseFactory = $responseFactory;
$this->displayErrorDetails = $displayErrorDetails;
$this->logErrors = $logErrors;
$this->logErrorDetails = $logErrorDetails;
$this->logger = $logger;
}
public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
{
try {
return $handler->handle($request);
} catch (Throwable $e) {
return $this->handleException($request, $e);
}
}
public function handleException(ServerRequestInterface $request, Throwable $exception): ResponseInterface
{
if ($exception instanceof HttpException) {
$request = $exception->getRequest();
}
$exceptionType = get_class($exception);
$handler = $this->getErrorHandler($exceptionType);
/** @var ResponseInterface */
return $handler($request, $exception, $this->displayErrorDetails, $this->logErrors, $this->logErrorDetails);
}
/**
* Get callable to handle scenarios where an error
* occurs when processing the current request.
*
* @param string $type Exception/Throwable name. ie: RuntimeException::class
* @return callable|ErrorHandler
*/
public function getErrorHandler(string $type)
{
if (isset($this->handlers[$type])) {
return $this->callableResolver->resolve($this->handlers[$type]);
}
if (isset($this->subClassHandlers[$type])) {
return $this->callableResolver->resolve($this->subClassHandlers[$type]);
}
foreach ($this->subClassHandlers as $class => $handler) {
if (is_subclass_of($type, $class)) {
return $this->callableResolver->resolve($handler);
}
}
return $this->getDefaultErrorHandler();
}
/**
* Get default error handler
*
* @return ErrorHandler|callable
*/
public function getDefaultErrorHandler()
{
if ($this->defaultErrorHandler === null) {
$this->defaultErrorHandler = new ErrorHandler(
$this->callableResolver,
$this->responseFactory,
$this->logger
);
}
return $this->callableResolver->resolve($this->defaultErrorHandler);
}
/**
* Set callable as the default Slim application error handler.
*
* The callable signature MUST match the ErrorHandlerInterface
*
* @param string|callable|ErrorHandler $handler
* @see ErrorHandlerInterface
*
* 1. Instance of \Psr\Http\Message\ServerRequestInterface
* 2. Instance of \Throwable
* 3. Boolean $displayErrorDetails
* 4. Boolean $logErrors
* 5. Boolean $logErrorDetails
*
* The callable MUST return an instance of
* \Psr\Http\Message\ResponseInterface.
*
*/
public function setDefaultErrorHandler($handler): self
{
$this->defaultErrorHandler = $handler;
return $this;
}
/**
* Set callable to handle scenarios where an error
* occurs when processing the current request.
*
* The callable signature MUST match the ErrorHandlerInterface
*
* Pass true to $handleSubclasses to make the handler handle all subclasses of
* the type as well. Pass an array of classes to make the same function handle multiple exceptions.
*
* @param string|string[] $typeOrTypes Exception/Throwable name.
* ie: RuntimeException::class or an array of classes
* ie: [HttpNotFoundException::class, HttpMethodNotAllowedException::class]
* @param string|callable|ErrorHandlerInterface $handler
*
* @see ErrorHandlerInterface
*
* 1. Instance of \Psr\Http\Message\ServerRequestInterface
* 2. Instance of \Throwable
* 3. Boolean $displayErrorDetails
* 4. Boolean $logErrors
* 5. Boolean $logErrorDetails
*
* The callable MUST return an instance of
* \Psr\Http\Message\ResponseInterface.
*
*/
public function setErrorHandler($typeOrTypes, $handler, bool $handleSubclasses = false): self
{
if (is_array($typeOrTypes)) {
foreach ($typeOrTypes as $type) {
$this->addErrorHandler($type, $handler, $handleSubclasses);
}
} else {
$this->addErrorHandler($typeOrTypes, $handler, $handleSubclasses);
}
return $this;
}
/**
* Used internally to avoid code repetition when passing multiple exceptions to setErrorHandler().
* @param string|callable|ErrorHandlerInterface $handler
*/
private function addErrorHandler(string $type, $handler, bool $handleSubclasses): void
{
if ($handleSubclasses) {
$this->subClassHandlers[$type] = $handler;
} else {
$this->handlers[$type] = $handler;
}
}
}
================================================
FILE: Slim/Middleware/MethodOverrideMiddleware.php
================================================
<?php
/**
* Slim Framework (https://slimframework.com)
*
* @license https://github.com/slimphp/Slim/blob/4.x/LICENSE.md (MIT License)
*/
declare(strict_types=1);
namespace Slim\Middleware;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Server\MiddlewareInterface;
use Psr\Http\Server\RequestHandlerInterface;
use function is_array;
use function strtoupper;
/** @api */
class MethodOverrideMiddleware implements MiddlewareInterface
{
public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
{
$methodHeader = $request->getHeaderLine('X-Http-Method-Override');
if ($methodHeader) {
$request = $request->withMethod($methodHeader);
} elseif (strtoupper($request->getMethod()) === 'POST') {
$body = $request->getParsedBody();
if (is_array($body) && !empty($body['_METHOD']) && is_string($body['_METHOD'])) {
$request = $request->withMethod($body['_METHOD']);
}
if ($request->getBody()->eof()) {
$request->getBody()->rewind();
}
}
return $handler->handle($request);
}
}
================================================
FILE: Slim/Middleware/OutputBufferingMiddleware.php
================================================
<?php
/**
* Slim Framework (https://slimframework.com)
*
* @license https://github.com/slimphp/Slim/blob/4.x/LICENSE.md (MIT License)
*/
declare(strict_types=1);
namespace Slim\Middleware;
use InvalidArgumentException;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Message\StreamFactoryInterface;
use Psr\Http\Server\MiddlewareInterface;
use Psr\Http\Server\RequestHandlerInterface;
use Throwable;
use function in_array;
use function ob_end_clean;
use function ob_get_clean;
use function ob_start;
/** @api */
class OutputBufferingMiddleware implements MiddlewareInterface
{
public const APPEND = 'append';
public const PREPEND = 'prepend';
protected StreamFactoryInterface $streamFactory;
protected string $style;
/**
* @param string $style Either "append" or "prepend"
*/
public function __construct(StreamFactoryInterface $streamFactory, string $style = 'append')
{
$this->streamFactory = $streamFactory;
$this->style = $style;
if (!in_array($style, [static::APPEND, static::PREPEND], true)) {
throw new InvalidArgumentException("Invalid style `{$style}`. Must be `append` or `prepend`");
}
}
/**
* @throws Throwable
*/
public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
{
try {
ob_start();
$response = $handler->handle($request);
$output = ob_get_clean();
} catch (Throwable $e) {
ob_end_clean();
throw $e;
}
if (!empty($output)) {
if ($this->style === static::PREPEND) {
$body = $this->streamFactory->createStream();
$body->write($output . $response->getBody());
$response = $response->withBody($body);
} elseif ($this->style === static::APPEND && $response->getBody()->isWritable()) {
$response->getBody()->write($output);
}
}
return $response;
}
}
================================================
FILE: Slim/Middleware/RoutingMiddleware.php
================================================
<?php
/**
* Slim Framework (https://slimframework.com)
*
* @license https://github.com/slimphp/Slim/blob/4.x/LICENSE.md (MIT License)
*/
declare(strict_types=1);
namespace Slim\Middleware;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Server\MiddlewareInterface;
use Psr\Http\Server\RequestHandlerInterface;
use RuntimeException;
use Slim\Exception\HttpMethodNotAllowedException;
use Slim\Exception\HttpNotFoundException;
use Slim\Interfaces\RouteParserInterface;
use Slim\Interfaces\RouteResolverInterface;
use Slim\Routing\RouteContext;
use Slim\Routing\RoutingResults;
class RoutingMiddleware implements MiddlewareInterface
{
protected RouteResolverInterface $routeResolver;
protected RouteParserInterface $routeParser;
public function __construct(RouteResolverInterface $routeResolver, RouteParserInterface $routeParser)
{
$this->routeResolver = $routeResolver;
$this->routeParser = $routeParser;
}
/**
* @throws HttpNotFoundException
* @throws HttpMethodNotAllowedException
* @throws RuntimeException
*/
public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
{
$request = $this->performRouting($request);
return $handler->handle($request);
}
/**
* Perform routing
*
* @param ServerRequestInterface $request PSR7 Server Request
*
* @throws HttpNotFoundException
* @throws HttpMethodNotAllowedException
* @throws RuntimeException
*/
public function performRouting(ServerRequestInterface $request): ServerRequestInterface
{
$request = $request->withAttribute(RouteContext::ROUTE_PARSER, $this->routeParser);
$routingResults = $this->resolveRoutingResultsFromRequest($request);
$routeStatus = $routingResults->getRouteStatus();
$request = $request->withAttribute(RouteContext::ROUTING_RESULTS, $routingResults);
switch ($routeStatus) {
case RoutingResults::FOUND:
$routeArguments = $routingResults->getRouteArguments();
$routeIdentifier = $routingResults->getRouteIdentifier() ?? '';
$route = $this->routeResolver
->resolveRoute($routeIdentifier)
->prepare($routeArguments);
return $request->withAttribute(RouteContext::ROUTE, $route);
case RoutingResults::NOT_FOUND:
throw new HttpNotFoundException($request);
case RoutingResults::METHOD_NOT_ALLOWED:
$exception = new HttpMethodNotAllowedException($request);
$exception->setAllowedMethods($routingResults->getAllowedMethods());
throw $exception;
default:
throw new RuntimeException('An unexpected error occurred while performing routing.');
}
}
/**
* Resolves the route from the given request
*/
protected function resolveRoutingResultsFromRequest(ServerRequestInterface $request): RoutingResults
{
return $this->routeResolver->computeRoutingResults(
$request->getUri()->getPath(),
$request->getMethod()
);
}
}
================================================
FILE: Slim/MiddlewareDispatcher.php
================================================
<?php
/**
* Slim Framework (https://slimframework.com)
*
* @license https://github.com/slimphp/Slim/blob/4.x/LICENSE.md (MIT License)
*/
declare(strict_types=1);
namespace Slim;
use Closure;
use Psr\Container\ContainerInterface;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Server\MiddlewareInterface;
use Psr\Http\Server\RequestHandlerInterface;
use RuntimeException;
use Slim\Interfaces\AdvancedCallableResolverInterface;
use Slim\Interfaces\CallableResolverInterface;
use Slim\Interfaces\MiddlewareDispatcherInterface;
use function class_exists;
use function function_exists;
use function is_callable;
use function is_string;
use function preg_match;
use function sprintf;
/**
* @api
* @template TContainerInterface of (ContainerInterface|null)
*/
class MiddlewareDispatcher implements MiddlewareDispatcherInterface
{
/**
* Tip of the middleware call stack
*/
protected RequestHandlerInterface $tip;
protected ?CallableResolverInterface $callableResolver;
/** @var TContainerInterface $container */
protected ?ContainerInterface $container;
/**
* @param TContainerInterface $container
*/
public function __construct(
RequestHandlerInterface $kernel,
?CallableResolverInterface $callableResolver = null,
?ContainerInterface $container = null
) {
$this->seedMiddlewareStack($kernel);
$this->callableResolver = $callableResolver;
$this->container = $container;
}
/**
* {@inheritdoc}
*/
public function seedMiddlewareStack(RequestHandlerInterface $kernel): void
{
$this->tip = $kernel;
}
/**
* Invoke the middleware stack
*/
public function handle(ServerRequestInterface $request): ResponseInterface
{
return $this->tip->handle($request);
}
/**
* Add a new middleware to the stack
*
* Middleware are organized as a stack. That means middleware
* that have been added before will be executed after the newly
* added one (last in, first out).
*
* @param MiddlewareInterface|string|callable $middleware
*/
public function add($middleware): MiddlewareDispatcherInterface
{
if ($middleware instanceof MiddlewareInterface) {
return $this->addMiddleware($middleware);
}
if (is_string($middleware)) {
return $this->addDeferred($middleware);
}
if (is_callable($middleware)) {
return $this->addCallable($middleware);
}
/** @phpstan-ignore-next-line */
throw new RuntimeException(
'A middleware must be an object/class name referencing an implementation of ' .
'MiddlewareInterface or a callable with a matching signature.'
);
}
/**
* Add a new middleware to the stack
*
* Middleware are organized as a stack. That means middleware
* that have been added before will be executed after the newly
* added one (last in, first out).
*/
public function addMiddleware(MiddlewareInterface $middleware): MiddlewareDispatcherInterface
{
$next = $this->tip;
$this->tip = new class ($middleware, $next) implements RequestHandlerInterface {
private MiddlewareInterface $middleware;
private RequestHandlerInterface $next;
public function __construct(MiddlewareInterface $middleware, RequestHandlerInterface $next)
{
$this->middleware = $middleware;
$this->next = $next;
}
public function handle(ServerRequestInterface $request): ResponseInterface
{
return $this->middleware->process($request, $this->next);
}
};
return $this;
}
/**
* Add a new middleware by class name
*
* Middleware are organized as a stack. That means middleware
* that have been added before will be executed after the newly
* added one (last in, first out).
* @return MiddlewareDispatcher<TContainerInterface>
*/
public function addDeferred(string $middleware): self
{
$next = $this->tip;
$this->tip = new class (
$middleware,
$next,
$this->container,
$this->callableResolver
) implements RequestHandlerInterface {
private string $middleware;
private RequestHandlerInterface $next;
private ?ContainerInterface $container;
private ?CallableResolverInterface $callableResolver;
public function __construct(
string $middleware,
RequestHandlerInterface $next,
?ContainerInterface $container = null,
?CallableResolverInterface $callableResolver = null
) {
$this->middleware = $middleware;
$this->next = $next;
$this->container = $container;
$this->callableResolver = $callableResolver;
}
public function handle(ServerRequestInterface $request): ResponseInterface
{
if ($this->callableResolver instanceof AdvancedCallableResolverInterface) {
$callable = $this->callableResolver->resolveMiddleware($this->middleware);
/** @var ResponseInterface */
return $callable($request, $this->next);
}
$callable = null;
if ($this->callableResolver instanceof CallableResolverInterface) {
try {
$callable = $this->callableResolver->resolve($this->middleware);
} catch (RuntimeException $e) {
// Do Nothing
}
}
if (!$callable) {
$resolved = $this->middleware;
$instance = null;
$method = null;
/** @psalm-suppress ArgumentTypeCoercion */
// Check for Slim callable as `class:method`
if (preg_match(CallableResolver::$callablePattern, $resolved, $matches)) {
$resolved = $matches[1];
$method = $matches[2];
}
if ($this->container && $this->container->has($resolved)) {
$instance = $this->container->get($resolved);
if ($instance instanceof MiddlewareInterface) {
return $instance->process($request, $this->next);
}
} elseif (!function_exists($resolved)) {
if (!class_exists($resolved)) {
throw new RuntimeException(sprintf('Middleware %s does not exist', $resolved));
}
$instance = new $resolved($this->container);
}
if ($instance && $instance instanceof MiddlewareInterface) {
return $instance->process($request, $this->next);
}
$callable = $instance ?? $resolved;
if ($instance && $method) {
$callable = [$instance, $method];
}
if ($this->container && $callable instanceof Closure) {
$callable = $callable->bindTo($this->container);
}
}
if (!is_callable($callable)) {
throw new RuntimeException(
sprintf(
'Middleware %s is not resolvable',
$this->middleware
)
);
}
/** @var ResponseInterface */
return $callable($request, $this->next);
}
};
return $this;
}
/**
* Add a (non-standard) callable middleware to the stack
*
* Middleware are organized as a stack. That means middleware
* that have been added before will be executed after the newly
* added one (last in, first out).
* @return MiddlewareDispatcher<TContainerInterface>
*/
public function addCallable(callable $middleware): self
{
$next = $this->tip;
if ($this->container && $middleware instanceof Closure) {
/** @var Closure $middleware */
$middleware = $middleware->bindTo($this->container);
}
$this->tip = new class ($middleware, $next) implements RequestHandlerInterface {
/**
* @var callable
*/
private $middleware;
/**
* @var RequestHandlerInterface
*/
private $next;
public function __construct(callable $middleware, RequestHandlerInterface $next)
{
$this->middleware = $middleware;
$this->next = $next;
}
public function handle(ServerRequestInterface $request): ResponseInterface
{
/** @var ResponseInterface */
return ($this->middleware)($request, $this->next);
}
};
return $this;
}
}
================================================
FILE: Slim/ResponseEmitter.php
================================================
<?php
/**
* Slim Framework (https://slimframework.com)
*
* @license https://github.com/slimphp/Slim/blob/4.x/LICENSE.md (MIT License)
*/
declare(strict_types=1);
namespace Slim;
use Psr\Http\Message\ResponseInterface;
use function connection_status;
use function header;
use function headers_sent;
use function in_array;
use function min;
use function sprintf;
use function strlen;
use function strtolower;
use const CONNECTION_NORMAL;
class ResponseEmitter
{
private int $responseChunkSize;
public function __construct(int $responseChunkSize = 4096)
{
$this->responseChunkSize = $responseChunkSize;
}
/**
* Send the response the client
*/
public function emit(ResponseInterface $response): void
{
$isEmpty = $this->isResponseEmpty($response);
if (headers_sent() === false) {
$this->emitHeaders($response);
// Set the status _after_ the headers, because of PHP's "helpful" behavior with location headers.
// See https://github.com/slimphp/Slim/issues/1730
$this->emitStatusLine($response);
}
if (!$isEmpty) {
$this->emitBody($response);
}
}
/**
* Emit Response Headers
*/
private function emitHeaders(ResponseInterface $response): void
{
foreach ($response->getHeaders() as $name => $values) {
$first = strtolower($name) !== 'set-cookie';
foreach ($values as $value) {
$header = sprintf('%s: %s', $name, $value);
header($header, $first);
$first = false;
}
}
}
/**
* Emit Status Line
*/
private function emitStatusLine(ResponseInterface $response): void
{
$statusLine = sprintf(
'HTTP/%s %s %s',
$response->getProtocolVersion(),
$response->getStatusCode(),
$response->getReasonPhrase()
);
header($statusLine, true, $response->getStatusCode());
}
/**
* Emit Body
*/
private function emitBody(ResponseInterface $response): void
{
$body = $response->getBody();
if ($body->isSeekable()) {
$body->rewind();
}
$amountToRead = (int) $response->getHeaderLine('Content-Length');
if (!$amountToRead) {
$amountToRead = $body->getSize();
}
if ($amountToRead) {
while ($amountToRead > 0 && !$body->eof()) {
$length = min($this->responseChunkSize, $amountToRead);
$data = $body->read($length);
echo $data;
$amountToRead -= strlen($data);
if (connection_status() !== CONNECTION_NORMAL) {
break;
}
}
} else {
while (!$body->eof()) {
echo $body->read($this->responseChunkSize);
if (connection_status() !== CONNECTION_NORMAL) {
break;
}
}
}
}
/**
* Asserts response body is empty or status code is 204, 205 or 304
*/
public function isResponseEmpty(ResponseInterface $response): bool
{
if (in_array($response->getStatusCode(), [204, 205, 304], true)) {
return true;
}
$stream = $response->getBody();
$seekable = $stream->isSeekable();
if ($seekable) {
$stream->rewind();
}
return $seekable ? $stream->read(1) === '' : $stream->eof();
}
}
================================================
FILE: Slim/Routing/Dispatcher.php
================================================
<?php
declare(strict_types=1);
namespace Slim\Routing;
use FastRoute\DataGenerator\GroupCountBased;
use FastRoute\RouteCollector as FastRouteCollector;
use FastRoute\RouteParser\Std;
use Slim\Interfaces\DispatcherInterface;
use Slim\Interfaces\RouteCollectorInterface;
class Dispatcher implements DispatcherInterface
{
private RouteCollectorInterface $routeCollector;
private ?FastRouteDispatcher $dispatcher = null;
public function __construct(RouteCollectorInterface $routeCollector)
{
$this->routeCollector = $routeCollector;
}
protected function createDispatcher(): FastRouteDispatcher
{
if ($this->dispatcher) {
return $this->dispatcher;
}
$routeDefinitionCallback = function (FastRouteCollector $r): void {
$basePath = $this->routeCollector->getBasePath();
foreach ($this->routeCollector->getRoutes() as $route) {
$r->addRoute($route->getMethods(), $basePath . $route->getPattern(), $route->getIdentifier());
}
};
$cacheFile = $this->routeCollector->getCacheFile();
if ($cacheFile) {
/** @var FastRouteDispatcher $dispatcher */
$dispatcher = \FastRoute\cachedDispatcher($routeDefinitionCallback, [
'dataGenerator' => GroupCountBased::class,
'dispatcher' => FastRouteDispatcher::class,
'routeParser' => new Std(),
'cacheFile' => $cacheFile,
]);
} else {
/** @var FastRouteDispatcher $dispatcher */
$dispatcher = \FastRoute\simpleDispatcher($routeDefinitionCallback, [
'dataGenerator' => GroupCountBased::class,
'dispatcher' => FastRouteDispatcher::class,
'routeParser' => new Std(),
]);
}
$this->dispatcher = $dispatcher;
return $this->dispatcher;
}
/**
* {@inheritdoc}
*/
public function dispatch(string $method, string $uri): RoutingResults
{
$dispatcher = $this->createDispatcher();
$results = $dispatcher->dispatch($method, $uri);
return new RoutingResults($this, $method, $uri, $results[0], $results[1], $results[2]);
}
/**
* {@inheritdoc}
*/
public function getAllowedMethods(string $uri): array
{
$dispatcher = $this->createDispatcher();
return $dispatcher->getAllowedMethods($uri);
}
}
================================================
FILE: Slim/Routing/FastRouteDispatcher.php
================================================
<?php
/**
* Slim Framework (https://slimframework.com)
*
* @license https://github.com/slimphp/Slim/blob/4.x/LICENSE.md (MIT License)
*/
declare(strict_types=1);
namespace Slim\Routing;
use FastRoute\Dispatcher\GroupCountBased;
class FastRouteDispatcher extends GroupCountBased
{
/**
* @var string[][]
*/
private array $allowedMethods = [];
/**
* @param string $httpMethod
* @param string $uri
*
* @return array{int, string|null, array<string, string>}
*/
public function dispatch($httpMethod, $uri): array
{
$routingResults = $this->routingResults($httpMethod, $uri);
if ($routingResults[0] === self::FOUND) {
return $routingResults;
}
// For HEAD requests, attempt fallback to GET
if ($httpMethod === 'HEAD') {
$routingResults = $this->routingResults('GET', $uri);
if ($routingResults[0] === self::FOUND) {
return $routingResults;
}
}
// If nothing else matches, try fallback routes
$routingResults = $this->routingResults('*', $uri);
if ($routingResults[0] === self::FOUND) {
return $routingResults;
}
if (!empty($this->getAllowedMethods($uri))) {
return [self::METHOD_NOT_ALLOWED, null, []];
}
return [self::NOT_FOUND, null, []];
}
/**
* @param string $httpMethod
* @param string $uri
*
* @return array{int, string|null, array<string, string>}
*/
private function routingResults(string $httpMethod, string $uri): array
{
if (isset($this->staticRouteMap[$httpMethod][$uri])) {
/** @var string $routeIdentifier */
$routeIdentifier = $this->staticRouteMap[$httpMethod][$uri];
return [self::FOUND, $routeIdentifier, []];
}
if (isset($this->variableRouteData[$httpMethod])) {
/** @var array{0: int, 1?: string, 2?: array<string, string>} $result */
$result = $this->dispatchVariableRoute($this->variableRouteData[$httpMethod], $uri);
if ($result[0] === self::FOUND) {
/** @var array{int, string, array<string, string>} $result */
return [self::FOUND, $result[1], $result[2]];
}
}
return [self::NOT_FOUND, null, []];
}
/**
* @param string $uri
*
* @return string[]
*/
public function getAllowedMethods(string $uri): array
{
if (isset($this->allowedMethods[$uri])) {
return $this->allowedMethods[$uri];
}
$allowedMethods = [];
foreach ($this->staticRouteMap as $method => $uriMap) {
if (isset($uriMap[$uri])) {
$allowedMethods[$method] = true;
}
}
foreach ($this->variableRouteData as $method => $routeData) {
$result = $this->dispatchVariableRoute($routeData, $uri);
if ($result[0] === self::FOUND) {
$allowedMethods[$method] = true;
}
}
return $this->allowedMethods[$uri] = array_keys($allowedMethods);
}
}
================================================
FILE: Slim/Routing/Route.php
================================================
<?php
/**
* Slim Framework (https://slimframework.com)
*
* @license https://github.com/slimphp/Slim/blob/4.x/LICENSE.md (MIT License)
*/
declare(strict_types=1);
namespace Slim\Routing;
use Psr\Container\ContainerInterface;
use Psr\Http\Message\ResponseFactoryInterface;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Server\MiddlewareInterface;
use Psr\Http\Server\RequestHandlerInterface;
use Slim\Handlers\Strategies\RequestHandler;
use Slim\Handlers\Strategies\RequestResponse;
use Slim\Interfaces\AdvancedCallableResolverInterface;
use Slim\Interfaces\CallableResolverInterface;
use Slim\Interfaces\InvocationStrategyInterface;
use Slim\Interfaces\RequestHandlerInvocationStrategyInterface;
use Slim\Interfaces\RouteGroupInterface;
use Slim\Interfaces\RouteInterface;
use Slim\MiddlewareDispatcher;
use function array_key_exists;
use function array_replace;
use function array_reverse;
use function class_implements;
use function in_array;
use function is_array;
/**
* @api
* @template TContainerInterface of (ContainerInterface|null)
*/
class Route implements RouteInterface, RequestHandlerInterface
{
/**
* HTTP methods supported by this route
*
* @var string[]
*/
protected array $methods = [];
/**
* Route identifier
*/
protected string $identifier;
/**
* Route name
*/
protected ?string $name = null;
/**
* Parent route groups
*
* @var RouteGroupInterface[]
*/
protected array $groups;
protected InvocationStrategyInterface $invocationStrategy;
/**
* Route parameters
*
* @var array<string, string>
*/
protected array $arguments = [];
/**
* Route arguments parameters
*
* @var array<string, string>
*/
protected array $savedArguments = [];
/**
* Container
* @var TContainerInterface $container
*/
protected ?ContainerInterface $container = null;
/** @var MiddlewareDispatcher<TContainerInterface> $middlewareDispatcher */
protected MiddlewareDispatcher $middlewareDispatcher;
/**
* Route callable
*
* @var callable|array{class-string, string}|string
*/
protected $callable;
protected CallableResolverInterface $callableResolver;
protected ResponseFactoryInterface $responseFactory;
/**
* Route pattern
*/
protected string $pattern;
protected bool $groupMiddlewareAppended = false;
/**
* @param string[] $methods The route HTTP methods
* @param string $pattern The route pattern
* @param callable|array{class-string, string}|string $callable The route callable
* @param ResponseFactoryInterface $responseFactory
* @param CallableResolverInterface $callableResolver
* @param TContainerInterface $container
* @param InvocationStrategyInterface|null $invocationStrategy
* @param RouteGroupInterface[] $groups The parent route groups
* @param int $identifier The route identifier
*/
public function __construct(
array $methods,
string $pattern,
$callable,
ResponseFactoryInterface $responseFactory,
CallableResolverInterface $callableResolver,
?ContainerInterface $container = null,
?InvocationStrategyInterface $invocationStrategy = null,
array $groups = [],
int $identifier = 0
) {
$this->methods = $methods;
$this->pattern = $pattern;
$this->callable = $callable;
$this->responseFactory = $responseFactory;
$this->callableResolver = $callableResolver;
$this->container = $container;
$this->invocationStrategy = $invocationStrategy ?? new RequestResponse();
$this->groups = $groups;
$this->identifier = 'route' . $identifier;
$this->middlewareDispatcher = new MiddlewareDispatcher($this, $callableResolver, $container);
}
public function getCallableResolver(): CallableResolverInterface
{
return $this->callableResolver;
}
/**
* {@inheritdoc}
*/
public function getInvocationStrategy(): InvocationStrategyInterface
{
return $this->invocationStrategy;
}
/**
* {@inheritdoc}
*/
public function setInvocationStrategy(InvocationStrategyInterface $invocationStrategy): RouteInterface
{
$this->invocationStrategy = $invocationStrategy;
return $this;
}
/**
* {@inheritdoc}
*/
public function getMethods(): array
{
return $this->methods;
}
/**
* {@inheritdoc}
*/
public function getPattern(): string
{
return $this->pattern;
}
/**
* {@inheritdoc}
*/
public function setPattern(string $pattern): RouteInterface
{
$this->pattern = $pattern;
return $this;
}
/**
* {@inheritdoc}
*/
public function getCallable()
{
return $this->callable;
}
/**
* {@inheritdoc}
*/
public function setCallable($callable): RouteInterface
{
$this->callable = $callable;
return $this;
}
/**
* {@inheritdoc}
*/
public function getName(): ?string
{
return $this->name;
}
/**
* {@inheritdoc}
*/
public function setName(string $name): RouteInterface
{
$this->name = $name;
return $this;
}
/**
* {@inheritdoc}
*/
public function getIdentifier(): string
{
return $this->identifier;
}
/**
* {@inheritdoc}
*/
public function getArgument(string $name, ?string $default = null): ?string
{
if (array_key_exists($name, $this->arguments)) {
return $this->arguments[$name];
}
return $default;
}
/**
* {@inheritdoc}
*/
public function getArguments(): array
{
return $this->arguments;
}
/**
* {@inheritdoc}
*/
public function setArguments(array $arguments, bool $includeInSavedArguments = true): RouteInterface
{
if ($includeInSavedArguments) {
$this->savedArguments = $arguments;
}
$this->arguments = $arguments;
return $this;
}
/**
* @return RouteGroupInterface[]
*/
public function getGroups(): array
{
return $this->groups;
}
/**
* {@inheritdoc}
*/
public function add($middleware): RouteInterface
{
$this->middlewareDispatcher->add($middleware);
return $this;
}
/**
* {@inheritdoc}
*/
public function addMiddleware(MiddlewareInterface $middleware): RouteInterface
{
$this->middlewareDispatcher->addMiddleware($middleware);
return $this;
}
/**
* {@inheritdoc}
*/
public function prepare(array $arguments): RouteInterface
{
$this->arguments = array_replace($this->savedArguments, $arguments);
return $this;
}
/**
* {@inheritdoc}
*/
public function setArgument(string $name, string $value, bool $includeInSavedArguments = true): RouteInterface
{
if ($includeInSavedArguments) {
$this->savedArguments[$name] = $value;
}
$this->arguments[$name] = $value;
return $this;
}
/**
* {@inheritdoc}
*/
public function run(ServerRequestInterface $request): ResponseInterface
{
if (!$this->groupMiddlewareAppended) {
$this->appendGroupMiddlewareToRoute();
}
return $this->middlewareDispatcher->handle($request);
}
/**
* @return void
*/
protected function appendGroupMiddlewareToRoute(): void
{
$inner = $this->middlewareDispatcher;
$this->middlewareDispatcher = new MiddlewareDispatcher($inner, $this->callableResolver, $this->container);
foreach (array_reverse($this->groups) as $group) {
$group->appendMiddlewareToDispatcher($this->middlewareDispatcher);
}
$this->groupMiddlewareAppended = true;
}
/**
* {@inheritdoc}
*/
public function handle(ServerRequestInterface $request): ResponseInterface
{
if ($this->callableResolver instanceof AdvancedCallableResolverInterface) {
$callable = $this->callableResolver->resolveRoute($this->callable);
} else {
$callable = $this->callableResolver->resolve($this->callable);
}
$strategy = $this->invocationStrategy;
$strategyImplements = class_implements($strategy);
if (
is_array($callable)
&& $callable[0] instanceof RequestHandlerInterface
&& !in_array(RequestHandlerInvocationStrategyInterface::class, $strategyImplements)
) {
$strategy = new RequestHandler();
}
$response = $this->responseFactory->createResponse();
return $strategy($callable, $request, $response, $this->arguments);
}
}
================================================
FILE: Slim/Routing/RouteCollector.php
================================================
<?php
/**
* Slim Framework (https://slimframework.com)
*
* @license https://github.com/slimphp/Slim/blob/4.x/LICENSE.md (MIT License)
*/
declare(strict_types=1);
namespace Slim\Routing;
use Psr\Container\ContainerInterface;
use Psr\Http\Message\ResponseFactoryInterface;
use RuntimeException;
use Slim\Handlers\Strategies\RequestResponse;
use Slim\Interfaces\CallableResolverInterface;
use Slim\Interfaces\InvocationStrategyInterface;
use Slim\Interfaces\RouteCollectorInterface;
use Slim\Interfaces\RouteCollectorProxyInterface;
use Slim\Interfaces\RouteGroupInterface;
use Slim\Interfaces\RouteInterface;
use Slim\Interfaces\RouteParserInterface;
use function array_pop;
use function dirname;
use function file_exists;
use function is_readable;
use function is_writable;
use function sprintf;
/**
* RouteCollector is used to collect routes and route groups
* as well as generate paths and URLs relative to its environment
* @template TContainerInterface of (ContainerInterface|null)
*/
class RouteCollector implements RouteCollectorInterface
{
protected RouteParserInterface $routeParser;
protected CallableResolverInterface $callableResolver;
protected ?ContainerInterface $container = null;
protected InvocationStrategyInterface $defaultInvocationStrategy;
/**
* Base path used in pathFor()
*/
protected string $basePath = '';
/**
* Path to fast route cache file. Set to null to disable route caching
*/
protected ?string $cacheFile = null;
/**
* Routes
*
* @var RouteInterface[]
*/
protected array $routes = [];
/**
* Routes indexed by name
*
* @var RouteInterface[]
*/
protected array $routesByName = [];
/**
* Route groups
*
* @var RouteGroupInterface[]
*/
protected array $routeGroups = [];
/**
* Route counter incrementer
*/
protected int $routeCounter = 0;
protected ResponseFactoryInterface $responseFactory;
/**
* @param TContainerInterface $container
*/
public function __construct(
ResponseFactoryInterface $responseFactory,
CallableResolverInterface $callableResolver,
?ContainerInterface $container = null,
?InvocationStrategyInterface $defaultInvocationStrategy = null,
?RouteParserInterface $routeParser = null,
?string $cacheFile = null
) {
$this->responseFactory = $responseFactory;
$this->callableResolver = $callableResolver;
$this->container = $container;
$this->defaultInvocationStrategy = $defaultInvocationStrategy ?? new RequestResponse();
$this->routeParser = $routeParser ?? new RouteParser($this);
if ($cacheFile) {
$this->setCacheFile($cacheFile);
}
}
public function getRouteParser(): RouteParserInterface
{
return $this->routeParser;
}
/**
* Get default route invocation strategy
*/
public function getDefaultInvocationStrategy(): InvocationStrategyInterface
{
return $this->defaultInvocationStrategy;
}
public function setDefaultInvocationStrategy(InvocationStrategyInterface $strategy): RouteCollectorInterface
{
$this->defaultInvocationStrategy = $strategy;
return $this;
}
/**
* {@inheritdoc}
*/
public function getCacheFile(): ?string
{
return $this->cacheFile;
}
/**
* {@inheritdoc}
*/
public function setCacheFile(string $cacheFile): RouteCollectorInterface
{
if (file_exists($cacheFile) && !is_readable($cacheFile)) {
throw new RuntimeException(
sprintf('Route collector cache file `%s` is not readable', $cacheFile)
);
}
if (!file_exists($cacheFile) && !is_writable(dirname($cacheFile))) {
throw new RuntimeException(
sprintf('Route collector cache file directory `%s` is not writable', dirname($cacheFile))
);
}
$this->cacheFile = $cacheFile;
return $this;
}
/**
* {@inheritdoc}
*/
public function getBasePath(): string
{
return $this->basePath;
}
/**
* Set the base path used in urlFor()
*/
public function setBasePath(string $basePath): RouteCollectorInterface
{
$this->basePath = $basePath;
return $this;
}
/**
* {@inheritdoc}
*/
public function getRoutes(): array
{
return $this->routes;
}
/**
* {@inheritdoc}
*/
public function removeNamedRoute(string $name): RouteCollectorInterface
{
$route = $this->getNamedRoute($name);
/** @psalm-suppress PossiblyNullArrayOffset */
unset($this->routesByName[$route->getName()], $this->routes[$route->getIdentifier()]);
return $this;
}
/**
* {@inheritdoc}
*/
public function getNamedRoute(string $name): RouteInterface
{
if (isset($this->routesByName[$name])) {
$route = $this->routesByName[$name];
if ($route->getName() === $name) {
return $route;
}
unset($this->routesByName[$name]);
}
foreach ($this->routes as $route) {
if ($name === $route->getName()) {
$this->routesByName[$name] = $route;
return $route;
}
}
throw new RuntimeException('Named route does not exist for name: ' . $name);
}
/**
* {@inheritdoc}
*/
public function lookupRoute(string $identifier): RouteInterface
{
if (!isset($this->routes[$identifier])) {
throw new RuntimeException('Route not found, looks like your route cache is stale.');
}
return $this->routes[$identifier];
}
/**
* {@inheritdoc}
*/
public function group(string $pattern, $callable): RouteGroupInterface
{
$routeGroup = $this->createGroup($pattern, $callable);
$this->routeGroups[] = $routeGroup;
$routeGroup->collectRoutes();
array_pop($this->routeGroups);
return $routeGroup;
}
/**
* @param string|callable $callable
*/
protected function createGroup(string $pattern, $callable): RouteGroupInterface
{
$routeCollectorProxy = $this->createProxy($pattern);
return new RouteGroup($pattern, $callable, $this->callableResolver, $routeCollectorProxy);
}
/**
* @return RouteCollectorProxyInterface<TContainerInterface>
*/
protected function createProxy(string $pattern): RouteCollectorProxyInterface
{
/** @var RouteCollectorProxy<TContainerInterface> */
return new RouteCollectorProxy(
$this->responseFactory,
$this->callableResolver,
$this->container,
$this,
$pattern
);
}
/**
* {@inheritdoc}
*/
public function map(array $methods, string $pattern, $handler): RouteInterface
{
$route = $this->createRoute($methods, $pattern, $handler);
$this->routes[$route->getIdentifier()] = $route;
$routeName = $route->getName();
if ($routeName !== null && !isset($this->routesByName[$routeName])) {
$this->routesByName[$routeName] = $route;
}
$this->routeCounter++;
return $route;
}
/**
* @param string[] $methods
* @param callable|array{class-string, string}|string $callable
*/
protected function createRoute(array $methods, string $pattern, $callable): RouteInterface
{
return new Route(
$methods,
$pattern,
$callable,
$this->responseFactory,
$this->callableResolver,
$this->container,
$this->defaultInvocationStrategy,
$this->routeGroups,
$this->routeCounter
);
}
}
================================================
FILE: Slim/Routing/RouteCollectorProxy.php
================================================
<?php
/**
* Slim Framework (https://slimframework.com)
*
* @license https://github.com/slimphp/Slim/blob/4.x/LICENSE.md (MIT License)
*/
declare(strict_types=1);
namespace Slim\Routing;
use Psr\Container\ContainerInterface;
use Psr\Http\Message\ResponseFactoryInterface;
use Slim\Interfaces\CallableResolverInterface;
use Slim\Interfaces\RouteCollectorInterface;
use Slim\Interfaces\RouteCollectorProxyInterface;
use Slim\Interfaces\RouteGroupInterface;
use Slim\Interfaces\RouteInterface;
/**
* @template TContainerInterface of (ContainerInterface|null)
* @template-implements RouteCollectorProxyInterface<TContainerInterface>
*/
class RouteCollectorProxy implements RouteCollectorProxyInterface
{
protected ResponseFactoryInterface $responseFactory;
protected CallableResolverInterface $callableResolver;
/** @var TContainerInterface */
protected ?ContainerInterface $container = null;
protected RouteCollectorInterface $routeCollector;
protected string $groupPattern;
/**
* @param TContainerInterface $container
*/
public function __construct(
ResponseFactoryInterface $responseFactory,
CallableResolverInterface $callableResolver,
?ContainerInterface $container = null,
?RouteCollectorInterface $routeCollector = null,
string $groupPattern = ''
) {
$this->responseFactory = $responseFactory;
$this->callableResolver = $callableResolver;
$this->container = $container;
$this->routeCollector = $routeCollector ?? new RouteCollector($responseFactory, $callableResolver, $container);
$this->groupPattern = $groupPattern;
}
/**
* {@inheritdoc}
*/
public function getResponseFactory(): ResponseFactoryInterface
{
return $this->responseFactory;
}
/**
* {@inheritdoc}
*/
public function getCallableResolver(): CallableResolverInterface
{
return $this->callableResolver;
}
/**
* {@inheritdoc}
* @return TContainerInterface
*/
public function getContainer(): ?ContainerInterface
{
return $this->container;
}
/**
* {@inheritdoc}
*/
public function getRouteCollector(): RouteCollectorInterface
{
return $this->routeCollector;
}
/**
* {@inheritdoc}
*/
public function getBasePath(): string
{
return $this->routeCollector->getBasePath();
}
/**
* {@inheritdoc}
*/
public function setBasePath(string $basePath): RouteCollectorProxyInterface
{
$this->routeCollector->setBasePath($basePath);
return $this;
}
/**
* {@inheritdoc}
*/
public function get(
gitextract_5dpb6hp9/
├── .coveralls.yml
├── .editorconfig
├── .gitattributes
├── .github/
│ ├── FUNDING.yml
│ ├── dependabot.yml
│ └── workflows/
│ └── tests.yml
├── .gitignore
├── CHANGELOG.md
├── CODE_OF_CONDUCT.md
├── CONTRIBUTING.md
├── LICENSE.md
├── MAINTAINERS.md
├── README.md
├── SECURITY.md
├── Slim/
│ ├── App.php
│ ├── CallableResolver.php
│ ├── Error/
│ │ ├── AbstractErrorRenderer.php
│ │ └── Renderers/
│ │ ├── HtmlErrorRenderer.php
│ │ ├── JsonErrorRenderer.php
│ │ ├── PlainTextErrorRenderer.php
│ │ └── XmlErrorRenderer.php
│ ├── Exception/
│ │ ├── HttpBadRequestException.php
│ │ ├── HttpException.php
│ │ ├── HttpForbiddenException.php
│ │ ├── HttpGoneException.php
│ │ ├── HttpInternalServerErrorException.php
│ │ ├── HttpMethodNotAllowedException.php
│ │ ├── HttpNotFoundException.php
│ │ ├── HttpNotImplementedException.php
│ │ ├── HttpSpecializedException.php
│ │ ├── HttpTooManyRequestsException.php
│ │ └── HttpUnauthorizedException.php
│ ├── Factory/
│ │ ├── AppFactory.php
│ │ ├── Psr17/
│ │ │ ├── GuzzlePsr17Factory.php
│ │ │ ├── HttpSoftPsr17Factory.php
│ │ │ ├── LaminasDiactorosPsr17Factory.php
│ │ │ ├── NyholmPsr17Factory.php
│ │ │ ├── Psr17Factory.php
│ │ │ ├── Psr17FactoryProvider.php
│ │ │ ├── ServerRequestCreator.php
│ │ │ ├── SlimHttpPsr17Factory.php
│ │ │ ├── SlimHttpServerRequestCreator.php
│ │ │ └── SlimPsr17Factory.php
│ │ └── ServerRequestCreatorFactory.php
│ ├── Handlers/
│ │ ├── ErrorHandler.php
│ │ └── Strategies/
│ │ ├── RequestHandler.php
│ │ ├── RequestResponse.php
│ │ ├── RequestResponseArgs.php
│ │ └── RequestResponseNamedArgs.php
│ ├── Interfaces/
│ │ ├── AdvancedCallableResolverInterface.php
│ │ ├── CallableResolverInterface.php
│ │ ├── DispatcherInterface.php
│ │ ├── ErrorHandlerInterface.php
│ │ ├── ErrorRendererInterface.php
│ │ ├── InvocationStrategyInterface.php
│ │ ├── MiddlewareDispatcherInterface.php
│ │ ├── Psr17FactoryInterface.php
│ │ ├── Psr17FactoryProviderInterface.php
│ │ ├── RequestHandlerInvocationStrategyInterface.php
│ │ ├── RouteCollectorInterface.php
│ │ ├── RouteCollectorProxyInterface.php
│ │ ├── RouteGroupInterface.php
│ │ ├── RouteInterface.php
│ │ ├── RouteParserInterface.php
│ │ ├── RouteResolverInterface.php
│ │ └── ServerRequestCreatorInterface.php
│ ├── Logger.php
│ ├── Middleware/
│ │ ├── BodyParsingMiddleware.php
│ │ ├── ContentLengthMiddleware.php
│ │ ├── ErrorMiddleware.php
│ │ ├── MethodOverrideMiddleware.php
│ │ ├── OutputBufferingMiddleware.php
│ │ └── RoutingMiddleware.php
│ ├── MiddlewareDispatcher.php
│ ├── ResponseEmitter.php
│ └── Routing/
│ ├── Dispatcher.php
│ ├── FastRouteDispatcher.php
│ ├── Route.php
│ ├── RouteCollector.php
│ ├── RouteCollectorProxy.php
│ ├── RouteContext.php
│ ├── RouteGroup.php
│ ├── RouteParser.php
│ ├── RouteResolver.php
│ ├── RouteRunner.php
│ └── RoutingResults.php
├── UPGRADING.md
├── composer.json
├── phpcs.xml.dist
├── phpstan.neon.dist
├── phpunit.xml.dist
├── psalm.xml
└── tests/
├── AppTest.php
├── Assets/
│ └── HeaderStack.php
├── CallableResolverTest.php
├── Error/
│ └── AbstractErrorRendererTest.php
├── Exception/
│ ├── HttpExceptionTest.php
│ └── HttpUnauthorizedExceptionTest.php
├── Factory/
│ ├── AppFactoryTest.php
│ ├── Psr17/
│ │ ├── Psr17FactoryProviderTest.php
│ │ ├── Psr17FactoryTest.php
│ │ └── SlimHttpServerRequestCreatorTest.php
│ └── ServerRequestCreatorFactoryTest.php
├── Handlers/
│ ├── ErrorHandlerTest.php
│ └── Strategies/
│ └── RequestResponseNamedArgsTest.php
├── Middleware/
│ ├── BodyParsingMiddlewareTest.php
│ ├── ContentLengthMiddlewareTest.php
│ ├── ErrorMiddlewareTest.php
│ ├── MethodOverrideMiddlewareTest.php
│ ├── OutputBufferingMiddlewareTest.php
│ └── RoutingMiddlewareTest.php
├── MiddlewareDispatcherTest.php
├── Mocks/
│ ├── CallableTest.php
│ ├── InvocationStrategyTest.php
│ ├── InvokableTest.php
│ ├── MiddlewareTest.php
│ ├── MockAction.php
│ ├── MockCustomException.php
│ ├── MockCustomRequestHandlerInvocationStrategy.php
│ ├── MockMiddlewareSlimCallable.php
│ ├── MockMiddlewareWithConstructor.php
│ ├── MockMiddlewareWithoutConstructor.php
│ ├── MockMiddlewareWithoutInterface.php
│ ├── MockPsr17Factory.php
│ ├── MockPsr17FactoryWithoutStreamFactory.php
│ ├── MockRequestHandler.php
│ ├── MockSequenceMiddleware.php
│ ├── MockStream.php
│ ├── RequestHandlerTest.php
│ ├── SlowPokeStream.php
│ └── SmallChunksStream.php
├── Providers/
│ ├── PSR7ObjectProvider.php
│ └── PSR7ObjectProviderInterface.php
├── ResponseEmitterTest.php
├── Routing/
│ ├── DispatcherTest.php
│ ├── FastRouteDispatcherTest.php
│ ├── RouteCollectorProxyTest.php
│ ├── RouteCollectorTest.php
│ ├── RouteContextTest.php
│ ├── RouteParserTest.php
│ ├── RouteResolverTest.php
│ ├── RouteRunnerTest.php
│ └── RouteTest.php
├── TestCase.php
└── bootstrap.php
SYMBOL INDEX (852 symbols across 124 files)
FILE: Slim/App.php
class App (line 39) | class App extends RouteCollectorProxy implements RequestHandlerInterface
method __construct (line 55) | public function __construct(
method getRouteResolver (line 85) | public function getRouteResolver(): RouteResolverInterface
method getMiddlewareDispatcher (line 93) | public function getMiddlewareDispatcher(): MiddlewareDispatcherInterface
method add (line 102) | public function add($middleware): self
method addMiddleware (line 112) | public function addMiddleware(MiddlewareInterface $middleware): self
method addRoutingMiddleware (line 125) | public function addRoutingMiddleware(): RoutingMiddleware
method addErrorMiddleware (line 145) | public function addErrorMiddleware(
method addBodyParsingMiddleware (line 170) | public function addBodyParsingMiddleware(array $bodyParsers = []): Bod...
method run (line 186) | public function run(?ServerRequestInterface $request = null): void
method handle (line 207) | public function handle(ServerRequestInterface $request): ResponseInter...
FILE: Slim/CallableResolver.php
class CallableResolver (line 32) | final class CallableResolver implements AdvancedCallableResolverInterface
method __construct (line 42) | public function __construct(?ContainerInterface $container = null)
method resolve (line 50) | public function resolve($toResolve): callable
method resolveRoute (line 68) | public function resolveRoute($toResolve): callable
method resolveMiddleware (line 76) | public function resolveMiddleware($toResolve): callable
method resolveByPredicate (line 86) | private function resolveByPredicate($toResolve, callable $predicate, s...
method isRoute (line 110) | private function isRoute($toResolve): bool
method isMiddleware (line 118) | private function isMiddleware($toResolve): bool
method resolveSlimNotation (line 128) | private function resolveSlimNotation(string $toResolve): array
method assertCallable (line 157) | private function assertCallable($resolved, $toResolve): callable
method bindToContainer (line 170) | private function bindToContainer(callable $callable): callable
method prepareToResolve (line 187) | private function prepareToResolve($toResolve)
FILE: Slim/Error/AbstractErrorRenderer.php
class AbstractErrorRenderer (line 23) | abstract class AbstractErrorRenderer implements ErrorRendererInterface
method getErrorTitle (line 29) | protected function getErrorTitle(Throwable $exception): string
method getErrorDescription (line 38) | protected function getErrorDescription(Throwable $exception): string
FILE: Slim/Error/Renderers/HtmlErrorRenderer.php
class HtmlErrorRenderer (line 23) | class HtmlErrorRenderer extends AbstractErrorRenderer
method __invoke (line 25) | public function __invoke(Throwable $exception, bool $displayErrorDetai...
method renderExceptionFragment (line 38) | private function renderExceptionFragment(Throwable $exception): string
method renderHtmlBody (line 57) | public function renderHtmlBody(string $title = '', string $html = ''):...
FILE: Slim/Error/Renderers/JsonErrorRenderer.php
class JsonErrorRenderer (line 25) | class JsonErrorRenderer extends AbstractErrorRenderer
method __invoke (line 27) | public function __invoke(Throwable $exception, bool $displayErrorDetai...
method formatExceptionFragment (line 44) | private function formatExceptionFragment(Throwable $exception): array
FILE: Slim/Error/Renderers/PlainTextErrorRenderer.php
class PlainTextErrorRenderer (line 23) | class PlainTextErrorRenderer extends AbstractErrorRenderer
method __invoke (line 25) | public function __invoke(Throwable $exception, bool $displayErrorDetai...
method formatExceptionFragment (line 41) | private function formatExceptionFragment(Throwable $exception): string
FILE: Slim/Error/Renderers/XmlErrorRenderer.php
class XmlErrorRenderer (line 23) | class XmlErrorRenderer extends AbstractErrorRenderer
method __invoke (line 25) | public function __invoke(Throwable $exception, bool $displayErrorDetai...
method createCdataSection (line 50) | private function createCdataSection(string $content): string
FILE: Slim/Exception/HttpBadRequestException.php
class HttpBadRequestException (line 14) | class HttpBadRequestException extends HttpSpecializedException
FILE: Slim/Exception/HttpException.php
class HttpException (line 21) | class HttpException extends RuntimeException
method __construct (line 29) | public function __construct(
method getRequest (line 39) | public function getRequest(): ServerRequestInterface
method getTitle (line 44) | public function getTitle(): string
method setTitle (line 49) | public function setTitle(string $title): self
method getDescription (line 55) | public function getDescription(): string
method setDescription (line 60) | public function setDescription(string $description): self
FILE: Slim/Exception/HttpForbiddenException.php
class HttpForbiddenException (line 14) | class HttpForbiddenException extends HttpSpecializedException
FILE: Slim/Exception/HttpGoneException.php
class HttpGoneException (line 14) | class HttpGoneException extends HttpSpecializedException
FILE: Slim/Exception/HttpInternalServerErrorException.php
class HttpInternalServerErrorException (line 14) | class HttpInternalServerErrorException extends HttpSpecializedException
FILE: Slim/Exception/HttpMethodNotAllowedException.php
class HttpMethodNotAllowedException (line 15) | class HttpMethodNotAllowedException extends HttpSpecializedException
method getAllowedMethods (line 38) | public function getAllowedMethods(): array
method setAllowedMethods (line 46) | public function setAllowedMethods(array $methods): self
FILE: Slim/Exception/HttpNotFoundException.php
class HttpNotFoundException (line 13) | class HttpNotFoundException extends HttpSpecializedException
FILE: Slim/Exception/HttpNotImplementedException.php
class HttpNotImplementedException (line 14) | class HttpNotImplementedException extends HttpSpecializedException
FILE: Slim/Exception/HttpSpecializedException.php
class HttpSpecializedException (line 16) | abstract class HttpSpecializedException extends HttpException
method __construct (line 23) | public function __construct(ServerRequestInterface $request, ?string $...
FILE: Slim/Exception/HttpTooManyRequestsException.php
class HttpTooManyRequestsException (line 14) | class HttpTooManyRequestsException extends HttpSpecializedException
FILE: Slim/Exception/HttpUnauthorizedException.php
class HttpUnauthorizedException (line 14) | class HttpUnauthorizedException extends HttpSpecializedException
FILE: Slim/Factory/AppFactory.php
class AppFactory (line 28) | class AppFactory
method create (line 53) | public static function create(
method createFromContainer (line 77) | public static function createFromContainer(ContainerInterface $contain...
method determineResponseFactory (line 127) | public static function determineResponseFactory(): ResponseFactoryInte...
method attemptResponseFactoryDecoration (line 159) | protected static function attemptResponseFactoryDecoration(
method setPsr17FactoryProvider (line 173) | public static function setPsr17FactoryProvider(Psr17FactoryProviderInt...
method setResponseFactory (line 178) | public static function setResponseFactory(ResponseFactoryInterface $re...
method setStreamFactory (line 183) | public static function setStreamFactory(StreamFactoryInterface $stream...
method setContainer (line 188) | public static function setContainer(ContainerInterface $container): void
method setCallableResolver (line 193) | public static function setCallableResolver(CallableResolverInterface $...
method setRouteCollector (line 198) | public static function setRouteCollector(RouteCollectorInterface $rout...
method setRouteResolver (line 203) | public static function setRouteResolver(RouteResolverInterface $routeR...
method setMiddlewareDispatcher (line 208) | public static function setMiddlewareDispatcher(MiddlewareDispatcherInt...
method setSlimHttpDecoratorsAutomaticDetection (line 213) | public static function setSlimHttpDecoratorsAutomaticDetection(bool $e...
FILE: Slim/Factory/Psr17/GuzzlePsr17Factory.php
class GuzzlePsr17Factory (line 13) | class GuzzlePsr17Factory extends Psr17Factory
FILE: Slim/Factory/Psr17/HttpSoftPsr17Factory.php
class HttpSoftPsr17Factory (line 13) | class HttpSoftPsr17Factory extends Psr17Factory
FILE: Slim/Factory/Psr17/LaminasDiactorosPsr17Factory.php
class LaminasDiactorosPsr17Factory (line 13) | class LaminasDiactorosPsr17Factory extends Psr17Factory
FILE: Slim/Factory/Psr17/NyholmPsr17Factory.php
class NyholmPsr17Factory (line 9) | class NyholmPsr17Factory extends Psr17Factory
method getServerRequestCreator (line 19) | public static function getServerRequestCreator(): ServerRequestCreator...
FILE: Slim/Factory/Psr17/Psr17Factory.php
class Psr17Factory (line 22) | abstract class Psr17Factory implements Psr17FactoryInterface
method getResponseFactory (line 35) | public static function getResponseFactory(): ResponseFactoryInterface
method getStreamFactory (line 50) | public static function getStreamFactory(): StreamFactoryInterface
method getServerRequestCreator (line 65) | public static function getServerRequestCreator(): ServerRequestCreator...
method isResponseFactoryAvailable (line 77) | public static function isResponseFactoryAvailable(): bool
method isStreamFactoryAvailable (line 85) | public static function isStreamFactoryAvailable(): bool
method isServerRequestCreatorAvailable (line 93) | public static function isServerRequestCreatorAvailable(): bool
FILE: Slim/Factory/Psr17/Psr17FactoryProvider.php
class Psr17FactoryProvider (line 17) | class Psr17FactoryProvider implements Psr17FactoryProviderInterface
method getFactories (line 33) | public static function getFactories(): array
method setFactories (line 41) | public static function setFactories(array $factories): void
method addFactory (line 49) | public static function addFactory(string $factory): void
FILE: Slim/Factory/Psr17/ServerRequestCreator.php
class ServerRequestCreator (line 17) | class ServerRequestCreator implements ServerRequestCreatorInterface
method __construct (line 29) | public function __construct($serverRequestCreator, string $serverReque...
method createServerRequestFromGlobals (line 38) | public function createServerRequestFromGlobals(): ServerRequestInterface
FILE: Slim/Factory/Psr17/SlimHttpPsr17Factory.php
class SlimHttpPsr17Factory (line 17) | class SlimHttpPsr17Factory extends Psr17Factory
method createDecoratedResponseFactory (line 24) | public static function createDecoratedResponseFactory(
FILE: Slim/Factory/Psr17/SlimHttpServerRequestCreator.php
class SlimHttpServerRequestCreator (line 19) | class SlimHttpServerRequestCreator implements ServerRequestCreatorInterface
method __construct (line 25) | public function __construct(ServerRequestCreatorInterface $serverReque...
method createServerRequestFromGlobals (line 33) | public function createServerRequestFromGlobals(): ServerRequestInterface
method isServerRequestDecoratorAvailable (line 52) | public static function isServerRequestDecoratorAvailable(): bool
FILE: Slim/Factory/Psr17/SlimPsr17Factory.php
class SlimPsr17Factory (line 13) | class SlimPsr17Factory extends Psr17Factory
FILE: Slim/Factory/ServerRequestCreatorFactory.php
class ServerRequestCreatorFactory (line 21) | class ServerRequestCreatorFactory
method create (line 29) | public static function create(): ServerRequestCreatorInterface
method determineServerRequestCreator (line 37) | public static function determineServerRequestCreator(): ServerRequestC...
method attemptServerRequestCreatorDecoration (line 61) | protected static function attemptServerRequestCreatorDecoration(
method setPsr17FactoryProvider (line 74) | public static function setPsr17FactoryProvider(Psr17FactoryProviderInt...
method setServerRequestCreator (line 79) | public static function setServerRequestCreator(ServerRequestCreatorInt...
method setSlimHttpDecoratorsAutomaticDetection (line 84) | public static function setSlimHttpDecoratorsAutomaticDetection(bool $e...
FILE: Slim/Handlers/ErrorHandler.php
class ErrorHandler (line 48) | class ErrorHandler implements ErrorHandlerInterface
method __construct (line 95) | public function __construct(
method __invoke (line 114) | public function __invoke(
method forceContentType (line 144) | public function forceContentType(?string $contentType): void
method determineStatusCode (line 149) | protected function determineStatusCode(): int
method determineContentType (line 169) | protected function determineContentType(ServerRequestInterface $reques...
method determineRenderer (line 213) | protected function determineRenderer(): callable
method registerErrorRenderer (line 230) | public function registerErrorRenderer(string $contentType, $errorRende...
method setDefaultErrorRenderer (line 241) | public function setDefaultErrorRenderer(string $contentType, $errorRen...
method setLogErrorRenderer (line 252) | public function setLogErrorRenderer($logErrorRenderer): void
method writeToErrorLog (line 260) | protected function writeToErrorLog(): void
method logError (line 278) | protected function logError(string $error): void
method getDefaultLogger (line 286) | protected function getDefaultLogger(): LoggerInterface
method respond (line 291) | protected function respond(): ResponseInterface
FILE: Slim/Handlers/Strategies/RequestHandler.php
class RequestHandler (line 20) | class RequestHandler implements RequestHandlerInvocationStrategyInterface
method __construct (line 24) | public function __construct(bool $appendRouteArgumentsToRequestAttribu...
method __invoke (line 34) | public function __invoke(
FILE: Slim/Handlers/Strategies/RequestResponse.php
class RequestResponse (line 20) | class RequestResponse implements InvocationStrategyInterface
method __invoke (line 28) | public function __invoke(
FILE: Slim/Handlers/Strategies/RequestResponseArgs.php
class RequestResponseArgs (line 23) | class RequestResponseArgs implements InvocationStrategyInterface
method __invoke (line 31) | public function __invoke(
FILE: Slim/Handlers/Strategies/RequestResponseNamedArgs.php
class RequestResponseNamedArgs (line 22) | class RequestResponseNamedArgs implements InvocationStrategyInterface
method __invoke (line 30) | public function __invoke(
FILE: Slim/Interfaces/AdvancedCallableResolverInterface.php
type AdvancedCallableResolverInterface (line 13) | interface AdvancedCallableResolverInterface extends CallableResolverInte...
method resolveRoute (line 20) | public function resolveRoute($toResolve): callable;
method resolveMiddleware (line 27) | public function resolveMiddleware($toResolve): callable;
FILE: Slim/Interfaces/CallableResolverInterface.php
type CallableResolverInterface (line 13) | interface CallableResolverInterface
method resolve (line 20) | public function resolve($toResolve): callable;
FILE: Slim/Interfaces/DispatcherInterface.php
type DispatcherInterface (line 15) | interface DispatcherInterface
method dispatch (line 20) | public function dispatch(string $method, string $uri): RoutingResults;
method getAllowedMethods (line 27) | public function getAllowedMethods(string $uri): array;
FILE: Slim/Interfaces/ErrorHandlerInterface.php
type ErrorHandlerInterface (line 17) | interface ErrorHandlerInterface
method __invoke (line 19) | public function __invoke(
FILE: Slim/Interfaces/ErrorRendererInterface.php
type ErrorRendererInterface (line 15) | interface ErrorRendererInterface
method __invoke (line 17) | public function __invoke(Throwable $exception, bool $displayErrorDetai...
FILE: Slim/Interfaces/InvocationStrategyInterface.php
type InvocationStrategyInterface (line 19) | interface InvocationStrategyInterface
method __invoke (line 31) | public function __invoke(
FILE: Slim/Interfaces/MiddlewareDispatcherInterface.php
type MiddlewareDispatcherInterface (line 17) | interface MiddlewareDispatcherInterface extends RequestHandlerInterface
method add (line 28) | public function add($middleware): self;
method addMiddleware (line 37) | public function addMiddleware(MiddlewareInterface $middleware): self;
method seedMiddlewareStack (line 42) | public function seedMiddlewareStack(RequestHandlerInterface $kernel): ...
FILE: Slim/Interfaces/Psr17FactoryInterface.php
type Psr17FactoryInterface (line 17) | interface Psr17FactoryInterface
method getResponseFactory (line 22) | public static function getResponseFactory(): ResponseFactoryInterface;
method getStreamFactory (line 27) | public static function getStreamFactory(): StreamFactoryInterface;
method getServerRequestCreator (line 32) | public static function getServerRequestCreator(): ServerRequestCreator...
method isResponseFactoryAvailable (line 37) | public static function isResponseFactoryAvailable(): bool;
method isStreamFactoryAvailable (line 42) | public static function isStreamFactoryAvailable(): bool;
method isServerRequestCreatorAvailable (line 47) | public static function isServerRequestCreatorAvailable(): bool;
FILE: Slim/Interfaces/Psr17FactoryProviderInterface.php
type Psr17FactoryProviderInterface (line 14) | interface Psr17FactoryProviderInterface
method getFactories (line 19) | public static function getFactories(): array;
method setFactories (line 24) | public static function setFactories(array $factories): void;
method addFactory (line 26) | public static function addFactory(string $factory): void;
FILE: Slim/Interfaces/RequestHandlerInvocationStrategyInterface.php
type RequestHandlerInvocationStrategyInterface (line 13) | interface RequestHandlerInvocationStrategyInterface extends InvocationSt...
FILE: Slim/Interfaces/RouteCollectorInterface.php
type RouteCollectorInterface (line 17) | interface RouteCollectorInterface
method getRouteParser (line 22) | public function getRouteParser(): RouteParserInterface;
method getDefaultInvocationStrategy (line 27) | public function getDefaultInvocationStrategy(): InvocationStrategyInte...
method setDefaultInvocationStrategy (line 32) | public function setDefaultInvocationStrategy(InvocationStrategyInterfa...
method getCacheFile (line 37) | public function getCacheFile(): ?string;
method setCacheFile (line 45) | public function setCacheFile(string $cacheFile): RouteCollectorInterface;
method getBasePath (line 50) | public function getBasePath(): string;
method setBasePath (line 55) | public function setBasePath(string $basePath): RouteCollectorInterface;
method getRoutes (line 62) | public function getRoutes(): array;
method getNamedRoute (line 71) | public function getNamedRoute(string $name): RouteInterface;
method removeNamedRoute (line 80) | public function removeNamedRoute(string $name): RouteCollectorInterface;
method lookupRoute (line 87) | public function lookupRoute(string $identifier): RouteInterface;
method group (line 93) | public function group(string $pattern, $callable): RouteGroupInterface;
method map (line 102) | public function map(array $methods, string $pattern, $handler): RouteI...
FILE: Slim/Interfaces/RouteCollectorProxyInterface.php
type RouteCollectorProxyInterface (line 21) | interface RouteCollectorProxyInterface
method getResponseFactory (line 23) | public function getResponseFactory(): ResponseFactoryInterface;
method getCallableResolver (line 25) | public function getCallableResolver(): CallableResolverInterface;
method getContainer (line 30) | public function getContainer(): ?ContainerInterface;
method getRouteCollector (line 32) | public function getRouteCollector(): RouteCollectorInterface;
method getBasePath (line 37) | public function getBasePath(): string;
method setBasePath (line 43) | public function setBasePath(string $basePath): RouteCollectorProxyInte...
method get (line 51) | public function get(string $pattern, $callable): RouteInterface;
method post (line 59) | public function post(string $pattern, $callable): RouteInterface;
method put (line 67) | public function put(string $pattern, $callable): RouteInterface;
method patch (line 75) | public function patch(string $pattern, $callable): RouteInterface;
method delete (line 83) | public function delete(string $pattern, $callable): RouteInterface;
method options (line 91) | public function options(string $pattern, $callable): RouteInterface;
method any (line 99) | public function any(string $pattern, $callable): RouteInterface;
method map (line 108) | public function map(array $methods, string $pattern, $callable): Route...
method group (line 118) | public function group(string $pattern, $callable): RouteGroupInterface;
method redirect (line 125) | public function redirect(string $from, $to, int $status = 302): RouteI...
FILE: Slim/Interfaces/RouteGroupInterface.php
type RouteGroupInterface (line 17) | interface RouteGroupInterface
method collectRoutes (line 19) | public function collectRoutes(): RouteGroupInterface;
method add (line 26) | public function add($middleware): RouteGroupInterface;
method addMiddleware (line 31) | public function addMiddleware(MiddlewareInterface $middleware): RouteG...
method appendMiddlewareToDispatcher (line 37) | public function appendMiddlewareToDispatcher(MiddlewareDispatcher $dis...
method getPattern (line 42) | public function getPattern(): string;
FILE: Slim/Interfaces/RouteInterface.php
type RouteInterface (line 18) | interface RouteInterface
method getInvocationStrategy (line 23) | public function getInvocationStrategy(): InvocationStrategyInterface;
method setInvocationStrategy (line 28) | public function setInvocationStrategy(InvocationStrategyInterface $inv...
method getMethods (line 35) | public function getMethods(): array;
method getPattern (line 40) | public function getPattern(): string;
method setPattern (line 45) | public function setPattern(string $pattern): RouteInterface;
method getCallable (line 52) | public function getCallable();
method setCallable (line 59) | public function setCallable($callable): RouteInterface;
method getName (line 64) | public function getName(): ?string;
method setName (line 71) | public function setName(string $name): RouteInterface;
method getIdentifier (line 76) | public function getIdentifier(): string;
method getArgument (line 81) | public function getArgument(string $name, ?string $default = null): ?s...
method getArguments (line 88) | public function getArguments(): array;
method setArgument (line 95) | public function setArgument(string $name, string $value): RouteInterface;
method setArguments (line 104) | public function setArguments(array $arguments): self;
method add (line 109) | public function add($middleware): self;
method addMiddleware (line 111) | public function addMiddleware(MiddlewareInterface $middleware): self;
method prepare (line 118) | public function prepare(array $arguments): self;
method run (line 127) | public function run(ServerRequestInterface $request): ResponseInterface;
FILE: Slim/Interfaces/RouteParserInterface.php
type RouteParserInterface (line 18) | interface RouteParserInterface
method relativeUrlFor (line 30) | public function relativeUrlFor(string $routeName, array $data = [], ar...
method urlFor (line 42) | public function urlFor(string $routeName, array $data = [], array $que...
method fullUrlFor (line 52) | public function fullUrlFor(UriInterface $uri, string $routeName, array...
FILE: Slim/Interfaces/RouteResolverInterface.php
type RouteResolverInterface (line 9) | interface RouteResolverInterface
method computeRoutingResults (line 14) | public function computeRoutingResults(string $uri, string $method): Ro...
method resolveRoute (line 16) | public function resolveRoute(string $identifier): RouteInterface;
FILE: Slim/Interfaces/ServerRequestCreatorInterface.php
type ServerRequestCreatorInterface (line 15) | interface ServerRequestCreatorInterface
method createServerRequestFromGlobals (line 17) | public function createServerRequestFromGlobals(): ServerRequestInterface;
FILE: Slim/Logger.php
class Logger (line 19) | class Logger extends AbstractLogger
method log (line 28) | public function log($level, $message, array $context = []): void
FILE: Slim/Middleware/BodyParsingMiddleware.php
class BodyParsingMiddleware (line 36) | class BodyParsingMiddleware implements MiddlewareInterface
method __construct (line 46) | public function __construct(array $bodyParsers = [])
method process (line 55) | public function process(ServerRequestInterface $request, RequestHandle...
method registerBodyParser (line 71) | public function registerBodyParser(string $mediaType, callable $callab...
method hasBodyParser (line 80) | public function hasBodyParser(string $mediaType): bool
method getBodyParser (line 89) | public function getBodyParser(string $mediaType): callable
method registerDefaultBodyParsers (line 97) | protected function registerDefaultBodyParsers(): void
method parseBody (line 142) | protected function parseBody(ServerRequestInterface $request)
method getMediaType (line 177) | protected function getMediaType(ServerRequestInterface $request): ?string
method disableXmlEntityLoader (line 189) | protected static function disableXmlEntityLoader(bool $disable): bool
FILE: Slim/Middleware/ContentLengthMiddleware.php
class ContentLengthMiddleware (line 19) | class ContentLengthMiddleware implements MiddlewareInterface
method process (line 21) | public function process(ServerRequestInterface $request, RequestHandle...
FILE: Slim/Middleware/ErrorMiddleware.php
class ErrorMiddleware (line 29) | class ErrorMiddleware implements MiddlewareInterface
method __construct (line 58) | public function __construct(
method process (line 74) | public function process(ServerRequestInterface $request, RequestHandle...
method handleException (line 83) | public function handleException(ServerRequestInterface $request, Throw...
method getErrorHandler (line 103) | public function getErrorHandler(string $type)
method getDefaultErrorHandler (line 127) | public function getDefaultErrorHandler()
method setDefaultErrorHandler (line 158) | public function setDefaultErrorHandler($handler): self
method setErrorHandler (line 190) | public function setErrorHandler($typeOrTypes, $handler, bool $handleSu...
method addErrorHandler (line 207) | private function addErrorHandler(string $type, $handler, bool $handleS...
FILE: Slim/Middleware/MethodOverrideMiddleware.php
class MethodOverrideMiddleware (line 22) | class MethodOverrideMiddleware implements MiddlewareInterface
method process (line 24) | public function process(ServerRequestInterface $request, RequestHandle...
FILE: Slim/Middleware/OutputBufferingMiddleware.php
class OutputBufferingMiddleware (line 27) | class OutputBufferingMiddleware implements MiddlewareInterface
method __construct (line 39) | public function __construct(StreamFactoryInterface $streamFactory, str...
method process (line 52) | public function process(ServerRequestInterface $request, RequestHandle...
FILE: Slim/Middleware/RoutingMiddleware.php
class RoutingMiddleware (line 25) | class RoutingMiddleware implements MiddlewareInterface
method __construct (line 31) | public function __construct(RouteResolverInterface $routeResolver, Rou...
method process (line 42) | public function process(ServerRequestInterface $request, RequestHandle...
method performRouting (line 57) | public function performRouting(ServerRequestInterface $request): Serve...
method resolveRoutingResultsFromRequest (line 91) | protected function resolveRoutingResultsFromRequest(ServerRequestInter...
FILE: Slim/MiddlewareDispatcher.php
class MiddlewareDispatcher (line 35) | class MiddlewareDispatcher implements MiddlewareDispatcherInterface
method __construct (line 50) | public function __construct(
method seedMiddlewareStack (line 63) | public function seedMiddlewareStack(RequestHandlerInterface $kernel): ...
method handle (line 71) | public function handle(ServerRequestInterface $request): ResponseInter...
method add (line 85) | public function add($middleware): MiddlewareDispatcherInterface
method addMiddleware (line 113) | public function addMiddleware(MiddlewareInterface $middleware): Middle...
method addDeferred (line 144) | public function addDeferred(string $middleware): self
method addCallable (line 254) | public function addCallable(callable $middleware): self
FILE: Slim/ResponseEmitter.php
class ResponseEmitter (line 26) | class ResponseEmitter
method __construct (line 30) | public function __construct(int $responseChunkSize = 4096)
method emit (line 38) | public function emit(ResponseInterface $response): void
method emitHeaders (line 58) | private function emitHeaders(ResponseInterface $response): void
method emitStatusLine (line 73) | private function emitStatusLine(ResponseInterface $response): void
method emitBody (line 87) | private function emitBody(ResponseInterface $response): void
method isResponseEmpty (line 124) | public function isResponseEmpty(ResponseInterface $response): bool
FILE: Slim/Routing/Dispatcher.php
class Dispatcher (line 13) | class Dispatcher implements DispatcherInterface
method __construct (line 19) | public function __construct(RouteCollectorInterface $routeCollector)
method createDispatcher (line 24) | protected function createDispatcher(): FastRouteDispatcher
method dispatch (line 63) | public function dispatch(string $method, string $uri): RoutingResults
method getAllowedMethods (line 73) | public function getAllowedMethods(string $uri): array
FILE: Slim/Routing/FastRouteDispatcher.php
class FastRouteDispatcher (line 15) | class FastRouteDispatcher extends GroupCountBased
method dispatch (line 28) | public function dispatch($httpMethod, $uri): array
method routingResults (line 62) | private function routingResults(string $httpMethod, string $uri): array
method getAllowedMethods (line 87) | public function getAllowedMethods(string $uri): array
FILE: Slim/Routing/Route.php
class Route (line 40) | class Route implements RouteInterface, RequestHandlerInterface
method __construct (line 120) | public function __construct(
method getCallableResolver (line 143) | public function getCallableResolver(): CallableResolverInterface
method getInvocationStrategy (line 151) | public function getInvocationStrategy(): InvocationStrategyInterface
method setInvocationStrategy (line 159) | public function setInvocationStrategy(InvocationStrategyInterface $inv...
method getMethods (line 168) | public function getMethods(): array
method getPattern (line 176) | public function getPattern(): string
method setPattern (line 184) | public function setPattern(string $pattern): RouteInterface
method getCallable (line 193) | public function getCallable()
method setCallable (line 201) | public function setCallable($callable): RouteInterface
method getName (line 210) | public function getName(): ?string
method setName (line 218) | public function setName(string $name): RouteInterface
method getIdentifier (line 227) | public function getIdentifier(): string
method getArgument (line 235) | public function getArgument(string $name, ?string $default = null): ?s...
method getArguments (line 246) | public function getArguments(): array
method setArguments (line 254) | public function setArguments(array $arguments, bool $includeInSavedArg...
method getGroups (line 267) | public function getGroups(): array
method add (line 275) | public function add($middleware): RouteInterface
method addMiddleware (line 284) | public function addMiddleware(MiddlewareInterface $middleware): RouteI...
method prepare (line 293) | public function prepare(array $arguments): RouteInterface
method setArgument (line 302) | public function setArgument(string $name, string $value, bool $include...
method run (line 315) | public function run(ServerRequestInterface $request): ResponseInterface
method appendGroupMiddlewareToRoute (line 327) | protected function appendGroupMiddlewareToRoute(): void
method handle (line 342) | public function handle(ServerRequestInterface $request): ResponseInter...
FILE: Slim/Routing/RouteCollector.php
class RouteCollector (line 37) | class RouteCollector implements RouteCollectorInterface
method __construct (line 88) | public function __construct(
method getRouteParser (line 107) | public function getRouteParser(): RouteParserInterface
method getDefaultInvocationStrategy (line 115) | public function getDefaultInvocationStrategy(): InvocationStrategyInte...
method setDefaultInvocationStrategy (line 120) | public function setDefaultInvocationStrategy(InvocationStrategyInterfa...
method getCacheFile (line 129) | public function getCacheFile(): ?string
method setCacheFile (line 137) | public function setCacheFile(string $cacheFile): RouteCollectorInterface
method getBasePath (line 158) | public function getBasePath(): string
method setBasePath (line 166) | public function setBasePath(string $basePath): RouteCollectorInterface
method getRoutes (line 176) | public function getRoutes(): array
method removeNamedRoute (line 184) | public function removeNamedRoute(string $name): RouteCollectorInterface
method getNamedRoute (line 196) | public function getNamedRoute(string $name): RouteInterface
method lookupRoute (line 220) | public function lookupRoute(string $identifier): RouteInterface
method group (line 231) | public function group(string $pattern, $callable): RouteGroupInterface
method createGroup (line 245) | protected function createGroup(string $pattern, $callable): RouteGroup...
method createProxy (line 254) | protected function createProxy(string $pattern): RouteCollectorProxyIn...
method map (line 269) | public function map(array $methods, string $pattern, $handler): RouteI...
method createRoute (line 288) | protected function createRoute(array $methods, string $pattern, $calla...
FILE: Slim/Routing/RouteCollectorProxy.php
class RouteCollectorProxy (line 25) | class RouteCollectorProxy implements RouteCollectorProxyInterface
method __construct (line 41) | public function __construct(
method getResponseFactory (line 58) | public function getResponseFactory(): ResponseFactoryInterface
method getCallableResolver (line 66) | public function getCallableResolver(): CallableResolverInterface
method getContainer (line 75) | public function getContainer(): ?ContainerInterface
method getRouteCollector (line 83) | public function getRouteCollector(): RouteCollectorInterface
method getBasePath (line 91) | public function getBasePath(): string
method setBasePath (line 99) | public function setBasePath(string $basePath): RouteCollectorProxyInte...
method get (line 109) | public function get(string $pattern, $callable): RouteInterface
method post (line 117) | public function post(string $pattern, $callable): RouteInterface
method put (line 125) | public function put(string $pattern, $callable): RouteInterface
method patch (line 133) | public function patch(string $pattern, $callable): RouteInterface
method delete (line 141) | public function delete(string $pattern, $callable): RouteInterface
method options (line 149) | public function options(string $pattern, $callable): RouteInterface
method any (line 157) | public function any(string $pattern, $callable): RouteInterface
method map (line 165) | public function map(array $methods, string $pattern, $callable): Route...
method group (line 175) | public function group(string $pattern, $callable): RouteGroupInterface
method redirect (line 185) | public function redirect(string $from, $to, int $status = 302): RouteI...
FILE: Slim/Routing/RouteContext.php
class RouteContext (line 19) | final class RouteContext
method fromRequest (line 29) | public static function fromRequest(ServerRequestInterface $serverReque...
method __construct (line 55) | private function __construct(
method getRoute (line 67) | public function getRoute(): ?RouteInterface
method getRouteParser (line 72) | public function getRouteParser(): RouteParserInterface
method getRoutingResults (line 77) | public function getRoutingResults(): RoutingResults
method getBasePath (line 82) | public function getBasePath(): string
FILE: Slim/Routing/RouteGroup.php
class RouteGroup (line 20) | class RouteGroup implements RouteGroupInterface
method __construct (line 45) | public function __construct(
method collectRoutes (line 60) | public function collectRoutes(): RouteGroupInterface
method add (line 74) | public function add($middleware): RouteGroupInterface
method addMiddleware (line 83) | public function addMiddleware(MiddlewareInterface $middleware): RouteG...
method appendMiddlewareToDispatcher (line 93) | public function appendMiddlewareToDispatcher(MiddlewareDispatcher $dis...
method getPattern (line 105) | public function getPattern(): string
FILE: Slim/Routing/RouteParser.php
class RouteParser (line 25) | class RouteParser implements RouteParserInterface
method __construct (line 31) | public function __construct(RouteCollectorInterface $routeCollector)
method relativeUrlFor (line 40) | public function relativeUrlFor(string $routeName, array $data = [], ar...
method urlFor (line 104) | public function urlFor(string $routeName, array $data = [], array $que...
method fullUrlFor (line 119) | public function fullUrlFor(UriInterface $uri, string $routeName, array...
FILE: Slim/Routing/RouteResolver.php
class RouteResolver (line 25) | class RouteResolver implements RouteResolverInterface
method __construct (line 31) | public function __construct(RouteCollectorInterface $routeCollector, ?...
method computeRoutingResults (line 40) | public function computeRoutingResults(string $uri, string $method): Ro...
method resolveRoute (line 52) | public function resolveRoute(string $identifier): RouteInterface
FILE: Slim/Routing/RouteRunner.php
class RouteRunner (line 23) | class RouteRunner implements RequestHandlerInterface
method __construct (line 37) | public function __construct(
method handle (line 57) | public function handle(ServerRequestInterface $request): ResponseInter...
FILE: Slim/Routing/RoutingResults.php
class RoutingResults (line 18) | class RoutingResults
method __construct (line 48) | public function __construct(
method getDispatcher (line 64) | public function getDispatcher(): DispatcherInterface
method getMethod (line 69) | public function getMethod(): string
method getUri (line 74) | public function getUri(): string
method getRouteStatus (line 79) | public function getRouteStatus(): int
method getRouteIdentifier (line 84) | public function getRouteIdentifier(): ?string
method getRouteArguments (line 92) | public function getRouteArguments(bool $urlDecode = true): array
method getAllowedMethods (line 109) | public function getAllowedMethods(): array
FILE: tests/AppTest.php
class AppTest (line 56) | class AppTest extends TestCase
method setupBeforeClass (line 58) | public static function setupBeforeClass(): void
method testDoesNotUseContainerAsServiceLocator (line 63) | public function testDoesNotUseContainerAsServiceLocator(): void
method testGetContainer (line 77) | public function testGetContainer(): void
method testGetCallableResolverReturnsInjectedInstance (line 86) | public function testGetCallableResolverReturnsInjectedInstance(): void
method testCreatesCallableResolverWhenNull (line 95) | public function testCreatesCallableResolverWhenNull(): void
method testGetRouteCollectorReturnsInjectedInstance (line 105) | public function testGetRouteCollectorReturnsInjectedInstance(): void
method testCreatesRouteCollectorWhenNullWithInjectedContainer (line 118) | public function testCreatesRouteCollectorWhenNullWithInjectedContainer...
method testGetMiddlewareDispatcherGetsSeededAndReturnsInjectedInstance (line 137) | public function testGetMiddlewareDispatcherGetsSeededAndReturnsInjecte...
method lowerCaseRequestMethodsProvider (line 158) | public static function lowerCaseRequestMethodsProvider(): array
method testGetPostPutPatchDeleteOptionsMethods (line 174) | #[\PHPUnit\Framework\Attributes\DataProvider('upperCaseRequestMethodsP...
method testAnyRoute (line 208) | public function testAnyRoute(): void
method upperCaseRequestMethodsProvider (line 248) | public static function upperCaseRequestMethodsProvider(): array
method testMapRoute (line 265) | #[\PHPUnit\Framework\Attributes\DataProvider('lowerCaseRequestMethodsP...
method testRedirectRoute (line 299) | public function testRedirectRoute(): void
method testRouteWithInternationalCharacters (line 343) | public function testRouteWithInternationalCharacters(): void
method routePatternsProvider (line 382) | public static function routePatternsProvider(): array
method testRoutePatterns (line 397) | #[\PHPUnit\Framework\Attributes\DataProvider('routePatternsProvider')]
method routeGroupsDataProvider (line 416) | public static function routeGroupsDataProvider(): array
method testGroupClosureIsBoundToThisClass (line 530) | public function testGroupClosureIsBoundToThisClass(): void
method testRouteGroupCombinations (line 546) | #[\PHPUnit\Framework\Attributes\DataProvider('routeGroupsDataProvider')]
method testRouteGroupPattern (line 577) | public function testRouteGroupPattern(): void
method testAddMiddleware (line 594) | public function testAddMiddleware(): void
method testAddMiddlewareUsingDeferredResolution (line 658) | public function testAddMiddlewareUsingDeferredResolution(): void
method testAddRoutingMiddleware (line 693) | public function testAddRoutingMiddleware(): void
method testAddErrorMiddleware (line 723) | public function testAddErrorMiddleware(): void
method testAddBodyParsingMiddleware (line 756) | public function testAddBodyParsingMiddleware(): void
method testAddMiddlewareOnRoute (line 786) | public function testAddMiddlewareOnRoute(): void
method testAddMiddlewareOnRouteGroup (line 866) | public function testAddMiddlewareOnRouteGroup(): void
method testAddMiddlewareOnTwoRouteGroup (line 948) | public function testAddMiddlewareOnTwoRouteGroup(): void
method testAddMiddlewareAsStringNotImplementingInterfaceThrowsException (line 1068) | public function testAddMiddlewareAsStringNotImplementingInterfaceThrow...
method testInvokeReturnMethodNotAllowed (line 1085) | public function testInvokeReturnMethodNotAllowed(): void
method testInvokeWithMatchingRoute (line 1109) | public function testInvokeWithMatchingRoute(): void
method testInvokeWithMatchingRouteWithSetArgument (line 1143) | public function testInvokeWithMatchingRouteWithSetArgument(): void
method testInvokeWithMatchingRouteWithSetArguments (line 1184) | public function testInvokeWithMatchingRouteWithSetArguments(): void
method testInvokeWithMatchingRouteWithNamedParameterRequestResponseStrategy (line 1225) | public function testInvokeWithMatchingRouteWithNamedParameterRequestRe...
method testInvokeWithMatchingRouteWithNamedParameterRequestResponseArgStrategy (line 1266) | public function testInvokeWithMatchingRouteWithNamedParameterRequestRe...
method testInvokeWithMatchingRouteWithNamedParameterRequestResponseNamedArgsStrategy (line 1308) | public function testInvokeWithMatchingRouteWithNamedParameterRequestRe...
method testInvokeWithMatchingRouteWithNamedParameterOverwritesSetArgument (line 1357) | public function testInvokeWithMatchingRouteWithNamedParameterOverwrite...
method testInvokeWithoutMatchingRoute (line 1398) | public function testInvokeWithoutMatchingRoute(): void
method testInvokeWithCallableRegisteredInContainer (line 1420) | public function testInvokeWithCallableRegisteredInContainer(): void
method testInvokeWithNonExistentMethodOnCallableRegisteredInContainer (line 1464) | public function testInvokeWithNonExistentMethodOnCallableRegisteredInC...
method testInvokeWithCallableInContainerViaCallMagicMethod (line 1500) | public function testInvokeWithCallableInContainerViaCallMagicMethod():...
method testInvokeFunctionName (line 1545) | public function testInvokeFunctionName(): void
method testCurrentRequestAttributesAreNotLostWhenAddingRouteArguments (line 1592) | public function testCurrentRequestAttributesAreNotLostWhenAddingRouteA...
method testCurrentRequestAttributesAreNotLostWhenAddingRouteArgumentsRequestResponseArg (line 1633) | public function testCurrentRequestAttributesAreNotLostWhenAddingRouteA...
method testRun (line 1675) | public function testRun(): void
method testRunWithoutPassingInServerRequest (line 1728) | public function testRunWithoutPassingInServerRequest(): void
method testHandleReturnsEmptyResponseBodyWithHeadRequestMethod (line 1769) | public function testHandleReturnsEmptyResponseBodyWithHeadRequestMetho...
method testCanBeReExecutedRecursivelyDuringDispatch (line 1826) | public function testCanBeReExecutedRecursivelyDuringDispatch(): void
method testContainerSetToRoute (line 1946) | public function testContainerSetToRoute(): void
method testAppIsARequestHandler (line 1984) | public function testAppIsARequestHandler(): void
method testInvokeSequentialProcessToAPathWithOptionalArgsAndWithoutOptionalArgs (line 1992) | public function testInvokeSequentialProcessToAPathWithOptionalArgsAndW...
method testInvokeSequentialProcessToAPathWithOptionalArgsAndWithoutOptionalArgsAndKeepSetedArgs (line 2047) | public function testInvokeSequentialProcessToAPathWithOptionalArgsAndW...
method testInvokeSequentialProcessAfterAddingAnotherRouteArgument (line 2102) | public function testInvokeSequentialProcessAfterAddingAnotherRouteArgu...
FILE: tests/Assets/HeaderStack.php
class HeaderStack (line 41) | class HeaderStack
method reset (line 51) | public static function reset()
method push (line 61) | public static function push(array $header)
method stack (line 71) | public static function stack()
method has (line 83) | public static function has($header)
FILE: tests/CallableResolverTest.php
class CallableResolverTest (line 24) | class CallableResolverTest extends TestCase
method setUpBeforeClass (line 28) | public static function setUpBeforeClass(): void
method setUp (line 36) | public function setUp(): void
method testClosure (line 46) | public function testClosure(): void
method testClosureContainer (line 61) | public function testClosureContainer(): void
method testFunctionName (line 86) | public function testFunctionName(): void
method testObjMethodArray (line 98) | public function testObjMethodArray(): void
method testSlimCallable (line 116) | public function testSlimCallable(): void
method testSlimCallableAsArray (line 133) | public function testSlimCallableAsArray(): void
method testSlimCallableContainer (line 150) | public function testSlimCallableContainer(): void
method testSlimCallableAsArrayContainer (line 167) | public function testSlimCallableAsArrayContainer(): void
method testContainer (line 184) | public function testContainer(): void
method testResolutionToAnInvokableClassInContainer (line 207) | public function testResolutionToAnInvokableClassInContainer(): void
method testResolutionToAnInvokableClass (line 230) | public function testResolutionToAnInvokableClass(): void
method testResolutionToAPsrRequestHandlerClass (line 247) | public function testResolutionToAPsrRequestHandlerClass(): void
method testRouteResolutionToAPsrRequestHandlerClass (line 256) | public function testRouteResolutionToAPsrRequestHandlerClass(): void
method testMiddlewareResolutionToAPsrRequestHandlerClass (line 265) | public function testMiddlewareResolutionToAPsrRequestHandlerClass(): void
method testObjPsrRequestHandlerClass (line 274) | public function testObjPsrRequestHandlerClass(): void
method testRouteObjPsrRequestHandlerClass (line 284) | public function testRouteObjPsrRequestHandlerClass(): void
method testMiddlewareObjPsrRequestHandlerClass (line 294) | public function testMiddlewareObjPsrRequestHandlerClass(): void
method testObjPsrRequestHandlerClassInContainer (line 304) | public function testObjPsrRequestHandlerClassInContainer(): void
method testRouteObjPsrRequestHandlerClassInContainer (line 318) | public function testRouteObjPsrRequestHandlerClassInContainer(): void
method testMiddlewareObjPsrRequestHandlerClassInContainer (line 333) | public function testMiddlewareObjPsrRequestHandlerClassInContainer(): ...
method testResolutionToAPsrRequestHandlerClassWithCustomMethod (line 347) | public function testResolutionToAPsrRequestHandlerClassWithCustomMetho...
method testObjMiddlewareClass (line 367) | public function testObjMiddlewareClass(): void
method testRouteObjMiddlewareClass (line 377) | public function testRouteObjMiddlewareClass(): void
method testMiddlewareObjMiddlewareClass (line 387) | public function testMiddlewareObjMiddlewareClass(): void
method testNotObjectInContainerThrowException (line 397) | public function testNotObjectInContainerThrowException(): void
method testMethodNotFoundThrowException (line 411) | public function testMethodNotFoundThrowException(): void
method testRouteMethodNotFoundThrowException (line 425) | public function testRouteMethodNotFoundThrowException(): void
method testMiddlewareMethodNotFoundThrowException (line 439) | public function testMiddlewareMethodNotFoundThrowException(): void
method testFunctionNotFoundThrowException (line 453) | public function testFunctionNotFoundThrowException(): void
method testRouteFunctionNotFoundThrowException (line 464) | public function testRouteFunctionNotFoundThrowException(): void
method testMiddlewareFunctionNotFoundThrowException (line 475) | public function testMiddlewareFunctionNotFoundThrowException(): void
method testClassNotFoundThrowException (line 486) | public function testClassNotFoundThrowException(): void
method testRouteClassNotFoundThrowException (line 497) | public function testRouteClassNotFoundThrowException(): void
method testMiddlewareClassNotFoundThrowException (line 508) | public function testMiddlewareClassNotFoundThrowException(): void
method testCallableClassNotFoundThrowException (line 519) | public function testCallableClassNotFoundThrowException(): void
method testRouteCallableClassNotFoundThrowException (line 530) | public function testRouteCallableClassNotFoundThrowException(): void
method testMiddlewareCallableClassNotFoundThrowException (line 541) | public function testMiddlewareCallableClassNotFoundThrowException(): void
FILE: tests/Error/AbstractErrorRendererTest.php
class AbstractErrorRendererTest (line 28) | class AbstractErrorRendererTest extends TestCase
method testHTMLErrorRendererDisplaysErrorDetails (line 30) | public function testHTMLErrorRendererDisplaysErrorDetails()
method testHTMLErrorRendererNoErrorDetails (line 43) | public function testHTMLErrorRendererNoErrorDetails()
method testHTMLErrorRendererRenderFragmentMethod (line 56) | public function testHTMLErrorRendererRenderFragmentMethod()
method testHTMLErrorRendererRenderHttpException (line 73) | public function testHTMLErrorRendererRenderHttpException()
method testJSONErrorRendererDisplaysErrorDetails (line 97) | public function testJSONErrorRendererDisplaysErrorDetails()
method testJSONErrorRendererDoesNotDisplayErrorDetails (line 113) | public function testJSONErrorRendererDoesNotDisplayErrorDetails()
method testJSONErrorRendererDisplaysPreviousError (line 123) | public function testJSONErrorRendererDisplaysPreviousError()
method testJSONErrorRendererRenderHttpException (line 145) | public function testJSONErrorRendererRenderHttpException()
method testXMLErrorRendererDisplaysErrorDetails (line 167) | public function testXMLErrorRendererDisplaysErrorDetails()
method testXMLErrorRendererRenderHttpException (line 184) | public function testXMLErrorRendererRenderHttpException()
method testPlainTextErrorRendererFormatFragmentMethod (line 203) | public function testPlainTextErrorRendererFormatFragmentMethod()
method testPlainTextErrorRendererDisplaysErrorDetails (line 225) | public function testPlainTextErrorRendererDisplaysErrorDetails()
method testPlainTextErrorRendererNotDisplaysErrorDetails (line 236) | public function testPlainTextErrorRendererNotDisplaysErrorDetails()
method testPlainTextErrorRendererRenderHttpException (line 247) | public function testPlainTextErrorRendererRenderHttpException()
FILE: tests/Exception/HttpExceptionTest.php
class HttpExceptionTest (line 18) | class HttpExceptionTest extends TestCase
method testHttpExceptionRequestReponseGetterSetters (line 20) | public function testHttpExceptionRequestReponseGetterSetters()
method testHttpExceptionAttributeGettersSetters (line 28) | public function testHttpExceptionAttributeGettersSetters()
method testHttpNotAllowedExceptionGetAllowedMethods (line 40) | public function testHttpNotAllowedExceptionGetAllowedMethods()
FILE: tests/Exception/HttpUnauthorizedExceptionTest.php
class HttpUnauthorizedExceptionTest (line 16) | class HttpUnauthorizedExceptionTest extends TestCase
method testHttpUnauthorizedException (line 18) | public function testHttpUnauthorizedException()
method testHttpUnauthorizedExceptionWithMessage (line 26) | public function testHttpUnauthorizedExceptionWithMessage()
FILE: tests/Factory/AppFactoryTest.php
class AppFactoryTest (line 45) | class AppFactoryTest extends TestCase
method tearDown (line 47) | protected function tearDown(): void
method provideImplementations (line 53) | public static function provideImplementations()
method testCreateAppWithAllImplementations (line 69) | #[\PHPUnit\Framework\Attributes\DataProvider('provideImplementations')]
method testDetermineResponseFactoryReturnsDecoratedFactory (line 87) | public function testDetermineResponseFactoryReturnsDecoratedFactory()
method testDetermineResponseFactoryThrowsRuntimeExceptionIfDecoratedNotInstanceOfResponseInterface (line 97) | public function testDetermineResponseFactoryThrowsRuntimeExceptionIfDe...
method testDetermineResponseFactoryThrowsRuntimeException (line 116) | public function testDetermineResponseFactoryThrowsRuntimeException()
method testSetPsr17FactoryProvider (line 124) | public function testSetPsr17FactoryProvider()
method testResponseFactoryIsStillReturnedIfStreamFactoryIsNotAvailable (line 138) | #[\PHPUnit\Framework\Attributes\RunInSeparateProcess]
method testAppIsCreatedWithInstancesFromSetters (line 152) | #[\PHPUnit\Framework\Attributes\RunInSeparateProcess]
method testAppIsCreatedWithInjectedInstancesFromFunctionArguments (line 210) | #[\PHPUnit\Framework\Attributes\RunInSeparateProcess]
method testResponseAndStreamFactoryIsBeingInjectedInDecoratedResponseFactory (line 261) | #[\PHPUnit\Framework\Attributes\RunInSeparateProcess]
method testCreateAppWithContainerUsesContainerDependenciesWhenPresent (line 289) | public function testCreateAppWithContainerUsesContainerDependenciesWhe...
method testCreateAppWithEmptyContainer (line 367) | public function testCreateAppWithEmptyContainer()
FILE: tests/Factory/Psr17/Psr17FactoryProviderTest.php
class Psr17FactoryProviderTest (line 16) | class Psr17FactoryProviderTest extends TestCase
method testGetSetFactories (line 21) | #[\PHPUnit\Framework\Attributes\RunInSeparateProcess]
method testAddFactory (line 33) | #[\PHPUnit\Framework\Attributes\RunInSeparateProcess]
FILE: tests/Factory/Psr17/Psr17FactoryTest.php
class Psr17FactoryTest (line 17) | class Psr17FactoryTest extends TestCase
method testGetResponseFactoryThrowsRuntimeException (line 19) | public function testGetResponseFactoryThrowsRuntimeException()
method testGetStreamFactoryThrowsRuntimeException (line 27) | public function testGetStreamFactoryThrowsRuntimeException()
method testGetServerRequestCreatorThrowsRuntimeException (line 35) | public function testGetServerRequestCreatorThrowsRuntimeException()
FILE: tests/Factory/Psr17/SlimHttpServerRequestCreatorTest.php
class SlimHttpServerRequestCreatorTest (line 23) | class SlimHttpServerRequestCreatorTest extends TestCase
method tearDown (line 29) | public function tearDown(): void
method testCreateServerRequestFromGlobals (line 43) | public function testCreateServerRequestFromGlobals()
method testCreateServerRequestFromGlobalsThrowsRuntimeException (line 59) | public function testCreateServerRequestFromGlobalsThrowsRuntimeExcepti...
method testCreateServerRequestFromGlobalsThrowsRuntimeExceptionIfNotInstanceOfServerRequestInterface (line 78) | public function testCreateServerRequestFromGlobalsThrowsRuntimeExcepti...
FILE: tests/Factory/ServerRequestCreatorFactoryTest.php
class ServerRequestCreatorFactoryTest (line 32) | class ServerRequestCreatorFactoryTest extends TestCase
method provideImplementations (line 34) | public static function provideImplementations()
method testCreateAppWithAllImplementations (line 50) | #[\PHPUnit\Framework\Attributes\DataProvider('provideImplementations')]
method testDetermineServerRequestCreatorReturnsDecoratedServerRequestCreator (line 62) | public function testDetermineServerRequestCreatorReturnsDecoratedServe...
method testDetermineServerRequestCreatorThrowsRuntimeException (line 76) | #[\PHPUnit\Framework\Attributes\RunInSeparateProcess]
method testSetPsr17FactoryProvider (line 85) | public function testSetPsr17FactoryProvider()
method testSetServerRequestCreatorWithoutDecorators (line 101) | #[\PHPUnit\Framework\Attributes\RunInSeparateProcess]
method testSetServerRequestCreatorWithDecorators (line 123) | #[\PHPUnit\Framework\Attributes\RunInSeparateProcess]
FILE: tests/Handlers/ErrorHandlerTest.php
class ErrorHandlerTest (line 31) | class ErrorHandlerTest extends TestCase
method getMockLogger (line 33) | private function getMockLogger(): LoggerInterface
method testDetermineRenderer (line 38) | public function testDetermineRenderer()
method testDetermineStatusCode (line 75) | public function testDetermineStatusCode()
method testForceContentType (line 104) | public function testForceContentType()
method testHalfValidContentType (line 121) | public function testHalfValidContentType()
method testDetermineContentTypeTextPlainMultiAcceptHeader (line 152) | public function testDetermineContentTypeTextPlainMultiAcceptHeader()
method testDetermineContentTypeApplicationJsonOrXml (line 184) | public function testDetermineContentTypeApplicationJsonOrXml()
method testAcceptableMediaTypeIsNotFirstInList (line 219) | public function testAcceptableMediaTypeIsNotFirstInList()
method testRegisterErrorRenderer (line 239) | public function testRegisterErrorRenderer()
method testSetDefaultErrorRenderer (line 252) | public function testSetDefaultErrorRenderer()
method testOptions (line 270) | public function testOptions()
method testWriteToErrorLog (line 285) | public function testWriteToErrorLog()
method testWriteToErrorLogShowTip (line 312) | public function testWriteToErrorLogShowTip()
method testWriteToErrorLogDoesNotShowTipIfErrorLogRendererIsNotPlainText (line 339) | public function testWriteToErrorLogDoesNotShowTipIfErrorLogRendererIsN...
method testDefaultErrorRenderer (line 368) | public function testDefaultErrorRenderer()
method testLogErrorRenderer (line 384) | public function testLogErrorRenderer()
FILE: tests/Handlers/Strategies/RequestResponseNamedArgsTest.php
class RequestResponseNamedArgsTest (line 18) | class RequestResponseNamedArgsTest extends TestCase
method setUp (line 25) | public function setUp(): void
method testCallingWithEmptyArguments (line 31) | public function testCallingWithEmptyArguments()
method testCallingWithKnownArguments (line 50) | public function testCallingWithKnownArguments()
method testCallingWithOptionalArguments (line 75) | public function testCallingWithOptionalArguments()
method testCallingWithUnknownAndVariadic (line 99) | public function testCallingWithUnknownAndVariadic()
method testCallingWithMixedKnownAndUnknownParametersAndVariadic (line 123) | public function testCallingWithMixedKnownAndUnknownParametersAndVariad...
FILE: tests/Middleware/BodyParsingMiddlewareTest.php
class BodyParsingMiddlewareTest (line 23) | class BodyParsingMiddlewareTest extends TestCase
method createRequestHandler (line 29) | protected function createRequestHandler(): RequestHandlerInterface
method createRequestWithBody (line 54) | protected function createRequestWithBody($contentType, $body)
method parsingProvider (line 67) | public static function parsingProvider()
method testParsing (line 151) | #[\PHPUnit\Framework\Attributes\DataProvider('parsingProvider')]
method testParsingWithARegisteredParser (line 163) | public function testParsingWithARegisteredParser()
method testParsingFailsWhenAnInvalidTypeIsReturned (line 179) | public function testParsingFailsWhenAnInvalidTypeIsReturned()
method testSettingAndGettingAParser (line 194) | public function testSettingAndGettingAParser()
method testGettingUnknownParser (line 209) | public function testGettingUnknownParser()
FILE: tests/Middleware/ContentLengthMiddlewareTest.php
class ContentLengthMiddlewareTest (line 17) | class ContentLengthMiddlewareTest extends TestCase
method testAddsContentLength (line 19) | public function testAddsContentLength()
FILE: tests/Middleware/ErrorMiddlewareTest.php
class ErrorMiddlewareTest (line 28) | class ErrorMiddlewareTest extends TestCase
method getMockLogger (line 30) | private function getMockLogger(): LoggerInterface
method testSetErrorHandler (line 35) | public function testSetErrorHandler()
method testSetDefaultErrorHandler (line 72) | public function testSetDefaultErrorHandler()
method testSetDefaultErrorHandlerThrowsException (line 108) | public function testSetDefaultErrorHandlerThrowsException()
method testGetErrorHandlerWillReturnDefaultErrorHandlerForUnhandledExceptions (line 129) | public function testGetErrorHandlerWillReturnDefaultErrorHandlerForUnh...
method testSuperclassExceptionHandlerHandlesExceptionWithSubclassExactMatch (line 142) | public function testSuperclassExceptionHandlerHandlesExceptionWithSubc...
method testSuperclassExceptionHandlerHandlesSubclassException (line 172) | public function testSuperclassExceptionHandlerHandlesSubclassException()
method testSuperclassExceptionHandlerDoesNotHandleSubclassException (line 210) | public function testSuperclassExceptionHandlerDoesNotHandleSubclassExc...
method testHandleMultipleExceptionsAddedAsArray (line 248) | public function testHandleMultipleExceptionsAddedAsArray()
method testErrorHandlerHandlesThrowables (line 288) | public function testErrorHandlerHandlesThrowables()
FILE: tests/Middleware/MethodOverrideMiddlewareTest.php
class MethodOverrideMiddlewareTest (line 19) | class MethodOverrideMiddlewareTest extends TestCase
method testHeader (line 21) | public function testHeader()
method testBodyParam (line 43) | public function testBodyParam()
method testHeaderPreferred (line 66) | public function testHeaderPreferred()
method testNoOverride (line 90) | public function testNoOverride()
method testNoOverrideRewindEofBodyStream (line 111) | public function testNoOverrideRewindEofBodyStream()
FILE: tests/Middleware/OutputBufferingMiddlewareTest.php
class OutputBufferingMiddlewareTest (line 22) | class OutputBufferingMiddlewareTest extends TestCase
method testStyleDefaultValid (line 24) | public function testStyleDefaultValid()
method testStyleCustomValid (line 35) | public function testStyleCustomValid()
method testStyleCustomInvalid (line 46) | public function testStyleCustomInvalid()
method testAppend (line 53) | public function testAppend()
method testPrepend (line 78) | public function testPrepend()
method testOutputBufferIsCleanedWhenThrowableIsCaught (line 103) | public function testOutputBufferIsCleanedWhenThrowableIsCaught()
FILE: tests/Middleware/RoutingMiddlewareTest.php
class RoutingMiddlewareTest (line 31) | class RoutingMiddlewareTest extends TestCase
method getRouteCollector (line 33) | protected function getRouteCollector()
method testRouteIsStoredOnSuccessfulMatch (line 42) | public function testRouteIsStoredOnSuccessfulMatch()
method testRouteIsNotStoredOnMethodNotAllowed (line 78) | public function testRouteIsNotStoredOnMethodNotAllowed()
method testRouteIsNotStoredOnNotFound (line 115) | public function testRouteIsNotStoredOnNotFound()
method testPerformRoutingThrowsExceptionOnInvalidRoutingResultsRouteStatus (line 152) | public function testPerformRoutingThrowsExceptionOnInvalidRoutingResul...
FILE: tests/MiddlewareDispatcherTest.php
class MiddlewareDispatcherTest (line 28) | class MiddlewareDispatcherTest extends TestCase
method setUpBeforeClass (line 30) | public static function setUpBeforeClass(): void
method testAddMiddleware (line 38) | public function testAddMiddleware(): void
method testNamedFunctionIsResolved (line 55) | public function testNamedFunctionIsResolved(): void
method testDeferredResolvedCallable (line 68) | public function testDeferredResolvedCallable(): void
method testDeferredResolvedCallableWithoutContainerAndNonAdvancedCallableResolver (line 97) | public function testDeferredResolvedCallableWithoutContainerAndNonAdva...
method testDeferredResolvedCallableWithDirectConstructorCall (line 121) | public function testDeferredResolvedCallableWithDirectConstructorCall(...
method deferredCallableProvider (line 141) | public static function deferredCallableProvider(): array
method testDeferredResolvedCallableWithContainerAndNonAdvancedCallableResolverUnableToResolveCallable (line 160) | #[\PHPUnit\Framework\Attributes\DataProvider('deferredCallableProvider')]
method testDeferredResolvedSlimCallable (line 204) | public function testDeferredResolvedSlimCallable(): void
method testDeferredResolvedClosureIsBoundToContainer (line 216) | public function testDeferredResolvedClosureIsBoundToContainer(): void
method testAddCallableBindsClosureToContainer (line 240) | public function testAddCallableBindsClosureToContainer(): void
method testResolvableReturnsInstantiatedObject (line 264) | public function testResolvableReturnsInstantiatedObject(): void
method testResolveThrowsExceptionWhenResolvableDoesNotImplementMiddlewareInterface (line 279) | public function testResolveThrowsExceptionWhenResolvableDoesNotImpleme...
method testResolveThrowsExceptionWithoutContainerAndUnresolvableClass (line 304) | public function testResolveThrowsExceptionWithoutContainerAndUnresolva...
method testResolveThrowsExceptionWithoutContainerNonAdvancedCallableResolverAndUnresolvableClass (line 317) | public function testResolveThrowsExceptionWithoutContainerNonAdvancedC...
method testExecutesKernelWithEmptyMiddlewareStack (line 339) | public function testExecutesKernelWithEmptyMiddlewareStack(): void
method testExecutesMiddlewareLastInFirstOut (line 356) | public function testExecutesMiddlewareLastInFirstOut(): void
method testDoesNotInstantiateDeferredMiddlewareInCaseOfAnEarlyReturningOuterMiddleware (line 448) | public function testDoesNotInstantiateDeferredMiddlewareInCaseOfAnEarl...
method testThrowsExceptionForDeferredNonMiddlewareInterfaceClasses (line 470) | public function testThrowsExceptionForDeferredNonMiddlewareInterfaceCl...
method testCanBeExecutedMultipleTimes (line 486) | public function testCanBeExecutedMultipleTimes(): void
method testCanBeReExecutedRecursivelyDuringDispatch (line 507) | public function testCanBeReExecutedRecursivelyDuringDispatch(): void
method testFetchesMiddlewareFromContainer (line 556) | public function testFetchesMiddlewareFromContainer(): void
method testMiddlewareGetsInstantiatedWithContainer (line 580) | public function testMiddlewareGetsInstantiatedWithContainer(): void
FILE: tests/Mocks/CallableTest.php
class CallableTest (line 15) | class CallableTest
method __construct (line 21) | public function __construct($container = null)
method toCall (line 26) | public function toCall()
FILE: tests/Mocks/InvocationStrategyTest.php
class InvocationStrategyTest (line 17) | class InvocationStrategyTest implements InvocationStrategyInterface
method __invoke (line 31) | public function __invoke(
FILE: tests/Mocks/InvokableTest.php
class InvokableTest (line 13) | class InvokableTest
method __invoke (line 17) | public function __invoke()
FILE: tests/Mocks/MiddlewareTest.php
class MiddlewareTest (line 19) | class MiddlewareTest implements MiddlewareInterface
method process (line 26) | public function process(ServerRequestInterface $request, RequestHandle...
FILE: tests/Mocks/MockAction.php
class MockAction (line 19) | class MockAction
method __call (line 21) | public function __call($name, array $arguments)
FILE: tests/Mocks/MockCustomException.php
class MockCustomException (line 15) | class MockCustomException extends Exception
FILE: tests/Mocks/MockCustomRequestHandlerInvocationStrategy.php
class MockCustomRequestHandlerInvocationStrategy (line 17) | class MockCustomRequestHandlerInvocationStrategy implements RequestHandl...
method __invoke (line 21) | public function __invoke(
FILE: tests/Mocks/MockMiddlewareSlimCallable.php
class MockMiddlewareSlimCallable (line 17) | class MockMiddlewareSlimCallable
method custom (line 24) | public function custom(ServerRequestInterface $request, RequestHandler...
FILE: tests/Mocks/MockMiddlewareWithConstructor.php
class MockMiddlewareWithConstructor (line 20) | class MockMiddlewareWithConstructor implements MiddlewareInterface
method __construct (line 30) | public function __construct(?ContainerInterface $container = null)
method process (line 35) | public function process(ServerRequestInterface $request, RequestHandle...
FILE: tests/Mocks/MockMiddlewareWithoutConstructor.php
class MockMiddlewareWithoutConstructor (line 18) | class MockMiddlewareWithoutConstructor implements MiddlewareInterface
method process (line 27) | public function process(ServerRequestInterface $request, RequestHandle...
FILE: tests/Mocks/MockMiddlewareWithoutInterface.php
class MockMiddlewareWithoutInterface (line 13) | class MockMiddlewareWithoutInterface
FILE: tests/Mocks/MockPsr17Factory.php
class MockPsr17Factory (line 15) | class MockPsr17Factory extends Psr17Factory
FILE: tests/Mocks/MockPsr17FactoryWithoutStreamFactory.php
class MockPsr17FactoryWithoutStreamFactory (line 15) | class MockPsr17FactoryWithoutStreamFactory extends Psr17Factory
FILE: tests/Mocks/MockRequestHandler.php
class MockRequestHandler (line 18) | class MockRequestHandler implements RequestHandlerInterface
method handle (line 29) | public function handle(ServerRequestInterface $request): ResponseInter...
method getCalledCount (line 41) | public function getCalledCount(): int
FILE: tests/Mocks/MockSequenceMiddleware.php
class MockSequenceMiddleware (line 18) | class MockSequenceMiddleware implements MiddlewareInterface
method __construct (line 30) | public function __construct()
method process (line 35) | public function process(ServerRequestInterface $request, RequestHandle...
FILE: tests/Mocks/MockStream.php
class MockStream (line 36) | class MockStream implements StreamInterface
method __construct (line 76) | public function __construct($body = '')
method __destruct (line 101) | public function __destruct()
method __toString (line 106) | public function __toString(): string
method close (line 119) | public function close(): void
method detach (line 129) | public function detach()
method getSize (line 143) | public function getSize(): ?int
method tell (line 168) | public function tell(): int
method eof (line 177) | public function eof(): bool
method isSeekable (line 182) | public function isSeekable(): bool
method seek (line 187) | public function seek($offset, $whence = SEEK_SET): void
method rewind (line 201) | public function rewind(): void
method isWritable (line 206) | public function isWritable(): bool
method write (line 211) | public function write($string): int
method isReadable (line 227) | public function isReadable(): bool
method read (line 232) | public function read($length): string
method getContents (line 241) | public function getContents(): string
method getMetadata (line 254) | public function getMetadata($key = null)
FILE: tests/Mocks/RequestHandlerTest.php
class RequestHandlerTest (line 20) | class RequestHandlerTest implements RequestHandlerInterface
method handle (line 25) | public function handle(ServerRequestInterface $request): ResponseInter...
method custom (line 47) | public function custom(ServerRequestInterface $request): ResponseInter...
FILE: tests/Mocks/SlowPokeStream.php
class SlowPokeStream (line 22) | class SlowPokeStream implements StreamInterface
method __construct (line 32) | public function __construct()
method __toString (line 37) | public function __toString(): string
method close (line 46) | public function close(): void
method detach (line 50) | public function detach()
method eof (line 55) | public function eof(): bool
method getContents (line 60) | public function getContents(): string
method getMetadata (line 65) | public function getMetadata($key = null)
method getSize (line 70) | public function getSize(): ?int
method isReadable (line 75) | public function isReadable(): bool
method isSeekable (line 80) | public function isSeekable(): bool
method isWritable (line 85) | public function isWritable(): bool
method read (line 90) | public function read($length): string
method rewind (line 98) | public function rewind(): void
method seek (line 103) | public function seek($offset, $whence = SEEK_SET): void
method tell (line 108) | public function tell(): int
method write (line 113) | public function write($string): int
FILE: tests/Mocks/SmallChunksStream.php
class SmallChunksStream (line 21) | class SmallChunksStream implements StreamInterface
method __construct (line 31) | public function __construct()
method __toString (line 36) | public function __toString(): string
method close (line 41) | public function close(): void
method detach (line 45) | public function detach()
method eof (line 50) | public function eof(): bool
method getContents (line 55) | public function getContents(): string
method getMetadata (line 60) | public function getMetadata($key = null)
method getSize (line 65) | public function getSize(): ?int
method isReadable (line 70) | public function isReadable(): bool
method isSeekable (line 75) | public function isSeekable(): bool
method isWritable (line 80) | public function isWritable(): bool
method read (line 85) | public function read($length): string
method rewind (line 93) | public function rewind(): void
method seek (line 98) | public function seek($offset, $whence = SEEK_SET): void
method tell (line 103) | public function tell(): int
method write (line 108) | public function write($string): int
FILE: tests/Providers/PSR7ObjectProvider.php
class PSR7ObjectProvider (line 30) | class PSR7ObjectProvider implements PSR7ObjectProviderInterface
method createServerRequest (line 38) | public function createServerRequest(
method getServerRequestFactory (line 69) | public function getServerRequestFactory(): ServerRequestFactoryInterface
method createResponse (line 79) | public function createResponse(int $statusCode = 200, string $reasonPh...
method getResponseFactory (line 89) | public function getResponseFactory(): ResponseFactoryInterface
method createStream (line 98) | public function createStream(string $contents = ''): StreamInterface
method getStreamFactory (line 108) | public function getStreamFactory(): StreamFactoryInterface
FILE: tests/Providers/PSR7ObjectProviderInterface.php
type PSR7ObjectProviderInterface (line 25) | interface PSR7ObjectProviderInterface
method getServerRequestFactory (line 30) | public function getServerRequestFactory(): ServerRequestFactoryInterface;
method getResponseFactory (line 35) | public function getResponseFactory(): ResponseFactoryInterface;
method getStreamFactory (line 40) | public function getStreamFactory(): StreamFactoryInterface;
method createServerRequest (line 48) | public function createServerRequest(string $uri, string $method = 'GET...
method createResponse (line 55) | public function createResponse(int $statusCode = 200, string $reasonPh...
method createStream (line 61) | public function createStream(string $contents = ''): StreamInterface;
FILE: tests/ResponseEmitterTest.php
class ResponseEmitterTest (line 38) | class ResponseEmitterTest extends TestCase
method setUp (line 40) | public function setUp(): void
method tearDown (line 45) | public function tearDown(): void
method testRespond (line 50) | public function testRespond(): void
method testRespondWithPaddedStreamFilterOutput (line 61) | public function testRespondWithPaddedStreamFilterOutput(): void
method testRespondIndeterminateLength (line 106) | public function testRespondIndeterminateLength(): void
method testResponseWithStreamReadYieldingLessBytesThanAsked (line 126) | public function testResponseWithStreamReadYieldingLessBytesThanAsked()...
method testResponseReplacesPreviouslySetHeaders (line 137) | public function testResponseReplacesPreviouslySetHeaders(): void
method testResponseDoesNotReplacePreviouslySetSetCookieHeaders (line 155) | public function testResponseDoesNotReplacePreviouslySetSetCookieHeader...
method testIsResponseEmptyWithNonEmptyBodyAndTriggeringStatusCode (line 173) | public function testIsResponseEmptyWithNonEmptyBodyAndTriggeringStatus...
method testIsResponseEmptyDoesNotReadAllDataFromNonEmptySeekableResponse (line 184) | public function testIsResponseEmptyDoesNotReadAllDataFromNonEmptySeeka...
method testIsResponseEmptyDoesNotDrainNonSeekableResponseWithContent (line 198) | public function testIsResponseEmptyDoesNotDrainNonSeekableResponseWith...
method testAvoidReadFromSlowStreamAccordingToStatus (line 211) | public function testAvoidReadFromSlowStreamAccordingToStatus(): void
method testIsResponseEmptyWithEmptyBody (line 225) | public function testIsResponseEmptyWithEmptyBody(): void
method testIsResponseEmptyWithZeroAsBody (line 233) | public function testIsResponseEmptyWithZeroAsBody(): void
method testWillHandleInvalidConnectionStatusWithADeterminateBody (line 244) | public function testWillHandleInvalidConnectionStatusWithADeterminateB...
method testWillHandleInvalidConnectionStatusWithAnIndeterminateBody (line 267) | public function testWillHandleInvalidConnectionStatusWithAnIndetermina...
FILE: tests/Routing/DispatcherTest.php
class DispatcherTest (line 27) | class DispatcherTest extends TestCase
method testCreateDispatcher (line 29) | public function testCreateDispatcher()
method testRouteCacheFileCanBeDispatched (line 45) | public function testRouteCacheFileCanBeDispatched()
method testCreateDispatcherReturnsSameDispatcherASecondTime (line 83) | public function testCreateDispatcherReturnsSameDispatcherASecondTime()
method testGetAllowedMethods (line 99) | public function testGetAllowedMethods()
method testDispatch (line 117) | public function testDispatch()
FILE: tests/Routing/FastRouteDispatcherTest.php
class FastRouteDispatcherTest (line 21) | class FastRouteDispatcherTest extends TestCase
method testFoundDispatches (line 26) | #[\PHPUnit\Framework\Attributes\DataProvider('provideFoundDispatchCase...
method generateDispatcherOptions (line 42) | private function generateDispatcherOptions()
method getDataGeneratorClass (line 50) | protected function getDataGeneratorClass()
method getDispatcherClass (line 55) | protected function getDispatcherClass()
method testNotFoundDispatches (line 63) | #[\PHPUnit\Framework\Attributes\DataProvider('provideNotFoundDispatchC...
method testMethodNotAllowedDispatches (line 81) | #[\PHPUnit\Framework\Attributes\DataProvider('provideMethodNotAllowedD...
method testGetAllowedMethods (line 99) | #[\PHPUnit\Framework\Attributes\DataProvider('provideMethodNotAllowedD...
method testDuplicateVariableNameError (line 110) | public function testDuplicateVariableNameError()
method testDuplicateVariableRoute (line 120) | public function testDuplicateVariableRoute()
method testDuplicateStaticRoute (line 131) | public function testDuplicateStaticRoute()
method testShadowedStaticRoute (line 146) | public function testShadowedStaticRoute()
method testCapturing (line 158) | public function testCapturing()
method provideFoundDispatchCases (line 168) | public static function provideFoundDispatchCases()
method provideNotFoundDispatchCases (line 467) | public static function provideNotFoundDispatchCases()
method provideMethodNotAllowedDispatchCases (line 544) | public static function provideMethodNotAllowedDispatchCases()
FILE: tests/Routing/RouteCollectorProxyTest.php
class RouteCollectorProxyTest (line 26) | class RouteCollectorProxyTest extends TestCase
method testGetResponseFactory (line 28) | public function testGetResponseFactory()
method testGetCallableResolver (line 44) | public function testGetCallableResolver()
method testGetContainerReturnsInjectedInstance (line 60) | public function testGetContainerReturnsInjectedInstance()
method testGetRouteCollectorReturnsInjectedInstance (line 78) | public function testGetRouteCollectorReturnsInjectedInstance()
method testGetSetBasePath (line 98) | public function testGetSetBasePath()
method testGet (line 122) | public function testGet()
method testPost (line 155) | public function testPost()
method testPut (line 188) | public function testPut()
method testPatch (line 221) | public function testPatch()
method testDelete (line 254) | public function testDelete()
method testOptions (line 287) | public function testOptions()
method testAny (line 320) | public function testAny()
method testMap (line 353) | public function testMap()
method testRedirect (line 387) | public function testRedirect()
method testGroup (line 432) | public function testGroup()
FILE: tests/Routing/RouteCollectorTest.php
class RouteCollectorTest (line 29) | class RouteCollectorTest extends TestCase
method tearDown (line 36) | public function tearDown(): void
method testGetSetBasePath (line 43) | public function testGetSetBasePath()
method testMap (line 56) | public function testMap()
method testMapPrependsGroupPattern (line 69) | public function testMapPrependsGroupPattern()
method testGetRouteInvocationStrategy (line 92) | public function testGetRouteInvocationStrategy()
method testRemoveNamedRoute (line 109) | public function testRemoveNamedRoute()
method testRemoveNamedRouteWithARouteThatDoesNotExist (line 129) | public function testRemoveNamedRouteWithARouteThatDoesNotExist()
method testLookupRouteThrowsExceptionIfRouteNotFound (line 140) | public function testLookupRouteThrowsExceptionIfRouteNotFound()
method testCacheFileExistsAndIsNotReadable (line 154) | public function testCacheFileExistsAndIsNotReadable()
method testCacheFileDoesNotExistsAndDirectoryIsNotWritable (line 172) | public function testCacheFileDoesNotExistsAndDirectoryIsNotWritable()
method testSetCacheFileViaConstructor (line 189) | public function testSetCacheFileViaConstructor()
FILE: tests/Routing/RouteContextTest.php
class RouteContextTest (line 21) | class RouteContextTest extends TestCase
method testCanCreateInstanceFromServerRequest (line 23) | public function testCanCreateInstanceFromServerRequest(): void
method testCanCreateInstanceWithoutRoute (line 43) | public function testCanCreateInstanceWithoutRoute(): void
method testCanCreateInstanceWithoutBasePathAndThrowExceptionIfGetBasePathIsCalled (line 57) | public function testCanCreateInstanceWithoutBasePathAndThrowExceptionI...
method requiredRouteContextRequestAttributes (line 73) | public static function requiredRouteContextRequestAttributes(): array
method testCannotCreateInstanceIfRequestIsMissingAttributes (line 85) | #[\PHPUnit\Framework\Attributes\DataProvider('requiredRouteContextRequ...
method createServerRequestWithRouteAttributes (line 95) | private function createServerRequestWithRouteAttributes(): ServerReque...
FILE: tests/Routing/RouteParserTest.php
class RouteParserTest (line 18) | class RouteParserTest extends TestCase
method urlForCases (line 20) | public static function urlForCases()
method testRelativePathForWithNoBasePath (line 82) | public function testRelativePathForWithNoBasePath()
method testBasePathIsIgnoreInRelativePathFor (line 99) | public function testBasePathIsIgnoreInRelativePathFor()
method testUrlForWithBasePath (line 125) | #[\PHPUnit\Framework\Attributes\DataProvider('urlForCases')]
method testUrlForWithMissingSegmentData (line 147) | public function testUrlForWithMissingSegmentData()
method testUrlForRouteThatDoesNotExist (line 163) | public function testUrlForRouteThatDoesNotExist()
method testFullUrlFor (line 176) | public function testFullUrlFor()
FILE: tests/Routing/RouteResolverTest.php
class RouteResolverTest (line 24) | class RouteResolverTest extends TestCase
method computeRoutingResultsDataProvider (line 26) | public static function computeRoutingResultsDataProvider(): array
method testComputeRoutingResults (line 43) | #[\PHPUnit\Framework\Attributes\DataProvider('computeRoutingResultsDat...
method testResolveRoute (line 72) | public function testResolveRoute()
FILE: tests/Routing/RouteRunnerTest.php
class RouteRunnerTest (line 24) | class RouteRunnerTest extends TestCase
method testRoutingIsPerformedIfRoutingResultsAreUnavailable (line 26) | public function testRoutingIsPerformedIfRoutingResultsAreUnavailable()
FILE: tests/Routing/RouteTest.php
class RouteTest (line 43) | class RouteTest extends TestCase
method createRoute (line 51) | public function createRoute($methods = 'GET', string $pattern = '/', $...
method testConstructor (line 110) | public function testConstructor()
method testGetMethodsReturnsArrayWhenConstructedWithString (line 124) | public function testGetMethodsReturnsArrayWhenConstructedWithString()
method testGetMethods (line 131) | public function testGetMethods()
method testGetPattern (line 139) | public function testGetPattern()
method testGetCallable (line 146) | public function testGetCallable()
method testGetCallableResolver (line 153) | public function testGetCallableResolver()
method testGetInvocationStrategy (line 173) | public function testGetInvocationStrategy()
method testSetInvocationStrategy (line 197) | public function testSetInvocationStrategy()
method testGetGroups (line 219) | public function testGetGroups()
method testArgumentSetting (line 252) | public function testArgumentSetting()
method testAddMiddleware (line 270) | public function testAddMiddleware()
method testAddMiddlewareOnGroup (line 287) | public function testAddMiddlewareOnGroup()
method testAddClosureMiddleware (line 342) | public function testAddClosureMiddleware()
method testAddMiddlewareUsingDeferredResolution (line 358) | public function testAddMiddlewareUsingDeferredResolution()
method testAddMiddlewareAsStringNotImplementingInterfaceThrowsException (line 373) | public function testAddMiddlewareAsStringNotImplementingInterfaceThrow...
method testIdentifier (line 385) | public function testIdentifier()
method testSetName (line 391) | public function testSetName()
method testControllerMethodAsStringResolvesWithoutContainer (line 398) | public function testControllerMethodAsStringResolvesWithoutContainer()
method testControllerMethodAsStringResolvesWithContainer (line 415) | public function testControllerMethodAsStringResolvesWithContainer()
method testProcessWhenReturningAResponse (line 467) | public function testProcessWhenReturningAResponse()
method testRouteCallableDoesNotAppendEchoedOutput (line 485) | public function testRouteCallableDoesNotAppendEchoedOutput()
method testRouteCallableAppendsCorrectOutputToResponse (line 509) | public function testRouteCallableAppendsCorrectOutputToResponse()
method testInvokeWithException (line 523) | public function testInvokeWithException()
method testInvokeDeferredCallableWithNoContainer (line 539) | public function testInvokeDeferredCallableWithNoContainer()
method testInvokeDeferredCallableWithContainer (line 573) | public function testInvokeDeferredCallableWithContainer()
method testInvokeUsesRequestHandlerStrategyForRequestHandlers (line 608) | public function testInvokeUsesRequestHandlerStrategyForRequestHandlers()
method testInvokeUsesUserSetStrategyForRequestHandlers (line 645) | public function testInvokeUsesUserSetStrategyForRequestHandlers()
method testRequestHandlerStrategyAppendsRouteArgumentsAsAttributesToRequest (line 680) | public function testRequestHandlerStrategyAppendsRouteArgumentsAsAttri...
method testPatternCanBeChanged (line 729) | public function testPatternCanBeChanged()
method testChangingCallableWithNoContainer (line 740) | public function testChangingCallableWithNoContainer()
method testChangingCallableWithContainer (line 775) | public function testChangingCallableWithContainer()
method testRouteCallableIsResolvedUsingContainerWhenCallableResolverIsPresent (line 814) | public function testRouteCallableIsResolvedUsingContainerWhenCallableR...
FILE: tests/TestCase.php
class TestCase (line 30) | abstract class TestCase extends PhpUnitTestCase
method getServerRequestFactory (line 37) | protected function getServerRequestFactory(): ServerRequestFactoryInte...
method getResponseFactory (line 46) | protected function getResponseFactory(): ResponseFactoryInterface
method getStreamFactory (line 55) | protected function getStreamFactory(): StreamFactoryInterface
method getCallableResolver (line 66) | protected function getCallableResolver(?ContainerInterface $container ...
method createMiddlewareDispatcher (line 78) | protected function createMiddlewareDispatcher(
method createServerRequest (line 96) | protected function createServerRequest(
method createResponse (line 110) | protected function createResponse(int $statusCode = 200, string $reaso...
method createStream (line 120) | protected function createStream(string $contents = ''): StreamInterface
method setAccessible (line 130) | protected function setAccessible($ref, bool $accessible = true): void
Condensed preview — 145 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (620K chars).
[
{
"path": ".coveralls.yml",
"chars": 33,
"preview": "json_path: coveralls-upload.json\n"
},
{
"path": ".editorconfig",
"chars": 220,
"preview": "root = true\n\n[*]\ncharset = utf-8\nend_of_line = lf\ninsert_final_newline = true\nindent_style = space\nindent_size = 4\ntrim_"
},
{
"path": ".gitattributes",
"chars": 607,
"preview": "# Enforce Unix newlines\n* text=auto eol=lf\n\n# Exclude unused files\n# see: https://redd.it/2jzp6k\n/.coveralls.yml exp"
},
{
"path": ".github/FUNDING.yml",
"chars": 57,
"preview": "open_collective: slimphp\ntidelift: \"packagist/slim/slim\"\n"
},
{
"path": ".github/dependabot.yml",
"chars": 255,
"preview": "version: 2\nupdates:\n- package-ecosystem: \"github-actions\"\n directory: \"/\"\n schedule:\n interval: \"monthly\"\n- package"
},
{
"path": ".github/workflows/tests.yml",
"chars": 1594,
"preview": "name: Tests\n\npermissions:\n contents: read\n\non: [push, pull_request]\n\njobs:\n tests:\n name: Tests PHP ${{ matrix.php "
},
{
"path": ".gitignore",
"chars": 107,
"preview": ".DS_Store\n.idea\n.phpunit.result.cache\n.phpunit.cache/\ncomposer.lock\nphpunit.xml\nclover.xml\nvendor\ncoverage\n"
},
{
"path": "CHANGELOG.md",
"chars": 27594,
"preview": "# Changelog\n\n## [Unreleased]\n\n### Fixed\n\n### Added\n\n### Changed\n\n### Removed\n\n## 4.15.1 - 2025-11-21\n\n## Fixed\n\n- Allow "
},
{
"path": "CODE_OF_CONDUCT.md",
"chars": 997,
"preview": "# Code of Conduct\n\nThe Slim Framework code of conduct is derived from the Ruby code of conduct. This document provides c"
},
{
"path": "CONTRIBUTING.md",
"chars": 816,
"preview": "# How to Contribute\n\n## Pull Requests\n\n1. Fork the Slim Framework repository\n2. Create a new branch for each feature or "
},
{
"path": "LICENSE.md",
"chars": 1062,
"preview": "Copyright (c) 2011-2022 Josh Lockhart\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof t"
},
{
"path": "MAINTAINERS.md",
"chars": 946,
"preview": "# Maintainers\n\nThere aren't many rules for maintainers of Slim to remember; what we have is listed here.\n\n## We don't me"
},
{
"path": "README.md",
"chars": 8369,
"preview": "# Slim Framework\n\n[](ht"
},
{
"path": "SECURITY.md",
"chars": 286,
"preview": "# Security Policy\n\n### Supported Versions\n\n\n| Version | Supported |\n| ------- | ------------------ |\n| 3.x.x "
},
{
"path": "Slim/App.php",
"chars": 7048,
"preview": "<?php\n\n/**\n * Slim Framework (https://slimframework.com)\n *\n * @license https://github.com/slimphp/Slim/blob/4.x/LICENSE"
},
{
"path": "Slim/CallableResolver.php",
"chars": 6074,
"preview": "<?php\n\n/**\n * Slim Framework (https://slimframework.com)\n *\n * @license https://github.com/slimphp/Slim/blob/4.x/LICENSE"
},
{
"path": "Slim/Error/AbstractErrorRenderer.php",
"chars": 1200,
"preview": "<?php\n\n/**\n * Slim Framework (https://slimframework.com)\n *\n * @license https://github.com/slimphp/Slim/blob/4.x/LICENSE"
},
{
"path": "Slim/Error/Renderers/HtmlErrorRenderer.php",
"chars": 2733,
"preview": "<?php\n\n/**\n * Slim Framework (https://slimframework.com)\n *\n * @license https://github.com/slimphp/Slim/blob/4.x/LICENSE"
},
{
"path": "Slim/Error/Renderers/JsonErrorRenderer.php",
"chars": 1405,
"preview": "<?php\n\n/**\n * Slim Framework (https://slimframework.com)\n *\n * @license https://github.com/slimphp/Slim/blob/4.x/LICENSE"
},
{
"path": "Slim/Error/Renderers/PlainTextErrorRenderer.php",
"chars": 1468,
"preview": "<?php\n\n/**\n * Slim Framework (https://slimframework.com)\n *\n * @license https://github.com/slimphp/Slim/blob/4.x/LICENSE"
},
{
"path": "Slim/Error/Renderers/XmlErrorRenderer.php",
"chars": 1664,
"preview": "<?php\n\n/**\n * Slim Framework (https://slimframework.com)\n *\n * @license https://github.com/slimphp/Slim/blob/4.x/LICENSE"
},
{
"path": "Slim/Exception/HttpBadRequestException.php",
"chars": 596,
"preview": "<?php\n\n/**\n * Slim Framework (https://slimframework.com)\n *\n * @license https://github.com/slimphp/Slim/blob/4.x/LICENSE"
},
{
"path": "Slim/Exception/HttpException.php",
"chars": 1293,
"preview": "<?php\n\n/**\n * Slim Framework (https://slimframework.com)\n *\n * @license https://github.com/slimphp/Slim/blob/4.x/LICENSE"
},
{
"path": "Slim/Exception/HttpForbiddenException.php",
"chars": 553,
"preview": "<?php\n\n/**\n * Slim Framework (https://slimframework.com)\n *\n * @license https://github.com/slimphp/Slim/blob/4.x/LICENSE"
},
{
"path": "Slim/Exception/HttpGoneException.php",
"chars": 545,
"preview": "<?php\n\n/**\n * Slim Framework (https://slimframework.com)\n *\n * @license https://github.com/slimphp/Slim/blob/4.x/LICENSE"
},
{
"path": "Slim/Exception/HttpInternalServerErrorException.php",
"chars": 605,
"preview": "<?php\n\n/**\n * Slim Framework (https://slimframework.com)\n *\n * @license https://github.com/slimphp/Slim/blob/4.x/LICENSE"
},
{
"path": "Slim/Exception/HttpMethodNotAllowedException.php",
"chars": 1089,
"preview": "<?php\n\n/**\n * Slim Framework (https://slimframework.com)\n *\n * @license https://github.com/slimphp/Slim/blob/4.x/LICENSE"
},
{
"path": "Slim/Exception/HttpNotFoundException.php",
"chars": 562,
"preview": "<?php\n\n/**\n * Slim Framework (https://slimframework.com)\n *\n * @license https://github.com/slimphp/Slim/blob/4.x/LICENSE"
},
{
"path": "Slim/Exception/HttpNotImplementedException.php",
"chars": 591,
"preview": "<?php\n\n/**\n * Slim Framework (https://slimframework.com)\n *\n * @license https://github.com/slimphp/Slim/blob/4.x/LICENSE"
},
{
"path": "Slim/Exception/HttpSpecializedException.php",
"chars": 789,
"preview": "<?php\n\n/**\n * Slim Framework (https://slimframework.com)\n *\n * @license https://github.com/slimphp/Slim/blob/4.x/LICENSE"
},
{
"path": "Slim/Exception/HttpTooManyRequestsException.php",
"chars": 674,
"preview": "<?php\n\n/**\n * Slim Framework (https://slimframework.com)\n *\n * @license https://github.com/slimphp/Slim/blob/4.x/LICENSE"
},
{
"path": "Slim/Exception/HttpUnauthorizedException.php",
"chars": 552,
"preview": "<?php\n\n/**\n * Slim Framework (https://slimframework.com)\n *\n * @license https://github.com/slimphp/Slim/blob/4.x/LICENSE"
},
{
"path": "Slim/Factory/AppFactory.php",
"chars": 7935,
"preview": "<?php\n\n/**\n * Slim Framework (https://slimframework.com)\n *\n * @license https://github.com/slimphp/Slim/blob/4.x/LICENSE"
},
{
"path": "Slim/Factory/Psr17/GuzzlePsr17Factory.php",
"chars": 577,
"preview": "<?php\n\n/**\n * Slim Framework (https://slimframework.com)\n *\n * @license https://github.com/slimphp/Slim/blob/4.x/LICENSE"
},
{
"path": "Slim/Factory/Psr17/HttpSoftPsr17Factory.php",
"chars": 607,
"preview": "<?php\n\n/**\n * Slim Framework (https://slimframework.com)\n *\n * @license https://github.com/slimphp/Slim/blob/4.x/LICENSE"
},
{
"path": "Slim/Factory/Psr17/LaminasDiactorosPsr17Factory.php",
"chars": 606,
"preview": "<?php\n\n/**\n * Slim Framework (https://slimframework.com)\n *\n * @license https://github.com/slimphp/Slim/blob/4.x/LICENSE"
},
{
"path": "Slim/Factory/Psr17/NyholmPsr17Factory.php",
"chars": 1167,
"preview": "<?php\n\ndeclare(strict_types=1);\n\nnamespace Slim\\Factory\\Psr17;\n\nuse Slim\\Interfaces\\ServerRequestCreatorInterface;\n\nclas"
},
{
"path": "Slim/Factory/Psr17/Psr17Factory.php",
"chars": 2796,
"preview": "<?php\n\n/**\n * Slim Framework (https://slimframework.com)\n *\n * @license https://github.com/slimphp/Slim/blob/4.x/LICENSE"
},
{
"path": "Slim/Factory/Psr17/Psr17FactoryProvider.php",
"chars": 1077,
"preview": "<?php\n\n/**\n * Slim Framework (https://slimframework.com)\n *\n * @license https://github.com/slimphp/Slim/blob/4.x/LICENSE"
},
{
"path": "Slim/Factory/Psr17/ServerRequestCreator.php",
"chars": 1165,
"preview": "<?php\n\n/**\n * Slim Framework (https://slimframework.com)\n *\n * @license https://github.com/slimphp/Slim/blob/4.x/LICENSE"
},
{
"path": "Slim/Factory/Psr17/SlimHttpPsr17Factory.php",
"chars": 1144,
"preview": "<?php\n\n/**\n * Slim Framework (https://slimframework.com)\n *\n * @license https://github.com/slimphp/Slim/blob/4.x/LICENSE"
},
{
"path": "Slim/Factory/Psr17/SlimHttpServerRequestCreator.php",
"chars": 1622,
"preview": "<?php\n\n/**\n * Slim Framework (https://slimframework.com)\n *\n * @license https://github.com/slimphp/Slim/blob/4.x/LICENSE"
},
{
"path": "Slim/Factory/Psr17/SlimPsr17Factory.php",
"chars": 600,
"preview": "<?php\n\n/**\n * Slim Framework (https://slimframework.com)\n *\n * @license https://github.com/slimphp/Slim/blob/4.x/LICENSE"
},
{
"path": "Slim/Factory/ServerRequestCreatorFactory.php",
"chars": 3079,
"preview": "<?php\n\n/**\n * Slim Framework (https://slimframework.com)\n *\n * @license https://github.com/slimphp/Slim/blob/4.x/LICENSE"
},
{
"path": "Slim/Handlers/ErrorHandler.php",
"chars": 9948,
"preview": "<?php\n\n/**\n * Slim Framework (https://slimframework.com)\n *\n * @license https://github.com/slimphp/Slim/blob/4.x/LICENSE"
},
{
"path": "Slim/Handlers/Strategies/RequestHandler.php",
"chars": 1366,
"preview": "<?php\n\n/**\n * Slim Framework (https://slimframework.com)\n *\n * @license https://github.com/slimphp/Slim/blob/4.x/LICENSE"
},
{
"path": "Slim/Handlers/Strategies/RequestResponse.php",
"chars": 1102,
"preview": "<?php\n\n/**\n * Slim Framework (https://slimframework.com)\n *\n * @license https://github.com/slimphp/Slim/blob/4.x/LICENSE"
},
{
"path": "Slim/Handlers/Strategies/RequestResponseArgs.php",
"chars": 1033,
"preview": "<?php\n\n/**\n * Slim Framework (https://slimframework.com)\n *\n * @license https://github.com/slimphp/Slim/blob/4.x/LICENSE"
},
{
"path": "Slim/Handlers/Strategies/RequestResponseNamedArgs.php",
"chars": 1018,
"preview": "<?php\n\n/**\n * Slim Framework (https://slimframework.com)\n *\n * @license https://github.com/slimphp/Slim/blob/4.x/LICENSE"
},
{
"path": "Slim/Interfaces/AdvancedCallableResolverInterface.php",
"chars": 665,
"preview": "<?php\n\n/**\n * Slim Framework (https://slimframework.com)\n *\n * @license https://github.com/slimphp/Slim/blob/4.x/LICENSE"
},
{
"path": "Slim/Interfaces/CallableResolverInterface.php",
"chars": 422,
"preview": "<?php\n\n/**\n * Slim Framework (https://slimframework.com)\n *\n * @license https://github.com/slimphp/Slim/blob/4.x/LICENSE"
},
{
"path": "Slim/Interfaces/DispatcherInterface.php",
"chars": 568,
"preview": "<?php\n\n/**\n * Slim Framework (https://slimframework.com)\n *\n * @license https://github.com/slimphp/Slim/blob/4.x/LICENSE"
},
{
"path": "Slim/Interfaces/ErrorHandlerInterface.php",
"chars": 551,
"preview": "<?php\n\n/**\n * Slim Framework (https://slimframework.com)\n *\n * @license https://github.com/slimphp/Slim/blob/4.x/LICENSE"
},
{
"path": "Slim/Interfaces/ErrorRendererInterface.php",
"chars": 337,
"preview": "<?php\n\n/**\n * Slim Framework (https://slimframework.com)\n *\n * @license https://github.com/slimphp/Slim/blob/4.x/LICENSE"
},
{
"path": "Slim/Interfaces/InvocationStrategyInterface.php",
"chars": 1035,
"preview": "<?php\n\n/**\n * Slim Framework (https://slimframework.com)\n *\n * @license https://github.com/slimphp/Slim/blob/4.x/LICENSE"
},
{
"path": "Slim/Interfaces/MiddlewareDispatcherInterface.php",
"chars": 1195,
"preview": "<?php\n\n/**\n * Slim Framework (https://slimframework.com)\n *\n * @license https://github.com/slimphp/Slim/blob/4.x/LICENSE"
},
{
"path": "Slim/Interfaces/Psr17FactoryInterface.php",
"chars": 1235,
"preview": "<?php\n\n/**\n * Slim Framework (https://slimframework.com)\n *\n * @license https://github.com/slimphp/Slim/blob/4.x/LICENSE"
},
{
"path": "Slim/Interfaces/Psr17FactoryProviderInterface.php",
"chars": 522,
"preview": "<?php\n\n/**\n * Slim Framework (https://slimframework.com)\n *\n * @license https://github.com/slimphp/Slim/blob/4.x/LICENSE"
},
{
"path": "Slim/Interfaces/RequestHandlerInvocationStrategyInterface.php",
"chars": 289,
"preview": "<?php\n\n/**\n * Slim Framework (https://slimframework.com)\n *\n * @license https://github.com/slimphp/Slim/blob/4.x/LICENSE"
},
{
"path": "Slim/Interfaces/RouteCollectorInterface.php",
"chars": 2553,
"preview": "<?php\n\n/**\n * Slim Framework (https://slimframework.com)\n *\n * @license https://github.com/slimphp/Slim/blob/4.x/LICENSE"
},
{
"path": "Slim/Interfaces/RouteCollectorProxyInterface.php",
"chars": 3810,
"preview": "<?php\n\n/**\n * Slim Framework (https://slimframework.com)\n *\n * @license https://github.com/slimphp/Slim/blob/4.x/LICENSE"
},
{
"path": "Slim/Interfaces/RouteGroupInterface.php",
"chars": 1076,
"preview": "<?php\n\n/**\n * Slim Framework (https://slimframework.com)\n *\n * @license https://github.com/slimphp/Slim/blob/4.x/LICENSE"
},
{
"path": "Slim/Interfaces/RouteInterface.php",
"chars": 2978,
"preview": "<?php\n\n/**\n * Slim Framework (https://slimframework.com)\n *\n * @license https://github.com/slimphp/Slim/blob/4.x/LICENSE"
},
{
"path": "Slim/Interfaces/RouteParserInterface.php",
"chars": 2177,
"preview": "<?php\n\n/**\n * Slim Framework (https://slimframework.com)\n *\n * @license https://github.com/slimphp/Slim/blob/4.x/LICENSE"
},
{
"path": "Slim/Interfaces/RouteResolverInterface.php",
"chars": 387,
"preview": "<?php\n\ndeclare(strict_types=1);\n\nnamespace Slim\\Interfaces;\n\nuse Slim\\Routing\\RoutingResults;\n\ninterface RouteResolverIn"
},
{
"path": "Slim/Interfaces/ServerRequestCreatorInterface.php",
"chars": 365,
"preview": "<?php\n\n/**\n * Slim Framework (https://slimframework.com)\n *\n * @license https://github.com/slimphp/Slim/blob/4.x/LICENSE"
},
{
"path": "Slim/Logger.php",
"chars": 637,
"preview": "<?php\n\n/**\n * Slim Framework (https://slimframework.com)\n *\n * @license https://github.com/slimphp/Slim/blob/4.x/LICENSE"
},
{
"path": "Slim/Middleware/BodyParsingMiddleware.php",
"chars": 5942,
"preview": "<?php\n\n/**\n * Slim Framework (https://slimframework.com)\n *\n * @license https://github.com/slimphp/Slim/blob/4.x/LICENSE"
},
{
"path": "Slim/Middleware/ContentLengthMiddleware.php",
"chars": 919,
"preview": "<?php\n\n/**\n * Slim Framework (https://slimframework.com)\n *\n * @license https://github.com/slimphp/Slim/blob/4.x/LICENSE"
},
{
"path": "Slim/Middleware/ErrorMiddleware.php",
"chars": 6605,
"preview": "<?php\n\n/**\n * Slim Framework (https://slimframework.com)\n *\n * @license https://github.com/slimphp/Slim/blob/4.x/LICENSE"
},
{
"path": "Slim/Middleware/MethodOverrideMiddleware.php",
"chars": 1238,
"preview": "<?php\n\n/**\n * Slim Framework (https://slimframework.com)\n *\n * @license https://github.com/slimphp/Slim/blob/4.x/LICENSE"
},
{
"path": "Slim/Middleware/OutputBufferingMiddleware.php",
"chars": 2103,
"preview": "<?php\n\n/**\n * Slim Framework (https://slimframework.com)\n *\n * @license https://github.com/slimphp/Slim/blob/4.x/LICENSE"
},
{
"path": "Slim/Middleware/RoutingMiddleware.php",
"chars": 3281,
"preview": "<?php\n\n/**\n * Slim Framework (https://slimframework.com)\n *\n * @license https://github.com/slimphp/Slim/blob/4.x/LICENSE"
},
{
"path": "Slim/MiddlewareDispatcher.php",
"chars": 9460,
"preview": "<?php\n\n/**\n * Slim Framework (https://slimframework.com)\n *\n * @license https://github.com/slimphp/Slim/blob/4.x/LICENSE"
},
{
"path": "Slim/ResponseEmitter.php",
"chars": 3577,
"preview": "<?php\n\n/**\n * Slim Framework (https://slimframework.com)\n *\n * @license https://github.com/slimphp/Slim/blob/4.x/LICENSE"
},
{
"path": "Slim/Routing/Dispatcher.php",
"chars": 2472,
"preview": "<?php\n\ndeclare(strict_types=1);\n\nnamespace Slim\\Routing;\n\nuse FastRoute\\DataGenerator\\GroupCountBased;\nuse FastRoute\\Rou"
},
{
"path": "Slim/Routing/FastRouteDispatcher.php",
"chars": 3179,
"preview": "<?php\n\n/**\n * Slim Framework (https://slimframework.com)\n *\n * @license https://github.com/slimphp/Slim/blob/4.x/LICENSE"
},
{
"path": "Slim/Routing/Route.php",
"chars": 9054,
"preview": "<?php\n\n/**\n * Slim Framework (https://slimframework.com)\n *\n * @license https://github.com/slimphp/Slim/blob/4.x/LICENSE"
},
{
"path": "Slim/Routing/RouteCollector.php",
"chars": 7988,
"preview": "<?php\n\n/**\n * Slim Framework (https://slimframework.com)\n *\n * @license https://github.com/slimphp/Slim/blob/4.x/LICENSE"
},
{
"path": "Slim/Routing/RouteCollectorProxy.php",
"chars": 4906,
"preview": "<?php\n\n/**\n * Slim Framework (https://slimframework.com)\n *\n * @license https://github.com/slimphp/Slim/blob/4.x/LICENSE"
},
{
"path": "Slim/Routing/RouteContext.php",
"chars": 2426,
"preview": "<?php\n\n/**\n * Slim Framework (https://slimframework.com)\n *\n * @license https://github.com/slimphp/Slim/blob/4.x/LICENSE"
},
{
"path": "Slim/Routing/RouteGroup.php",
"chars": 2815,
"preview": "<?php\n\n/**\n * Slim Framework (https://slimframework.com)\n *\n * @license https://github.com/slimphp/Slim/blob/4.x/LICENSE"
},
{
"path": "Slim/Routing/RouteParser.php",
"chars": 3906,
"preview": "<?php\n\n/**\n * Slim Framework (https://slimframework.com)\n *\n * @license https://github.com/slimphp/Slim/blob/4.x/LICENSE"
},
{
"path": "Slim/Routing/RouteResolver.php",
"chars": 1512,
"preview": "<?php\n\n/**\n * Slim Framework (https://slimframework.com)\n *\n * @license https://github.com/slimphp/Slim/blob/4.x/LICENSE"
},
{
"path": "Slim/Routing/RouteRunner.php",
"chars": 2656,
"preview": "<?php\n\n/**\n * Slim Framework (https://slimframework.com)\n *\n * @license https://github.com/slimphp/Slim/blob/4.x/LICENSE"
},
{
"path": "Slim/Routing/RoutingResults.php",
"chars": 2391,
"preview": "<?php\n\n/**\n * Slim Framework (https://slimframework.com)\n *\n * @license https://github.com/slimphp/Slim/blob/4.x/LICENSE"
},
{
"path": "UPGRADING.md",
"chars": 2446,
"preview": "# How to upgrade\n\n* [2654] - `RouteParser::pathFor()` and `RouteParser::relativePathFor()` are deprecated. Use `RoutePar"
},
{
"path": "composer.json",
"chars": 3577,
"preview": "{\n \"name\": \"slim/slim\",\n \"type\": \"library\",\n \"description\": \"Slim is a PHP micro framework that helps you quick"
},
{
"path": "phpcs.xml.dist",
"chars": 423,
"preview": "<?xml version=\"1.0\"?>\n<ruleset name=\"Slim coding standard\">\n <description>Slim coding standard</description>\n\n <!-"
},
{
"path": "phpstan.neon.dist",
"chars": 53,
"preview": "parameters:\n level: max\n paths:\n - Slim\n"
},
{
"path": "phpunit.xml.dist",
"chars": 873,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<phpunit xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n xsi:noNam"
},
{
"path": "psalm.xml",
"chars": 506,
"preview": "<?xml version=\"1.0\"?>\n<psalm\n errorLevel=\"3\"\n resolveFromConfigFile=\"true\"\n xmlns:xsi=\"http://www.w3.org/2001/X"
},
{
"path": "tests/AppTest.php",
"chars": 92874,
"preview": "<?php\n\n/**\n * Slim Framework (https://slimframework.com)\n *\n * @license https://github.com/slimphp/Slim/blob/4.x/LICENSE"
},
{
"path": "tests/Assets/HeaderStack.php",
"chars": 2261,
"preview": "<?php\n\n/**\n * This is a direct copy of zend-diactoros/test/TestAsset/Functions.php and is used to override\n * header() a"
},
{
"path": "tests/CallableResolverTest.php",
"chars": 21446,
"preview": "<?php\n\n/**\n * Slim Framework (https://slimframework.com)\n *\n * @license https://github.com/slimphp/Slim/blob/4.x/LICENSE"
},
{
"path": "tests/Error/AbstractErrorRendererTest.php",
"chars": 9478,
"preview": "<?php\n\n/**\n * Slim Framework (https://slimframework.com)\n *\n * @license https://github.com/slimphp/Slim/blob/4.x/LICENSE"
},
{
"path": "tests/Exception/HttpExceptionTest.php",
"chars": 1719,
"preview": "<?php\n\n/**\n * Slim Framework (https://slimframework.com)\n *\n * @license https://github.com/slimphp/Slim/blob/4.x/LICENSE"
},
{
"path": "tests/Exception/HttpUnauthorizedExceptionTest.php",
"chars": 863,
"preview": "<?php\n\n/**\n * Slim Framework (https://slimframework.com)\n *\n * @license https://github.com/slimphp/Slim/blob/4.x/LICENSE"
},
{
"path": "tests/Factory/AppFactoryTest.php",
"chars": 15055,
"preview": "<?php\n\n/**\n * Slim Framework (https://slimframework.com)\n *\n * @license https://github.com/slimphp/Slim/blob/4.x/LICENSE"
},
{
"path": "tests/Factory/Psr17/Psr17FactoryProviderTest.php",
"chars": 1078,
"preview": "<?php\n\n/**\n * Slim Framework (https://slimframework.com)\n *\n * @license https://github.com/slimphp/Slim/blob/4.x/LICENSE"
},
{
"path": "tests/Factory/Psr17/Psr17FactoryTest.php",
"chars": 1310,
"preview": "<?php\n\n/**\n * Slim Framework (https://slimframework.com)\n *\n * @license https://github.com/slimphp/Slim/blob/4.x/LICENSE"
},
{
"path": "tests/Factory/Psr17/SlimHttpServerRequestCreatorTest.php",
"chars": 3946,
"preview": "<?php\n\n/**\n * Slim Framework (https://slimframework.com)\n *\n * @license https://github.com/slimphp/Slim/blob/4.x/LICENSE"
},
{
"path": "tests/Factory/ServerRequestCreatorFactoryTest.php",
"chars": 5754,
"preview": "<?php\n\n/**\n * Slim Framework (https://slimframework.com)\n *\n * @license https://github.com/slimphp/Slim/blob/4.x/LICENSE"
},
{
"path": "tests/Handlers/ErrorHandlerTest.php",
"chars": 15338,
"preview": "<?php\n\n/**\n * Slim Framework (https://slimframework.com)\n *\n * @license https://github.com/slimphp/Slim/blob/4.x/LICENSE"
},
{
"path": "tests/Handlers/Strategies/RequestResponseNamedArgsTest.php",
"chars": 5007,
"preview": "<?php\n\n/**\n * Slim Framework (https://slimframework.com)\n *\n * @license https://github.com/slimphp/Slim/blob/4.x/LICENSE"
},
{
"path": "tests/Middleware/BodyParsingMiddlewareTest.php",
"chars": 6715,
"preview": "<?php\n\n/**\n * Slim Framework (https://slimframework.com)\n *\n * @license https://github.com/slimphp/Slim/blob/4.x/LICENSE"
},
{
"path": "tests/Middleware/ContentLengthMiddlewareTest.php",
"chars": 1202,
"preview": "<?php\n\n/**\n * Slim Framework (https://slimframework.com)\n *\n * @license https://github.com/slimphp/Slim/blob/4.x/LICENSE"
},
{
"path": "tests/Middleware/ErrorMiddlewareTest.php",
"chars": 11401,
"preview": "<?php\n\n/**\n * Slim Framework (https://slimframework.com)\n *\n * @license https://github.com/slimphp/Slim/blob/4.x/LICENSE"
},
{
"path": "tests/Middleware/MethodOverrideMiddlewareTest.php",
"chars": 5412,
"preview": "<?php\n\n/**\n * Slim Framework (https://slimframework.com)\n *\n * @license https://github.com/slimphp/Slim/blob/4.x/LICENSE"
},
{
"path": "tests/Middleware/OutputBufferingMiddlewareTest.php",
"chars": 4264,
"preview": "<?php\n\n/**\n * Slim Framework (https://slimframework.com)\n *\n * @license https://github.com/slimphp/Slim/blob/4.x/LICENSE"
},
{
"path": "tests/Middleware/RoutingMiddlewareTest.php",
"chars": 8361,
"preview": "<?php\n\n/**\n * Slim Framework (https://slimframework.com)\n *\n * @license https://github.com/slimphp/Slim/blob/4.x/LICENSE"
},
{
"path": "tests/MiddlewareDispatcherTest.php",
"chars": 24935,
"preview": "<?php\n\n/**\n * Slim Framework (https://slimframework.com)\n *\n * @license https://github.com/slimphp/Slim/blob/4.x/LICENSE"
},
{
"path": "tests/Mocks/CallableTest.php",
"chars": 643,
"preview": "<?php\n\n/**\n * Slim Framework (https://slimframework.com)\n *\n * @license https://github.com/slimphp/Slim/blob/4.x/LICENSE"
},
{
"path": "tests/Mocks/InvocationStrategyTest.php",
"chars": 1173,
"preview": "<?php\n\n/**\n * Slim Framework (https://slimframework.com)\n *\n * @license https://github.com/slimphp/Slim/blob/4.x/LICENSE"
},
{
"path": "tests/Mocks/InvokableTest.php",
"chars": 341,
"preview": "<?php\n\n/**\n * Slim Framework (https://slimframework.com)\n *\n * @license https://github.com/slimphp/Slim/blob/4.x/LICENSE"
},
{
"path": "tests/Mocks/MiddlewareTest.php",
"chars": 1082,
"preview": "<?php\n\n/**\n * Slim Framework (https://slimframework.com)\n *\n * @license https://github.com/slimphp/Slim/blob/4.x/LICENSE"
},
{
"path": "tests/Mocks/MockAction.php",
"chars": 697,
"preview": "<?php\n\n/**\n * Slim Framework (https://slimframework.com)\n *\n * @license https://github.com/slimphp/Slim/blob/4.x/LICENSE"
},
{
"path": "tests/Mocks/MockCustomException.php",
"chars": 262,
"preview": "<?php\n\n/**\n * Slim Framework (https://slimframework.com)\n *\n * @license https://github.com/slimphp/Slim/blob/4.x/LICENSE"
},
{
"path": "tests/Mocks/MockCustomRequestHandlerInvocationStrategy.php",
"chars": 758,
"preview": "<?php\n\n/**\n * Slim Framework (https://slimframework.com)\n *\n * @license https://github.com/slimphp/Slim/blob/4.x/LICENSE"
},
{
"path": "tests/Mocks/MockMiddlewareSlimCallable.php",
"chars": 677,
"preview": "<?php\n\n/**\n * Slim Framework (https://slimframework.com)\n *\n * @license https://github.com/slimphp/Slim/blob/4.x/LICENSE"
},
{
"path": "tests/Mocks/MockMiddlewareWithConstructor.php",
"chars": 1052,
"preview": "<?php\n\n/**\n * Slim Framework (https://slimframework.com)\n *\n * @license https://github.com/slimphp/Slim/blob/4.x/LICENSE"
},
{
"path": "tests/Mocks/MockMiddlewareWithoutConstructor.php",
"chars": 989,
"preview": "<?php\n\n/**\n * Slim Framework (https://slimframework.com)\n *\n * @license https://github.com/slimphp/Slim/blob/4.x/LICENSE"
},
{
"path": "tests/Mocks/MockMiddlewareWithoutInterface.php",
"chars": 239,
"preview": "<?php\n\n/**\n * Slim Framework (https://slimframework.com)\n *\n * @license https://github.com/slimphp/Slim/blob/4.x/LICENSE"
},
{
"path": "tests/Mocks/MockPsr17Factory.php",
"chars": 517,
"preview": "<?php\n\n/**\n * Slim Framework (https://slimframework.com)\n *\n * @license https://github.com/slimphp/Slim/blob/4.x/LICENSE"
},
{
"path": "tests/Mocks/MockPsr17FactoryWithoutStreamFactory.php",
"chars": 570,
"preview": "<?php\n\n/**\n * Slim Framework (https://slimframework.com)\n *\n * @license https://github.com/slimphp/Slim/blob/4.x/LICENSE"
},
{
"path": "tests/Mocks/MockRequestHandler.php",
"chars": 1023,
"preview": "<?php\n\n/**\n * Slim Framework (https://slimframework.com)\n *\n * @license https://github.com/slimphp/Slim/blob/4.x/LICENSE"
},
{
"path": "tests/Mocks/MockSequenceMiddleware.php",
"chars": 1014,
"preview": "<?php\n\n/**\n * Slim Framework (https://slimframework.com)\n *\n * @license https://github.com/slimphp/Slim/blob/4.x/LICENSE"
},
{
"path": "tests/Mocks/MockStream.php",
"chars": 6543,
"preview": "<?php\n\n/**\n * Slim Framework (https://slimframework.com)\n *\n * @license https://github.com/slimphp/Slim/blob/4.x/LICENSE"
},
{
"path": "tests/Mocks/RequestHandlerTest.php",
"chars": 1533,
"preview": "<?php\n\n/**\n * Slim Framework (https://slimframework.com)\n *\n * @license https://github.com/slimphp/Slim/blob/4.x/LICENSE"
},
{
"path": "tests/Mocks/SlowPokeStream.php",
"chars": 2139,
"preview": "<?php\n\n/**\n * Slim Framework (https://slimframework.com)\n *\n * @license https://github.com/slimphp/Slim/blob/4.x/LICENSE"
},
{
"path": "tests/Mocks/SmallChunksStream.php",
"chars": 2022,
"preview": "<?php\n\n/**\n * Slim Framework (https://slimframework.com)\n *\n * @license https://github.com/slimphp/Slim/blob/4.x/LICENSE"
},
{
"path": "tests/Providers/PSR7ObjectProvider.php",
"chars": 3030,
"preview": "<?php\n\n/**\n * Slim Framework (https://slimframework.com)\n *\n * @license https://github.com/slimphp/Slim/blob/4.x/LICENSE"
},
{
"path": "tests/Providers/PSR7ObjectProviderInterface.php",
"chars": 1613,
"preview": "<?php\n\n/**\n * Slim Framework (https://slimframework.com)\n *\n * @license https://github.com/slimphp/Slim/blob/4.x/LICENSE"
},
{
"path": "tests/ResponseEmitterTest.php",
"chars": 9138,
"preview": "<?php\n\n/**\n * Slim Framework (https://slimframework.com)\n *\n * @license https://github.com/slimphp/Slim/blob/4.x/LICENSE"
},
{
"path": "tests/Routing/DispatcherTest.php",
"chars": 5581,
"preview": "<?php\n\n/**\n * Slim Framework (https://slimframework.com)\n *\n * @license https://github.com/slimphp/Slim/blob/4.x/LICENSE"
},
{
"path": "tests/Routing/FastRouteDispatcherTest.php",
"chars": 21028,
"preview": "<?php\n\n/**\n * Slim Framework (https://slimframework.com)\n *\n * @license https://github.com/slimphp/Slim/blob/4.x/LICENSE"
},
{
"path": "tests/Routing/RouteCollectorProxyTest.php",
"chars": 15485,
"preview": "<?php\n\n/**\n * Slim Framework (https://slimframework.com)\n *\n * @license https://github.com/slimphp/Slim/blob/4.x/LICENSE"
},
{
"path": "tests/Routing/RouteCollectorTest.php",
"chars": 7470,
"preview": "<?php\n\n/**\n * Slim Framework (https://slimframework.com)\n *\n * @license https://github.com/slimphp/Slim/blob/4.x/LICENSE"
},
{
"path": "tests/Routing/RouteContextTest.php",
"chars": 4108,
"preview": "<?php\n\n/**\n * Slim Framework (https://slimframework.com)\n *\n * @license https://github.com/slimphp/Slim/blob/4.x/LICENSE"
},
{
"path": "tests/Routing/RouteParserTest.php",
"chars": 7647,
"preview": "<?php\n\ndeclare(strict_types=1);\n\nnamespace Slim\\Tests\\Routing;\n\nuse InvalidArgumentException;\nuse Psr\\Http\\Message\\Respo"
},
{
"path": "tests/Routing/RouteResolverTest.php",
"chars": 2965,
"preview": "<?php\n\n/**\n * Slim Framework (https://slimframework.com)\n *\n * @license https://github.com/slimphp/Slim/blob/4.x/LICENSE"
},
{
"path": "tests/Routing/RouteRunnerTest.php",
"chars": 1811,
"preview": "<?php\n\n/**\n * Slim Framework (https://slimframework.com)\n *\n * @license https://github.com/slimphp/Slim/blob/4.x/LICENSE"
},
{
"path": "tests/Routing/RouteTest.php",
"chars": 29512,
"preview": "<?php\n\n/**\n * Slim Framework (https://slimframework.com)\n *\n * @license https://github.com/slimphp/Slim/blob/4.x/LICENSE"
},
{
"path": "tests/TestCase.php",
"chars": 3965,
"preview": "<?php\n\n/**\n * Slim Framework (https://slimframework.com)\n *\n * @license https://github.com/slimphp/Slim/blob/4.x/LICENSE"
},
{
"path": "tests/bootstrap.php",
"chars": 1404,
"preview": "<?php\n\n/**\n * Slim Framework (https://slimframework.com)\n *\n * @license https://github.com/slimphp/Slim/blob/4.x/LICENSE"
}
]
About this extraction
This page contains the full source code of the slimphp/Slim GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 145 files (576.9 KB), approximately 138.6k tokens, and a symbol index with 852 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.