parent
73550d684a
commit
c01b044b02
@ -1 +1 @@
|
||||
|
||||
server.port=8081
|
@ -0,0 +1,6 @@
|
||||
{
|
||||
"require": {
|
||||
"slim/psr7": "^1.6",
|
||||
"slim/slim": "4.*"
|
||||
}
|
||||
}
|
@ -0,0 +1,774 @@
|
||||
{
|
||||
"_readme": [
|
||||
"This file locks the dependencies of your project to a known state",
|
||||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||
"This file is @generated automatically"
|
||||
],
|
||||
"content-hash": "5707c67936a35c4a5c21097aec3e463b",
|
||||
"packages": [
|
||||
{
|
||||
"name": "fig/http-message-util",
|
||||
"version": "1.1.5",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/php-fig/http-message-util.git",
|
||||
"reference": "9d94dc0154230ac39e5bf89398b324a86f63f765"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/php-fig/http-message-util/zipball/9d94dc0154230ac39e5bf89398b324a86f63f765",
|
||||
"reference": "9d94dc0154230ac39e5bf89398b324a86f63f765",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": "^5.3 || ^7.0 || ^8.0"
|
||||
},
|
||||
"suggest": {
|
||||
"psr/http-message": "The package containing the PSR-7 interfaces"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "1.1.x-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Fig\\Http\\Message\\": "src/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "PHP-FIG",
|
||||
"homepage": "https://www.php-fig.org/"
|
||||
}
|
||||
],
|
||||
"description": "Utility classes and constants for use with PSR-7 (psr/http-message)",
|
||||
"keywords": [
|
||||
"http",
|
||||
"http-message",
|
||||
"psr",
|
||||
"psr-7",
|
||||
"request",
|
||||
"response"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/php-fig/http-message-util/issues",
|
||||
"source": "https://github.com/php-fig/http-message-util/tree/1.1.5"
|
||||
},
|
||||
"time": "2020-11-24T22:02:12+00:00"
|
||||
},
|
||||
{
|
||||
"name": "nikic/fast-route",
|
||||
"version": "v1.3.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/nikic/FastRoute.git",
|
||||
"reference": "181d480e08d9476e61381e04a71b34dc0432e812"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/nikic/FastRoute/zipball/181d480e08d9476e61381e04a71b34dc0432e812",
|
||||
"reference": "181d480e08d9476e61381e04a71b34dc0432e812",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=5.4.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "^4.8.35|~5.7"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"files": [
|
||||
"src/functions.php"
|
||||
],
|
||||
"psr-4": {
|
||||
"FastRoute\\": "src/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"BSD-3-Clause"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Nikita Popov",
|
||||
"email": "nikic@php.net"
|
||||
}
|
||||
],
|
||||
"description": "Fast request router for PHP",
|
||||
"keywords": [
|
||||
"router",
|
||||
"routing"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/nikic/FastRoute/issues",
|
||||
"source": "https://github.com/nikic/FastRoute/tree/master"
|
||||
},
|
||||
"time": "2018-02-13T20:26:39+00:00"
|
||||
},
|
||||
{
|
||||
"name": "psr/container",
|
||||
"version": "2.0.2",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/php-fig/container.git",
|
||||
"reference": "c71ecc56dfe541dbd90c5360474fbc405f8d5963"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/php-fig/container/zipball/c71ecc56dfe541dbd90c5360474fbc405f8d5963",
|
||||
"reference": "c71ecc56dfe541dbd90c5360474fbc405f8d5963",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=7.4.0"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "2.0.x-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Psr\\Container\\": "src/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "PHP-FIG",
|
||||
"homepage": "https://www.php-fig.org/"
|
||||
}
|
||||
],
|
||||
"description": "Common Container Interface (PHP FIG PSR-11)",
|
||||
"homepage": "https://github.com/php-fig/container",
|
||||
"keywords": [
|
||||
"PSR-11",
|
||||
"container",
|
||||
"container-interface",
|
||||
"container-interop",
|
||||
"psr"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/php-fig/container/issues",
|
||||
"source": "https://github.com/php-fig/container/tree/2.0.2"
|
||||
},
|
||||
"time": "2021-11-05T16:47:00+00:00"
|
||||
},
|
||||
{
|
||||
"name": "psr/http-factory",
|
||||
"version": "1.0.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/php-fig/http-factory.git",
|
||||
"reference": "12ac7fcd07e5b077433f5f2bee95b3a771bf61be"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/php-fig/http-factory/zipball/12ac7fcd07e5b077433f5f2bee95b3a771bf61be",
|
||||
"reference": "12ac7fcd07e5b077433f5f2bee95b3a771bf61be",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=7.0.0",
|
||||
"psr/http-message": "^1.0"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "1.0.x-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Psr\\Http\\Message\\": "src/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "PHP-FIG",
|
||||
"homepage": "http://www.php-fig.org/"
|
||||
}
|
||||
],
|
||||
"description": "Common interfaces for PSR-7 HTTP message factories",
|
||||
"keywords": [
|
||||
"factory",
|
||||
"http",
|
||||
"message",
|
||||
"psr",
|
||||
"psr-17",
|
||||
"psr-7",
|
||||
"request",
|
||||
"response"
|
||||
],
|
||||
"support": {
|
||||
"source": "https://github.com/php-fig/http-factory/tree/master"
|
||||
},
|
||||
"time": "2019-04-30T12:38:16+00:00"
|
||||
},
|
||||
{
|
||||
"name": "psr/http-message",
|
||||
"version": "1.0.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/php-fig/http-message.git",
|
||||
"reference": "f6561bf28d520154e4b0ec72be95418abe6d9363"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/php-fig/http-message/zipball/f6561bf28d520154e4b0ec72be95418abe6d9363",
|
||||
"reference": "f6561bf28d520154e4b0ec72be95418abe6d9363",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=5.3.0"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "1.0.x-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Psr\\Http\\Message\\": "src/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "PHP-FIG",
|
||||
"homepage": "http://www.php-fig.org/"
|
||||
}
|
||||
],
|
||||
"description": "Common interface for HTTP messages",
|
||||
"homepage": "https://github.com/php-fig/http-message",
|
||||
"keywords": [
|
||||
"http",
|
||||
"http-message",
|
||||
"psr",
|
||||
"psr-7",
|
||||
"request",
|
||||
"response"
|
||||
],
|
||||
"support": {
|
||||
"source": "https://github.com/php-fig/http-message/tree/master"
|
||||
},
|
||||
"time": "2016-08-06T14:39:51+00:00"
|
||||
},
|
||||
{
|
||||
"name": "psr/http-server-handler",
|
||||
"version": "1.0.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/php-fig/http-server-handler.git",
|
||||
"reference": "aff2f80e33b7f026ec96bb42f63242dc50ffcae7"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/php-fig/http-server-handler/zipball/aff2f80e33b7f026ec96bb42f63242dc50ffcae7",
|
||||
"reference": "aff2f80e33b7f026ec96bb42f63242dc50ffcae7",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=7.0",
|
||||
"psr/http-message": "^1.0"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "1.0.x-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Psr\\Http\\Server\\": "src/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "PHP-FIG",
|
||||
"homepage": "http://www.php-fig.org/"
|
||||
}
|
||||
],
|
||||
"description": "Common interface for HTTP server-side request handler",
|
||||
"keywords": [
|
||||
"handler",
|
||||
"http",
|
||||
"http-interop",
|
||||
"psr",
|
||||
"psr-15",
|
||||
"psr-7",
|
||||
"request",
|
||||
"response",
|
||||
"server"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/php-fig/http-server-handler/issues",
|
||||
"source": "https://github.com/php-fig/http-server-handler/tree/master"
|
||||
},
|
||||
"time": "2018-10-30T16:46:14+00:00"
|
||||
},
|
||||
{
|
||||
"name": "psr/http-server-middleware",
|
||||
"version": "1.0.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/php-fig/http-server-middleware.git",
|
||||
"reference": "2296f45510945530b9dceb8bcedb5cb84d40c5f5"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/php-fig/http-server-middleware/zipball/2296f45510945530b9dceb8bcedb5cb84d40c5f5",
|
||||
"reference": "2296f45510945530b9dceb8bcedb5cb84d40c5f5",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=7.0",
|
||||
"psr/http-message": "^1.0",
|
||||
"psr/http-server-handler": "^1.0"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "1.0.x-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Psr\\Http\\Server\\": "src/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "PHP-FIG",
|
||||
"homepage": "http://www.php-fig.org/"
|
||||
}
|
||||
],
|
||||
"description": "Common interface for HTTP server-side middleware",
|
||||
"keywords": [
|
||||
"http",
|
||||
"http-interop",
|
||||
"middleware",
|
||||
"psr",
|
||||
"psr-15",
|
||||
"psr-7",
|
||||
"request",
|
||||
"response"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/php-fig/http-server-middleware/issues",
|
||||
"source": "https://github.com/php-fig/http-server-middleware/tree/master"
|
||||
},
|
||||
"time": "2018-10-30T17:12:04+00:00"
|
||||
},
|
||||
{
|
||||
"name": "psr/log",
|
||||
"version": "3.0.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/php-fig/log.git",
|
||||
"reference": "fe5ea303b0887d5caefd3d431c3e61ad47037001"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/php-fig/log/zipball/fe5ea303b0887d5caefd3d431c3e61ad47037001",
|
||||
"reference": "fe5ea303b0887d5caefd3d431c3e61ad47037001",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=8.0.0"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "3.x-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Psr\\Log\\": "src"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "PHP-FIG",
|
||||
"homepage": "https://www.php-fig.org/"
|
||||
}
|
||||
],
|
||||
"description": "Common interface for logging libraries",
|
||||
"homepage": "https://github.com/php-fig/log",
|
||||
"keywords": [
|
||||
"log",
|
||||
"psr",
|
||||
"psr-3"
|
||||
],
|
||||
"support": {
|
||||
"source": "https://github.com/php-fig/log/tree/3.0.0"
|
||||
},
|
||||
"time": "2021-07-14T16:46:02+00:00"
|
||||
},
|
||||
{
|
||||
"name": "ralouphie/getallheaders",
|
||||
"version": "3.0.3",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/ralouphie/getallheaders.git",
|
||||
"reference": "120b605dfeb996808c31b6477290a714d356e822"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/ralouphie/getallheaders/zipball/120b605dfeb996808c31b6477290a714d356e822",
|
||||
"reference": "120b605dfeb996808c31b6477290a714d356e822",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=5.6"
|
||||
},
|
||||
"require-dev": {
|
||||
"php-coveralls/php-coveralls": "^2.1",
|
||||
"phpunit/phpunit": "^5 || ^6.5"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"files": [
|
||||
"src/getallheaders.php"
|
||||
]
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Ralph Khattar",
|
||||
"email": "ralph.khattar@gmail.com"
|
||||
}
|
||||
],
|
||||
"description": "A polyfill for getallheaders.",
|
||||
"support": {
|
||||
"issues": "https://github.com/ralouphie/getallheaders/issues",
|
||||
"source": "https://github.com/ralouphie/getallheaders/tree/develop"
|
||||
},
|
||||
"time": "2019-03-08T08:55:37+00:00"
|
||||
},
|
||||
{
|
||||
"name": "slim/psr7",
|
||||
"version": "1.6",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/slimphp/Slim-Psr7.git",
|
||||
"reference": "3471c22c1a0d26c51c78f6aeb06489d38cf46a4d"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/slimphp/Slim-Psr7/zipball/3471c22c1a0d26c51c78f6aeb06489d38cf46a4d",
|
||||
"reference": "3471c22c1a0d26c51c78f6aeb06489d38cf46a4d",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"fig/http-message-util": "^1.1.5",
|
||||
"php": "^7.4 || ^8.0",
|
||||
"psr/http-factory": "^1.0",
|
||||
"psr/http-message": "^1.0",
|
||||
"ralouphie/getallheaders": "^3.0",
|
||||
"symfony/polyfill-php80": "^1.26"
|
||||
},
|
||||
"provide": {
|
||||
"psr/http-factory-implementation": "1.0",
|
||||
"psr/http-message-implementation": "1.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"adriansuter/php-autoload-override": "^1.3",
|
||||
"ext-json": "*",
|
||||
"http-interop/http-factory-tests": "^0.9.0",
|
||||
"php-http/psr7-integration-tests": "dev-master",
|
||||
"phpspec/prophecy": "^1.15",
|
||||
"phpspec/prophecy-phpunit": "^2.0",
|
||||
"phpstan/phpstan": "^1.8",
|
||||
"phpunit/phpunit": "^9.5",
|
||||
"squizlabs/php_codesniffer": "^3.7"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Slim\\Psr7\\": "src"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Josh Lockhart",
|
||||
"email": "hello@joshlockhart.com",
|
||||
"homepage": "http://joshlockhart.com"
|
||||
},
|
||||
{
|
||||
"name": "Andrew Smith",
|
||||
"email": "a.smith@silentworks.co.uk",
|
||||
"homepage": "http://silentworks.co.uk"
|
||||
},
|
||||
{
|
||||
"name": "Rob Allen",
|
||||
"email": "rob@akrabat.com",
|
||||
"homepage": "http://akrabat.com"
|
||||
},
|
||||
{
|
||||
"name": "Pierre Berube",
|
||||
"email": "pierre@lgse.com",
|
||||
"homepage": "http://www.lgse.com"
|
||||
}
|
||||
],
|
||||
"description": "Strict PSR-7 implementation",
|
||||
"homepage": "https://www.slimframework.com",
|
||||
"keywords": [
|
||||
"http",
|
||||
"psr-7",
|
||||
"psr7"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/slimphp/Slim-Psr7/issues",
|
||||
"source": "https://github.com/slimphp/Slim-Psr7/tree/1.6"
|
||||
},
|
||||
"time": "2022-11-05T18:50:24+00:00"
|
||||
},
|
||||
{
|
||||
"name": "slim/slim",
|
||||
"version": "4.11.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/slimphp/Slim.git",
|
||||
"reference": "b0f4ca393ea037be9ac7292ba7d0a34d18bac0c7"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/slimphp/Slim/zipball/b0f4ca393ea037be9ac7292ba7d0a34d18bac0c7",
|
||||
"reference": "b0f4ca393ea037be9ac7292ba7d0a34d18bac0c7",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"ext-json": "*",
|
||||
"nikic/fast-route": "^1.3",
|
||||
"php": "^7.4 || ^8.0",
|
||||
"psr/container": "^1.0 || ^2.0",
|
||||
"psr/http-factory": "^1.0",
|
||||
"psr/http-message": "^1.0",
|
||||
"psr/http-server-handler": "^1.0",
|
||||
"psr/http-server-middleware": "^1.0",
|
||||
"psr/log": "^1.1 || ^2.0 || ^3.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"adriansuter/php-autoload-override": "^1.3",
|
||||
"ext-simplexml": "*",
|
||||
"guzzlehttp/psr7": "^2.4",
|
||||
"httpsoft/http-message": "^1.0",
|
||||
"httpsoft/http-server-request": "^1.0",
|
||||
"laminas/laminas-diactoros": "^2.17",
|
||||
"nyholm/psr7": "^1.5",
|
||||
"nyholm/psr7-server": "^1.0",
|
||||
"phpspec/prophecy": "^1.15",
|
||||
"phpspec/prophecy-phpunit": "^2.0",
|
||||
"phpstan/phpstan": "^1.8",
|
||||
"phpunit/phpunit": "^9.5",
|
||||
"slim/http": "^1.2",
|
||||
"slim/psr7": "^1.5",
|
||||
"squizlabs/php_codesniffer": "^3.7"
|
||||
},
|
||||
"suggest": {
|
||||
"ext-simplexml": "Needed to support XML format in BodyParsingMiddleware",
|
||||
"ext-xml": "Needed to support XML format in BodyParsingMiddleware",
|
||||
"php-di/php-di": "PHP-DI is the recommended container library to be used with Slim",
|
||||
"slim/psr7": "Slim PSR-7 implementation. See https://www.slimframework.com/docs/v4/start/installation.html for more information."
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Slim\\": "Slim"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Josh Lockhart",
|
||||
"email": "hello@joshlockhart.com",
|
||||
"homepage": "https://joshlockhart.com"
|
||||
},
|
||||
{
|
||||
"name": "Andrew Smith",
|
||||
"email": "a.smith@silentworks.co.uk",
|
||||
"homepage": "http://silentworks.co.uk"
|
||||
},
|
||||
{
|
||||
"name": "Rob Allen",
|
||||
"email": "rob@akrabat.com",
|
||||
"homepage": "http://akrabat.com"
|
||||
},
|
||||
{
|
||||
"name": "Pierre Berube",
|
||||
"email": "pierre@lgse.com",
|
||||
"homepage": "http://www.lgse.com"
|
||||
},
|
||||
{
|
||||
"name": "Gabriel Manricks",
|
||||
"email": "gmanricks@me.com",
|
||||
"homepage": "http://gabrielmanricks.com"
|
||||
}
|
||||
],
|
||||
"description": "Slim is a PHP micro framework that helps you quickly write simple yet powerful web applications and APIs",
|
||||
"homepage": "https://www.slimframework.com",
|
||||
"keywords": [
|
||||
"api",
|
||||
"framework",
|
||||
"micro",
|
||||
"router"
|
||||
],
|
||||
"support": {
|
||||
"docs": "https://www.slimframework.com/docs/v4/",
|
||||
"forum": "https://discourse.slimframework.com/",
|
||||
"irc": "irc://irc.freenode.net:6667/slimphp",
|
||||
"issues": "https://github.com/slimphp/Slim/issues",
|
||||
"rss": "https://www.slimframework.com/blog/feed.rss",
|
||||
"slack": "https://slimphp.slack.com/",
|
||||
"source": "https://github.com/slimphp/Slim",
|
||||
"wiki": "https://github.com/slimphp/Slim/wiki"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
"url": "https://opencollective.com/slimphp",
|
||||
"type": "open_collective"
|
||||
},
|
||||
{
|
||||
"url": "https://tidelift.com/funding/github/packagist/slim/slim",
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2022-11-06T16:33:39+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/polyfill-php80",
|
||||
"version": "v1.27.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/polyfill-php80.git",
|
||||
"reference": "7a6ff3f1959bb01aefccb463a0f2cd3d3d2fd936"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/7a6ff3f1959bb01aefccb463a0f2cd3d3d2fd936",
|
||||
"reference": "7a6ff3f1959bb01aefccb463a0f2cd3d3d2fd936",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=7.1"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-main": "1.27-dev"
|
||||
},
|
||||
"thanks": {
|
||||
"name": "symfony/polyfill",
|
||||
"url": "https://github.com/symfony/polyfill"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"files": [
|
||||
"bootstrap.php"
|
||||
],
|
||||
"psr-4": {
|
||||
"Symfony\\Polyfill\\Php80\\": ""
|
||||
},
|
||||
"classmap": [
|
||||
"Resources/stubs"
|
||||
]
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Ion Bazan",
|
||||
"email": "ion.bazan@gmail.com"
|
||||
},
|
||||
{
|
||||
"name": "Nicolas Grekas",
|
||||
"email": "p@tchwork.com"
|
||||
},
|
||||
{
|
||||
"name": "Symfony Community",
|
||||
"homepage": "https://symfony.com/contributors"
|
||||
}
|
||||
],
|
||||
"description": "Symfony polyfill backporting some PHP 8.0+ features to lower PHP versions",
|
||||
"homepage": "https://symfony.com",
|
||||
"keywords": [
|
||||
"compatibility",
|
||||
"polyfill",
|
||||
"portable",
|
||||
"shim"
|
||||
],
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/polyfill-php80/tree/v1.27.0"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
"url": "https://symfony.com/sponsor",
|
||||
"type": "custom"
|
||||
},
|
||||
{
|
||||
"url": "https://github.com/fabpot",
|
||||
"type": "github"
|
||||
},
|
||||
{
|
||||
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2022-11-03T14:55:06+00:00"
|
||||
}
|
||||
],
|
||||
"packages-dev": [],
|
||||
"aliases": [],
|
||||
"minimum-stability": "stable",
|
||||
"stability-flags": [],
|
||||
"prefer-stable": false,
|
||||
"prefer-lowest": false,
|
||||
"platform": [],
|
||||
"platform-dev": [],
|
||||
"plugin-api-version": "2.3.0"
|
||||
}
|
Binary file not shown.
@ -0,0 +1,61 @@
|
||||
<?php
|
||||
use Psr\Http\Message\ResponseInterface as Response;
|
||||
use Psr\Http\Message\ServerRequestInterface as Request;
|
||||
use Slim\Factory\AppFactory;
|
||||
|
||||
$loader = require __DIR__ . '/../vendor/autoload.php';
|
||||
//for namespace BL PSR4 here namespace ; dir
|
||||
$loader->addPsr4('BL\\', __DIR__);
|
||||
$app = AppFactory::create();
|
||||
|
||||
|
||||
$app->get('/', function (Request $request, Response $response, $args) {
|
||||
$response->getBody()->write("Hello world!");
|
||||
return $response;
|
||||
});
|
||||
|
||||
$app->get('/loan', function (Request $request, Response $response, $args) {
|
||||
$params=$request->getQueryParams();
|
||||
$account=$params["account"];
|
||||
$approval=$params["approval"];
|
||||
$somme=$params["somme"];
|
||||
$urlAccount = file_get_contents("http://localhost:8081/accounts/".$account);
|
||||
$urlApproval = file_get_contents("http://localhost:8080/approvals/".$approval);
|
||||
|
||||
if($somme<10000){
|
||||
$data=(array)json_decode($urlAccount);
|
||||
if($data["risk"]=="High"){
|
||||
$response->getBody()->write("refused | risk=High et somme<10000");
|
||||
}
|
||||
else{
|
||||
$urlAccount=("http://localhost:8081/accounts/".$account."/".$somme);
|
||||
echo $urlAccount;
|
||||
$ch=curl_init($urlAccount);
|
||||
curl_setopt($ch,CURLOPT_RETURNTRANSFER,true);
|
||||
curl_setopt($ch,CURLOPT_CUSTOMREQUEST,"PUT");
|
||||
$out=curl_exec($ch);
|
||||
curl_close($ch);
|
||||
$response->getBody()->write("accepted | somme<10000".$out);
|
||||
}
|
||||
}
|
||||
else{
|
||||
$data=(array)json_decode($urlApproval);
|
||||
if($data["accept"]){
|
||||
$urlAccount=("http://localhost:8081/accounts/".$account."/".$somme);
|
||||
echo $urlAccount;
|
||||
$ch=curl_init($urlAccount);
|
||||
curl_setopt($ch,CURLOPT_RETURNTRANSFER,true);
|
||||
curl_setopt($ch,CURLOPT_CUSTOMREQUEST,"PUT");
|
||||
$out=curl_exec($ch);
|
||||
curl_close($ch);
|
||||
$response->getBody()->write("accepted | Approval déjà accepté".$out);
|
||||
}
|
||||
else{
|
||||
$response->getBody()->write("refused | Approval déjà refusé");
|
||||
}
|
||||
}
|
||||
return $response;
|
||||
});
|
||||
|
||||
|
||||
$app->run();
|
@ -0,0 +1,25 @@
|
||||
<?php
|
||||
|
||||
// autoload.php @generated by Composer
|
||||
|
||||
if (PHP_VERSION_ID < 50600) {
|
||||
if (!headers_sent()) {
|
||||
header('HTTP/1.1 500 Internal Server Error');
|
||||
}
|
||||
$err = 'Composer 2.3.0 dropped support for autoloading on PHP <5.6 and you are running '.PHP_VERSION.', please upgrade PHP or use Composer 2.2 LTS via "composer self-update --2.2". Aborting.'.PHP_EOL;
|
||||
if (!ini_get('display_errors')) {
|
||||
if (PHP_SAPI === 'cli' || PHP_SAPI === 'phpdbg') {
|
||||
fwrite(STDERR, $err);
|
||||
} elseif (!headers_sent()) {
|
||||
echo $err;
|
||||
}
|
||||
}
|
||||
trigger_error(
|
||||
$err,
|
||||
E_USER_ERROR
|
||||
);
|
||||
}
|
||||
|
||||
require_once __DIR__ . '/composer/autoload_real.php';
|
||||
|
||||
return ComposerAutoloaderInit344c194729b7446a4ea6541135c6e068::getLoader();
|
@ -0,0 +1,585 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Composer.
|
||||
*
|
||||
* (c) Nils Adermann <naderman@naderman.de>
|
||||
* Jordi Boggiano <j.boggiano@seld.be>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Composer\Autoload;
|
||||
|
||||
/**
|
||||
* ClassLoader implements a PSR-0, PSR-4 and classmap class loader.
|
||||
*
|
||||
* $loader = new \Composer\Autoload\ClassLoader();
|
||||
*
|
||||
* // register classes with namespaces
|
||||
* $loader->add('Symfony\Component', __DIR__.'/component');
|
||||
* $loader->add('Symfony', __DIR__.'/framework');
|
||||
*
|
||||
* // activate the autoloader
|
||||
* $loader->register();
|
||||
*
|
||||
* // to enable searching the include path (eg. for PEAR packages)
|
||||
* $loader->setUseIncludePath(true);
|
||||
*
|
||||
* In this example, if you try to use a class in the Symfony\Component
|
||||
* namespace or one of its children (Symfony\Component\Console for instance),
|
||||
* the autoloader will first look for the class under the component/
|
||||
* directory, and it will then fallback to the framework/ directory if not
|
||||
* found before giving up.
|
||||
*
|
||||
* This class is loosely based on the Symfony UniversalClassLoader.
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
* @author Jordi Boggiano <j.boggiano@seld.be>
|
||||
* @see https://www.php-fig.org/psr/psr-0/
|
||||
* @see https://www.php-fig.org/psr/psr-4/
|
||||
*/
|
||||
class ClassLoader
|
||||
{
|
||||
/** @var \Closure(string):void */
|
||||
private static $includeFile;
|
||||
|
||||
/** @var ?string */
|
||||
private $vendorDir;
|
||||
|
||||
// PSR-4
|
||||
/**
|
||||
* @var array[]
|
||||
* @psalm-var array<string, array<string, int>>
|
||||
*/
|
||||
private $prefixLengthsPsr4 = array();
|
||||
/**
|
||||
* @var array[]
|
||||
* @psalm-var array<string, array<int, string>>
|
||||
*/
|
||||
private $prefixDirsPsr4 = array();
|
||||
/**
|
||||
* @var array[]
|
||||
* @psalm-var array<string, string>
|
||||
*/
|
||||
private $fallbackDirsPsr4 = array();
|
||||
|
||||
// PSR-0
|
||||
/**
|
||||
* @var array[]
|
||||
* @psalm-var array<string, array<string, string[]>>
|
||||
*/
|
||||
private $prefixesPsr0 = array();
|
||||
/**
|
||||
* @var array[]
|
||||
* @psalm-var array<string, string>
|
||||
*/
|
||||
private $fallbackDirsPsr0 = array();
|
||||
|
||||
/** @var bool */
|
||||
private $useIncludePath = false;
|
||||
|
||||
/**
|
||||
* @var string[]
|
||||
* @psalm-var array<string, string>
|
||||
*/
|
||||
private $classMap = array();
|
||||
|
||||
/** @var bool */
|
||||
private $classMapAuthoritative = false;
|
||||
|
||||
/**
|
||||
* @var bool[]
|
||||
* @psalm-var array<string, bool>
|
||||
*/
|
||||
private $missingClasses = array();
|
||||
|
||||
/** @var ?string */
|
||||
private $apcuPrefix;
|
||||
|
||||
/**
|
||||
* @var self[]
|
||||
*/
|
||||
private static $registeredLoaders = array();
|
||||
|
||||
/**
|
||||
* @param ?string $vendorDir
|
||||
*/
|
||||
public function __construct($vendorDir = null)
|
||||
{
|
||||
$this->vendorDir = $vendorDir;
|
||||
self::initializeIncludeClosure();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string[]
|
||||
*/
|
||||
public function getPrefixes()
|
||||
{
|
||||
if (!empty($this->prefixesPsr0)) {
|
||||
return call_user_func_array('array_merge', array_values($this->prefixesPsr0));
|
||||
}
|
||||
|
||||
return array();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array[]
|
||||
* @psalm-return array<string, array<int, string>>
|
||||
*/
|
||||
public function getPrefixesPsr4()
|
||||
{
|
||||
return $this->prefixDirsPsr4;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array[]
|
||||
* @psalm-return array<string, string>
|
||||
*/
|
||||
public function getFallbackDirs()
|
||||
{
|
||||
return $this->fallbackDirsPsr0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array[]
|
||||
* @psalm-return array<string, string>
|
||||
*/
|
||||
public function getFallbackDirsPsr4()
|
||||
{
|
||||
return $this->fallbackDirsPsr4;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string[] Array of classname => path
|
||||
* @psalm-return array<string, string>
|
||||
*/
|
||||
public function getClassMap()
|
||||
{
|
||||
return $this->classMap;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string[] $classMap Class to filename map
|
||||
* @psalm-param array<string, string> $classMap
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function addClassMap(array $classMap)
|
||||
{
|
||||
if ($this->classMap) {
|
||||
$this->classMap = array_merge($this->classMap, $classMap);
|
||||
} else {
|
||||
$this->classMap = $classMap;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers a set of PSR-0 directories for a given prefix, either
|
||||
* appending or prepending to the ones previously set for this prefix.
|
||||
*
|
||||
* @param string $prefix The prefix
|
||||
* @param string[]|string $paths The PSR-0 root directories
|
||||
* @param bool $prepend Whether to prepend the directories
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function add($prefix, $paths, $prepend = false)
|
||||
{
|
||||
if (!$prefix) {
|
||||
if ($prepend) {
|
||||
$this->fallbackDirsPsr0 = array_merge(
|
||||
(array) $paths,
|
||||
$this->fallbackDirsPsr0
|
||||
);
|
||||
} else {
|
||||
$this->fallbackDirsPsr0 = array_merge(
|
||||
$this->fallbackDirsPsr0,
|
||||
(array) $paths
|
||||
);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
$first = $prefix[0];
|
||||
if (!isset($this->prefixesPsr0[$first][$prefix])) {
|
||||
$this->prefixesPsr0[$first][$prefix] = (array) $paths;
|
||||
|
||||
return;
|
||||
}
|
||||
if ($prepend) {
|
||||
$this->prefixesPsr0[$first][$prefix] = array_merge(
|
||||
(array) $paths,
|
||||
$this->prefixesPsr0[$first][$prefix]
|
||||
);
|
||||
} else {
|
||||
$this->prefixesPsr0[$first][$prefix] = array_merge(
|
||||
$this->prefixesPsr0[$first][$prefix],
|
||||
(array) $paths
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers a set of PSR-4 directories for a given namespace, either
|
||||
* appending or prepending to the ones previously set for this namespace.
|
||||
*
|
||||
* @param string $prefix The prefix/namespace, with trailing '\\'
|
||||
* @param string[]|string $paths The PSR-4 base directories
|
||||
* @param bool $prepend Whether to prepend the directories
|
||||
*
|
||||
* @throws \InvalidArgumentException
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function addPsr4($prefix, $paths, $prepend = false)
|
||||
{
|
||||
if (!$prefix) {
|
||||
// Register directories for the root namespace.
|
||||
if ($prepend) {
|
||||
$this->fallbackDirsPsr4 = array_merge(
|
||||
(array) $paths,
|
||||
$this->fallbackDirsPsr4
|
||||
);
|
||||
} else {
|
||||
$this->fallbackDirsPsr4 = array_merge(
|
||||
$this->fallbackDirsPsr4,
|
||||
(array) $paths
|
||||
);
|
||||
}
|
||||
} elseif (!isset($this->prefixDirsPsr4[$prefix])) {
|
||||
// Register directories for a new namespace.
|
||||
$length = strlen($prefix);
|
||||
if ('\\' !== $prefix[$length - 1]) {
|
||||
throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator.");
|
||||
}
|
||||
$this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length;
|
||||
$this->prefixDirsPsr4[$prefix] = (array) $paths;
|
||||
} elseif ($prepend) {
|
||||
// Prepend directories for an already registered namespace.
|
||||
$this->prefixDirsPsr4[$prefix] = array_merge(
|
||||
(array) $paths,
|
||||
$this->prefixDirsPsr4[$prefix]
|
||||
);
|
||||
} else {
|
||||
// Append directories for an already registered namespace.
|
||||
$this->prefixDirsPsr4[$prefix] = array_merge(
|
||||
$this->prefixDirsPsr4[$prefix],
|
||||
(array) $paths
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers a set of PSR-0 directories for a given prefix,
|
||||
* replacing any others previously set for this prefix.
|
||||
*
|
||||
* @param string $prefix The prefix
|
||||
* @param string[]|string $paths The PSR-0 base directories
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function set($prefix, $paths)
|
||||
{
|
||||
if (!$prefix) {
|
||||
$this->fallbackDirsPsr0 = (array) $paths;
|
||||
} else {
|
||||
$this->prefixesPsr0[$prefix[0]][$prefix] = (array) $paths;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers a set of PSR-4 directories for a given namespace,
|
||||
* replacing any others previously set for this namespace.
|
||||
*
|
||||
* @param string $prefix The prefix/namespace, with trailing '\\'
|
||||
* @param string[]|string $paths The PSR-4 base directories
|
||||
*
|
||||
* @throws \InvalidArgumentException
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setPsr4($prefix, $paths)
|
||||
{
|
||||
if (!$prefix) {
|
||||
$this->fallbackDirsPsr4 = (array) $paths;
|
||||
} else {
|
||||
$length = strlen($prefix);
|
||||
if ('\\' !== $prefix[$length - 1]) {
|
||||
throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator.");
|
||||
}
|
||||
$this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length;
|
||||
$this->prefixDirsPsr4[$prefix] = (array) $paths;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Turns on searching the include path for class files.
|
||||
*
|
||||
* @param bool $useIncludePath
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setUseIncludePath($useIncludePath)
|
||||
{
|
||||
$this->useIncludePath = $useIncludePath;
|
||||
}
|
||||
|
||||
/**
|
||||
* Can be used to check if the autoloader uses the include path to check
|
||||
* for classes.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function getUseIncludePath()
|
||||
{
|
||||
return $this->useIncludePath;
|
||||
}
|
||||
|
||||
/**
|
||||
* Turns off searching the prefix and fallback directories for classes
|
||||
* that have not been registered with the class map.
|
||||
*
|
||||
* @param bool $classMapAuthoritative
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setClassMapAuthoritative($classMapAuthoritative)
|
||||
{
|
||||
$this->classMapAuthoritative = $classMapAuthoritative;
|
||||
}
|
||||
|
||||
/**
|
||||
* Should class lookup fail if not found in the current class map?
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isClassMapAuthoritative()
|
||||
{
|
||||
return $this->classMapAuthoritative;
|
||||
}
|
||||
|
||||
/**
|
||||
* APCu prefix to use to cache found/not-found classes, if the extension is enabled.
|
||||
*
|
||||
* @param string|null $apcuPrefix
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setApcuPrefix($apcuPrefix)
|
||||
{
|
||||
$this->apcuPrefix = function_exists('apcu_fetch') && filter_var(ini_get('apc.enabled'), FILTER_VALIDATE_BOOLEAN) ? $apcuPrefix : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* The APCu prefix in use, or null if APCu caching is not enabled.
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
public function getApcuPrefix()
|
||||
{
|
||||
return $this->apcuPrefix;
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers this instance as an autoloader.
|
||||
*
|
||||
* @param bool $prepend Whether to prepend the autoloader or not
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function register($prepend = false)
|
||||
{
|
||||
spl_autoload_register(array($this, 'loadClass'), true, $prepend);
|
||||
|
||||
if (null === $this->vendorDir) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ($prepend) {
|
||||
self::$registeredLoaders = array($this->vendorDir => $this) + self::$registeredLoaders;
|
||||
} else {
|
||||
unset(self::$registeredLoaders[$this->vendorDir]);
|
||||
self::$registeredLoaders[$this->vendorDir] = $this;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Unregisters this instance as an autoloader.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function unregister()
|
||||
{
|
||||
spl_autoload_unregister(array($this, 'loadClass'));
|
||||
|
||||
if (null !== $this->vendorDir) {
|
||||
unset(self::$registeredLoaders[$this->vendorDir]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads the given class or interface.
|
||||
*
|
||||
* @param string $class The name of the class
|
||||
* @return true|null True if loaded, null otherwise
|
||||
*/
|
||||
public function loadClass($class)
|
||||
{
|
||||
if ($file = $this->findFile($class)) {
|
||||
$includeFile = self::$includeFile;
|
||||
$includeFile($file);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds the path to the file where the class is defined.
|
||||
*
|
||||
* @param string $class The name of the class
|
||||
*
|
||||
* @return string|false The path if found, false otherwise
|
||||
*/
|
||||
public function findFile($class)
|
||||
{
|
||||
// class map lookup
|
||||
if (isset($this->classMap[$class])) {
|
||||
return $this->classMap[$class];
|
||||
}
|
||||
if ($this->classMapAuthoritative || isset($this->missingClasses[$class])) {
|
||||
return false;
|
||||
}
|
||||
if (null !== $this->apcuPrefix) {
|
||||
$file = apcu_fetch($this->apcuPrefix.$class, $hit);
|
||||
if ($hit) {
|
||||
return $file;
|
||||
}
|
||||
}
|
||||
|
||||
$file = $this->findFileWithExtension($class, '.php');
|
||||
|
||||
// Search for Hack files if we are running on HHVM
|
||||
if (false === $file && defined('HHVM_VERSION')) {
|
||||
$file = $this->findFileWithExtension($class, '.hh');
|
||||
}
|
||||
|
||||
if (null !== $this->apcuPrefix) {
|
||||
apcu_add($this->apcuPrefix.$class, $file);
|
||||
}
|
||||
|
||||
if (false === $file) {
|
||||
// Remember that this class does not exist.
|
||||
$this->missingClasses[$class] = true;
|
||||
}
|
||||
|
||||
return $file;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the currently registered loaders indexed by their corresponding vendor directories.
|
||||
*
|
||||
* @return self[]
|
||||
*/
|
||||
public static function getRegisteredLoaders()
|
||||
{
|
||||
return self::$registeredLoaders;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $class
|
||||
* @param string $ext
|
||||
* @return string|false
|
||||
*/
|
||||
private function findFileWithExtension($class, $ext)
|
||||
{
|
||||
// PSR-4 lookup
|
||||
$logicalPathPsr4 = strtr($class, '\\', DIRECTORY_SEPARATOR) . $ext;
|
||||
|
||||
$first = $class[0];
|
||||
if (isset($this->prefixLengthsPsr4[$first])) {
|
||||
$subPath = $class;
|
||||
while (false !== $lastPos = strrpos($subPath, '\\')) {
|
||||
$subPath = substr($subPath, 0, $lastPos);
|
||||
$search = $subPath . '\\';
|
||||
if (isset($this->prefixDirsPsr4[$search])) {
|
||||
$pathEnd = DIRECTORY_SEPARATOR . substr($logicalPathPsr4, $lastPos + 1);
|
||||
foreach ($this->prefixDirsPsr4[$search] as $dir) {
|
||||
if (file_exists($file = $dir . $pathEnd)) {
|
||||
return $file;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// PSR-4 fallback dirs
|
||||
foreach ($this->fallbackDirsPsr4 as $dir) {
|
||||
if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr4)) {
|
||||
return $file;
|
||||
}
|
||||
}
|
||||
|
||||
// PSR-0 lookup
|
||||
if (false !== $pos = strrpos($class, '\\')) {
|
||||
// namespaced class name
|
||||
$logicalPathPsr0 = substr($logicalPathPsr4, 0, $pos + 1)
|
||||
. strtr(substr($logicalPathPsr4, $pos + 1), '_', DIRECTORY_SEPARATOR);
|
||||
} else {
|
||||
// PEAR-like class name
|
||||
$logicalPathPsr0 = strtr($class, '_', DIRECTORY_SEPARATOR) . $ext;
|
||||
}
|
||||
|
||||
if (isset($this->prefixesPsr0[$first])) {
|
||||
foreach ($this->prefixesPsr0[$first] as $prefix => $dirs) {
|
||||
if (0 === strpos($class, $prefix)) {
|
||||
foreach ($dirs as $dir) {
|
||||
if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) {
|
||||
return $file;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// PSR-0 fallback dirs
|
||||
foreach ($this->fallbackDirsPsr0 as $dir) {
|
||||
if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) {
|
||||
return $file;
|
||||
}
|
||||
}
|
||||
|
||||
// PSR-0 include paths.
|
||||
if ($this->useIncludePath && $file = stream_resolve_include_path($logicalPathPsr0)) {
|
||||
return $file;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
private static function initializeIncludeClosure()
|
||||
{
|
||||
if (self::$includeFile !== null) {
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Scope isolated include.
|
||||
*
|
||||
* Prevents access to $this/self from included files.
|
||||
*
|
||||
* @param string $file
|
||||
* @return void
|
||||
*/
|
||||
self::$includeFile = \Closure::bind(static function($file) {
|
||||
include $file;
|
||||
}, null, null);
|
||||
}
|
||||
}
|
@ -0,0 +1,359 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Composer.
|
||||
*
|
||||
* (c) Nils Adermann <naderman@naderman.de>
|
||||
* Jordi Boggiano <j.boggiano@seld.be>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Composer;
|
||||
|
||||
use Composer\Autoload\ClassLoader;
|
||||
use Composer\Semver\VersionParser;
|
||||
|
||||
/**
|
||||
* This class is copied in every Composer installed project and available to all
|
||||
*
|
||||
* See also https://getcomposer.org/doc/07-runtime.md#installed-versions
|
||||
*
|
||||
* To require its presence, you can require `composer-runtime-api ^2.0`
|
||||
*
|
||||
* @final
|
||||
*/
|
||||
class InstalledVersions
|
||||
{
|
||||
/**
|
||||
* @var mixed[]|null
|
||||
* @psalm-var array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>}|array{}|null
|
||||
*/
|
||||
private static $installed;
|
||||
|
||||
/**
|
||||
* @var bool|null
|
||||
*/
|
||||
private static $canGetVendors;
|
||||
|
||||
/**
|
||||
* @var array[]
|
||||
* @psalm-var array<string, array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>}>
|
||||
*/
|
||||
private static $installedByVendor = array();
|
||||
|
||||
/**
|
||||
* Returns a list of all package names which are present, either by being installed, replaced or provided
|
||||
*
|
||||
* @return string[]
|
||||
* @psalm-return list<string>
|
||||
*/
|
||||
public static function getInstalledPackages()
|
||||
{
|
||||
$packages = array();
|
||||
foreach (self::getInstalled() as $installed) {
|
||||
$packages[] = array_keys($installed['versions']);
|
||||
}
|
||||
|
||||
if (1 === \count($packages)) {
|
||||
return $packages[0];
|
||||
}
|
||||
|
||||
return array_keys(array_flip(\call_user_func_array('array_merge', $packages)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a list of all package names with a specific type e.g. 'library'
|
||||
*
|
||||
* @param string $type
|
||||
* @return string[]
|
||||
* @psalm-return list<string>
|
||||
*/
|
||||
public static function getInstalledPackagesByType($type)
|
||||
{
|
||||
$packagesByType = array();
|
||||
|
||||
foreach (self::getInstalled() as $installed) {
|
||||
foreach ($installed['versions'] as $name => $package) {
|
||||
if (isset($package['type']) && $package['type'] === $type) {
|
||||
$packagesByType[] = $name;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $packagesByType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether the given package is installed
|
||||
*
|
||||
* This also returns true if the package name is provided or replaced by another package
|
||||
*
|
||||
* @param string $packageName
|
||||
* @param bool $includeDevRequirements
|
||||
* @return bool
|
||||
*/
|
||||
public static function isInstalled($packageName, $includeDevRequirements = true)
|
||||
{
|
||||
foreach (self::getInstalled() as $installed) {
|
||||
if (isset($installed['versions'][$packageName])) {
|
||||
return $includeDevRequirements || !isset($installed['versions'][$packageName]['dev_requirement']) || $installed['versions'][$packageName]['dev_requirement'] === false;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether the given package satisfies a version constraint
|
||||
*
|
||||
* e.g. If you want to know whether version 2.3+ of package foo/bar is installed, you would call:
|
||||
*
|
||||
* Composer\InstalledVersions::satisfies(new VersionParser, 'foo/bar', '^2.3')
|
||||
*
|
||||
* @param VersionParser $parser Install composer/semver to have access to this class and functionality
|
||||
* @param string $packageName
|
||||
* @param string|null $constraint A version constraint to check for, if you pass one you have to make sure composer/semver is required by your package
|
||||
* @return bool
|
||||
*/
|
||||
public static function satisfies(VersionParser $parser, $packageName, $constraint)
|
||||
{
|
||||
$constraint = $parser->parseConstraints((string) $constraint);
|
||||
$provided = $parser->parseConstraints(self::getVersionRanges($packageName));
|
||||
|
||||
return $provided->matches($constraint);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a version constraint representing all the range(s) which are installed for a given package
|
||||
*
|
||||
* It is easier to use this via isInstalled() with the $constraint argument if you need to check
|
||||
* whether a given version of a package is installed, and not just whether it exists
|
||||
*
|
||||
* @param string $packageName
|
||||
* @return string Version constraint usable with composer/semver
|
||||
*/
|
||||
public static function getVersionRanges($packageName)
|
||||
{
|
||||
foreach (self::getInstalled() as $installed) {
|
||||
if (!isset($installed['versions'][$packageName])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$ranges = array();
|
||||
if (isset($installed['versions'][$packageName]['pretty_version'])) {
|
||||
$ranges[] = $installed['versions'][$packageName]['pretty_version'];
|
||||
}
|
||||
if (array_key_exists('aliases', $installed['versions'][$packageName])) {
|
||||
$ranges = array_merge($ranges, $installed['versions'][$packageName]['aliases']);
|
||||
}
|
||||
if (array_key_exists('replaced', $installed['versions'][$packageName])) {
|
||||
$ranges = array_merge($ranges, $installed['versions'][$packageName]['replaced']);
|
||||
}
|
||||
if (array_key_exists('provided', $installed['versions'][$packageName])) {
|
||||
$ranges = array_merge($ranges, $installed['versions'][$packageName]['provided']);
|
||||
}
|
||||
|
||||
return implode(' || ', $ranges);
|
||||
}
|
||||
|
||||
throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $packageName
|
||||
* @return string|null If the package is being replaced or provided but is not really installed, null will be returned as version, use satisfies or getVersionRanges if you need to know if a given version is present
|
||||
*/
|
||||
public static function getVersion($packageName)
|
||||
{
|
||||
foreach (self::getInstalled() as $installed) {
|
||||
if (!isset($installed['versions'][$packageName])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!isset($installed['versions'][$packageName]['version'])) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return $installed['versions'][$packageName]['version'];
|
||||
}
|
||||
|
||||
throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $packageName
|
||||
* @return string|null If the package is being replaced or provided but is not really installed, null will be returned as version, use satisfies or getVersionRanges if you need to know if a given version is present
|
||||
*/
|
||||
public static function getPrettyVersion($packageName)
|
||||
{
|
||||
foreach (self::getInstalled() as $installed) {
|
||||
if (!isset($installed['versions'][$packageName])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!isset($installed['versions'][$packageName]['pretty_version'])) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return $installed['versions'][$packageName]['pretty_version'];
|
||||
}
|
||||
|
||||
throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $packageName
|
||||
* @return string|null If the package is being replaced or provided but is not really installed, null will be returned as reference
|
||||
*/
|
||||
public static function getReference($packageName)
|
||||
{
|
||||
foreach (self::getInstalled() as $installed) {
|
||||
if (!isset($installed['versions'][$packageName])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!isset($installed['versions'][$packageName]['reference'])) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return $installed['versions'][$packageName]['reference'];
|
||||
}
|
||||
|
||||
throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $packageName
|
||||
* @return string|null If the package is being replaced or provided but is not really installed, null will be returned as install path. Packages of type metapackages also have a null install path.
|
||||
*/
|
||||
public static function getInstallPath($packageName)
|
||||
{
|
||||
foreach (self::getInstalled() as $installed) {
|
||||
if (!isset($installed['versions'][$packageName])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
return isset($installed['versions'][$packageName]['install_path']) ? $installed['versions'][$packageName]['install_path'] : null;
|
||||
}
|
||||
|
||||
throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed');
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
* @psalm-return array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}
|
||||
*/
|
||||
public static function getRootPackage()
|
||||
{
|
||||
$installed = self::getInstalled();
|
||||
|
||||
return $installed[0]['root'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the raw installed.php data for custom implementations
|
||||
*
|
||||
* @deprecated Use getAllRawData() instead which returns all datasets for all autoloaders present in the process. getRawData only returns the first dataset loaded, which may not be what you expect.
|
||||
* @return array[]
|
||||
* @psalm-return array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>}
|
||||
*/
|
||||
public static function getRawData()
|
||||
{
|
||||
@trigger_error('getRawData only returns the first dataset loaded, which may not be what you expect. Use getAllRawData() instead which returns all datasets for all autoloaders present in the process.', E_USER_DEPRECATED);
|
||||
|
||||
if (null === self::$installed) {
|
||||
// only require the installed.php file if this file is loaded from its dumped location,
|
||||
// and not from its source location in the composer/composer package, see https://github.com/composer/composer/issues/9937
|
||||
if (substr(__DIR__, -8, 1) !== 'C') {
|
||||
self::$installed = include __DIR__ . '/installed.php';
|
||||
} else {
|
||||
self::$installed = array();
|
||||
}
|
||||
}
|
||||
|
||||
return self::$installed;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the raw data of all installed.php which are currently loaded for custom implementations
|
||||
*
|
||||
* @return array[]
|
||||
* @psalm-return list<array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>}>
|
||||
*/
|
||||
public static function getAllRawData()
|
||||
{
|
||||
return self::getInstalled();
|
||||
}
|
||||
|
||||
/**
|
||||
* Lets you reload the static array from another file
|
||||
*
|
||||
* This is only useful for complex integrations in which a project needs to use
|
||||
* this class but then also needs to execute another project's autoloader in process,
|
||||
* and wants to ensure both projects have access to their version of installed.php.
|
||||
*
|
||||
* A typical case would be PHPUnit, where it would need to make sure it reads all
|
||||
* the data it needs from this class, then call reload() with
|
||||
* `require $CWD/vendor/composer/installed.php` (or similar) as input to make sure
|
||||
* the project in which it runs can then also use this class safely, without
|
||||
* interference between PHPUnit's dependencies and the project's dependencies.
|
||||
*
|
||||
* @param array[] $data A vendor/composer/installed.php data set
|
||||
* @return void
|
||||
*
|
||||
* @psalm-param array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>} $data
|
||||
*/
|
||||
public static function reload($data)
|
||||
{
|
||||
self::$installed = $data;
|
||||
self::$installedByVendor = array();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array[]
|
||||
* @psalm-return list<array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>}>
|
||||
*/
|
||||
private static function getInstalled()
|
||||
{
|
||||
if (null === self::$canGetVendors) {
|
||||
self::$canGetVendors = method_exists('Composer\Autoload\ClassLoader', 'getRegisteredLoaders');
|
||||
}
|
||||
|
||||
$installed = array();
|
||||
|
||||
if (self::$canGetVendors) {
|
||||
foreach (ClassLoader::getRegisteredLoaders() as $vendorDir => $loader) {
|
||||
if (isset(self::$installedByVendor[$vendorDir])) {
|
||||
$installed[] = self::$installedByVendor[$vendorDir];
|
||||
} elseif (is_file($vendorDir.'/composer/installed.php')) {
|
||||
/** @var array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>} $required */
|
||||
$required = require $vendorDir.'/composer/installed.php';
|
||||
$installed[] = self::$installedByVendor[$vendorDir] = $required;
|
||||
if (null === self::$installed && strtr($vendorDir.'/composer', '\\', '/') === strtr(__DIR__, '\\', '/')) {
|
||||
self::$installed = $installed[count($installed) - 1];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (null === self::$installed) {
|
||||
// only require the installed.php file if this file is loaded from its dumped location,
|
||||
// and not from its source location in the composer/composer package, see https://github.com/composer/composer/issues/9937
|
||||
if (substr(__DIR__, -8, 1) !== 'C') {
|
||||
/** @var array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>} $required */
|
||||
$required = require __DIR__ . '/installed.php';
|
||||
self::$installed = $required;
|
||||
} else {
|
||||
self::$installed = array();
|
||||
}
|
||||
}
|
||||
|
||||
if (self::$installed !== array()) {
|
||||
$installed[] = self::$installed;
|
||||
}
|
||||
|
||||
return $installed;
|
||||
}
|
||||
}
|
@ -0,0 +1,21 @@
|
||||
|
||||
Copyright (c) Nils Adermann, Jordi Boggiano
|
||||
|
||||
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.
|
||||
|
@ -0,0 +1,15 @@
|
||||
<?php
|
||||
|
||||
// autoload_classmap.php @generated by Composer
|
||||
|
||||
$vendorDir = dirname(__DIR__);
|
||||
$baseDir = dirname($vendorDir);
|
||||
|
||||
return array(
|
||||
'Attribute' => $vendorDir . '/symfony/polyfill-php80/Resources/stubs/Attribute.php',
|
||||
'Composer\\InstalledVersions' => $vendorDir . '/composer/InstalledVersions.php',
|
||||
'PhpToken' => $vendorDir . '/symfony/polyfill-php80/Resources/stubs/PhpToken.php',
|
||||
'Stringable' => $vendorDir . '/symfony/polyfill-php80/Resources/stubs/Stringable.php',
|
||||
'UnhandledMatchError' => $vendorDir . '/symfony/polyfill-php80/Resources/stubs/UnhandledMatchError.php',
|
||||
'ValueError' => $vendorDir . '/symfony/polyfill-php80/Resources/stubs/ValueError.php',
|
||||
);
|
@ -0,0 +1,12 @@
|
||||
<?php
|
||||
|
||||
// autoload_files.php @generated by Composer
|
||||
|
||||
$vendorDir = dirname(__DIR__);
|
||||
$baseDir = dirname($vendorDir);
|
||||
|
||||
return array(
|
||||
'253c157292f75eb38082b5acb06f3f01' => $vendorDir . '/nikic/fast-route/src/functions.php',
|
||||
'7b11c4dc42b3b3023073cb14e519683c' => $vendorDir . '/ralouphie/getallheaders/src/getallheaders.php',
|
||||
'a4a119a56e50fbb293281d9a48007e0e' => $vendorDir . '/symfony/polyfill-php80/bootstrap.php',
|
||||
);
|
@ -0,0 +1,9 @@
|
||||
<?php
|
||||
|
||||
// autoload_namespaces.php @generated by Composer
|
||||
|
||||
$vendorDir = dirname(__DIR__);
|
||||
$baseDir = dirname($vendorDir);
|
||||
|
||||
return array(
|
||||
);
|
@ -0,0 +1,18 @@
|
||||
<?php
|
||||
|
||||
// autoload_psr4.php @generated by Composer
|
||||
|
||||
$vendorDir = dirname(__DIR__);
|
||||
$baseDir = dirname($vendorDir);
|
||||
|
||||
return array(
|
||||
'Symfony\\Polyfill\\Php80\\' => array($vendorDir . '/symfony/polyfill-php80'),
|
||||
'Slim\\Psr7\\' => array($vendorDir . '/slim/psr7/src'),
|
||||
'Slim\\' => array($vendorDir . '/slim/slim/Slim'),
|
||||
'Psr\\Log\\' => array($vendorDir . '/psr/log/src'),
|
||||
'Psr\\Http\\Server\\' => array($vendorDir . '/psr/http-server-handler/src', $vendorDir . '/psr/http-server-middleware/src'),
|
||||
'Psr\\Http\\Message\\' => array($vendorDir . '/psr/http-factory/src', $vendorDir . '/psr/http-message/src'),
|
||||
'Psr\\Container\\' => array($vendorDir . '/psr/container/src'),
|
||||
'Fig\\Http\\Message\\' => array($vendorDir . '/fig/http-message-util/src'),
|
||||
'FastRoute\\' => array($vendorDir . '/nikic/fast-route/src'),
|
||||
);
|
@ -0,0 +1,50 @@
|
||||
<?php
|
||||
|
||||
// autoload_real.php @generated by Composer
|
||||
|
||||
class ComposerAutoloaderInit344c194729b7446a4ea6541135c6e068
|
||||
{
|
||||
private static $loader;
|
||||
|
||||
public static function loadClassLoader($class)
|
||||
{
|
||||
if ('Composer\Autoload\ClassLoader' === $class) {
|
||||
require __DIR__ . '/ClassLoader.php';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \Composer\Autoload\ClassLoader
|
||||
*/
|
||||
public static function getLoader()
|
||||
{
|
||||
if (null !== self::$loader) {
|
||||
return self::$loader;
|
||||
}
|
||||
|
||||
require __DIR__ . '/platform_check.php';
|
||||
|
||||
spl_autoload_register(array('ComposerAutoloaderInit344c194729b7446a4ea6541135c6e068', 'loadClassLoader'), true, true);
|
||||
self::$loader = $loader = new \Composer\Autoload\ClassLoader(\dirname(__DIR__));
|
||||
spl_autoload_unregister(array('ComposerAutoloaderInit344c194729b7446a4ea6541135c6e068', 'loadClassLoader'));
|
||||
|
||||
require __DIR__ . '/autoload_static.php';
|
||||
call_user_func(\Composer\Autoload\ComposerStaticInit344c194729b7446a4ea6541135c6e068::getInitializer($loader));
|
||||
|
||||
$loader->register(true);
|
||||
|
||||
$filesToLoad = \Composer\Autoload\ComposerStaticInit344c194729b7446a4ea6541135c6e068::$files;
|
||||
$requireFile = \Closure::bind(static function ($fileIdentifier, $file) {
|
||||
if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) {
|
||||
$GLOBALS['__composer_autoload_files'][$fileIdentifier] = true;
|
||||
|
||||
require $file;
|
||||
}
|
||||
}, null, null);
|
||||
foreach ($filesToLoad as $fileIdentifier => $file) {
|
||||
$requireFile($fileIdentifier, $file);
|
||||
}
|
||||
|
||||
return $loader;
|
||||
}
|
||||
}
|
@ -0,0 +1,95 @@
|
||||
<?php
|
||||
|
||||
// autoload_static.php @generated by Composer
|
||||
|
||||
namespace Composer\Autoload;
|
||||
|
||||
class ComposerStaticInit344c194729b7446a4ea6541135c6e068
|
||||
{
|
||||
public static $files = array (
|
||||
'253c157292f75eb38082b5acb06f3f01' => __DIR__ . '/..' . '/nikic/fast-route/src/functions.php',
|
||||
'7b11c4dc42b3b3023073cb14e519683c' => __DIR__ . '/..' . '/ralouphie/getallheaders/src/getallheaders.php',
|
||||
'a4a119a56e50fbb293281d9a48007e0e' => __DIR__ . '/..' . '/symfony/polyfill-php80/bootstrap.php',
|
||||
);
|
||||
|
||||
public static $prefixLengthsPsr4 = array (
|
||||
'S' =>
|
||||
array (
|
||||
'Symfony\\Polyfill\\Php80\\' => 23,
|
||||
'Slim\\Psr7\\' => 10,
|
||||
'Slim\\' => 5,
|
||||
),
|
||||
'P' =>
|
||||
array (
|
||||
'Psr\\Log\\' => 8,
|
||||
'Psr\\Http\\Server\\' => 16,
|
||||
'Psr\\Http\\Message\\' => 17,
|
||||
'Psr\\Container\\' => 14,
|
||||
),
|
||||
'F' =>
|
||||
array (
|
||||
'Fig\\Http\\Message\\' => 17,
|
||||
'FastRoute\\' => 10,
|
||||
),
|
||||
);
|
||||
|
||||
public static $prefixDirsPsr4 = array (
|
||||
'Symfony\\Polyfill\\Php80\\' =>
|
||||
array (
|
||||
0 => __DIR__ . '/..' . '/symfony/polyfill-php80',
|
||||
),
|
||||
'Slim\\Psr7\\' =>
|
||||
array (
|
||||
0 => __DIR__ . '/..' . '/slim/psr7/src',
|
||||
),
|
||||
'Slim\\' =>
|
||||
array (
|
||||
0 => __DIR__ . '/..' . '/slim/slim/Slim',
|
||||
),
|
||||
'Psr\\Log\\' =>
|
||||
array (
|
||||
0 => __DIR__ . '/..' . '/psr/log/src',
|
||||
),
|
||||
'Psr\\Http\\Server\\' =>
|
||||
array (
|
||||
0 => __DIR__ . '/..' . '/psr/http-server-handler/src',
|
||||
1 => __DIR__ . '/..' . '/psr/http-server-middleware/src',
|
||||
),
|
||||
'Psr\\Http\\Message\\' =>
|
||||
array (
|
||||
0 => __DIR__ . '/..' . '/psr/http-factory/src',
|
||||
1 => __DIR__ . '/..' . '/psr/http-message/src',
|
||||
),
|
||||
'Psr\\Container\\' =>
|
||||
array (
|
||||
0 => __DIR__ . '/..' . '/psr/container/src',
|
||||
),
|
||||
'Fig\\Http\\Message\\' =>
|
||||
array (
|
||||
0 => __DIR__ . '/..' . '/fig/http-message-util/src',
|
||||
),
|
||||
'FastRoute\\' =>
|
||||
array (
|
||||
0 => __DIR__ . '/..' . '/nikic/fast-route/src',
|
||||
),
|
||||
);
|
||||
|
||||
public static $classMap = array (
|
||||
'Attribute' => __DIR__ . '/..' . '/symfony/polyfill-php80/Resources/stubs/Attribute.php',
|
||||
'Composer\\InstalledVersions' => __DIR__ . '/..' . '/composer/InstalledVersions.php',
|
||||
'PhpToken' => __DIR__ . '/..' . '/symfony/polyfill-php80/Resources/stubs/PhpToken.php',
|
||||
'Stringable' => __DIR__ . '/..' . '/symfony/polyfill-php80/Resources/stubs/Stringable.php',
|
||||
'UnhandledMatchError' => __DIR__ . '/..' . '/symfony/polyfill-php80/Resources/stubs/UnhandledMatchError.php',
|
||||
'ValueError' => __DIR__ . '/..' . '/symfony/polyfill-php80/Resources/stubs/ValueError.php',
|
||||
);
|
||||
|
||||
public static function getInitializer(ClassLoader $loader)
|
||||
{
|
||||
return \Closure::bind(function () use ($loader) {
|
||||
$loader->prefixLengthsPsr4 = ComposerStaticInit344c194729b7446a4ea6541135c6e068::$prefixLengthsPsr4;
|
||||
$loader->prefixDirsPsr4 = ComposerStaticInit344c194729b7446a4ea6541135c6e068::$prefixDirsPsr4;
|
||||
$loader->classMap = ComposerStaticInit344c194729b7446a4ea6541135c6e068::$classMap;
|
||||
|
||||
}, null, ClassLoader::class);
|
||||
}
|
||||
}
|
@ -0,0 +1,797 @@
|
||||
{
|
||||
"packages": [
|
||||
{
|
||||
"name": "fig/http-message-util",
|
||||
"version": "1.1.5",
|
||||
"version_normalized": "1.1.5.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/php-fig/http-message-util.git",
|
||||
"reference": "9d94dc0154230ac39e5bf89398b324a86f63f765"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/php-fig/http-message-util/zipball/9d94dc0154230ac39e5bf89398b324a86f63f765",
|
||||
"reference": "9d94dc0154230ac39e5bf89398b324a86f63f765",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": "^5.3 || ^7.0 || ^8.0"
|
||||
},
|
||||
"suggest": {
|
||||
"psr/http-message": "The package containing the PSR-7 interfaces"
|
||||
},
|
||||
"time": "2020-11-24T22:02:12+00:00",
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "1.1.x-dev"
|
||||
}
|
||||
},
|
||||
"installation-source": "dist",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Fig\\Http\\Message\\": "src/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "PHP-FIG",
|
||||
"homepage": "https://www.php-fig.org/"
|
||||
}
|
||||
],
|
||||
"description": "Utility classes and constants for use with PSR-7 (psr/http-message)",
|
||||
"keywords": [
|
||||
"http",
|
||||
"http-message",
|
||||
"psr",
|
||||
"psr-7",
|
||||
"request",
|
||||
"response"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/php-fig/http-message-util/issues",
|
||||
"source": "https://github.com/php-fig/http-message-util/tree/1.1.5"
|
||||
},
|
||||
"install-path": "../fig/http-message-util"
|
||||
},
|
||||
{
|
||||
"name": "nikic/fast-route",
|
||||
"version": "v1.3.0",
|
||||
"version_normalized": "1.3.0.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/nikic/FastRoute.git",
|
||||
"reference": "181d480e08d9476e61381e04a71b34dc0432e812"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/nikic/FastRoute/zipball/181d480e08d9476e61381e04a71b34dc0432e812",
|
||||
"reference": "181d480e08d9476e61381e04a71b34dc0432e812",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=5.4.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "^4.8.35|~5.7"
|
||||
},
|
||||
"time": "2018-02-13T20:26:39+00:00",
|
||||
"type": "library",
|
||||
"installation-source": "dist",
|
||||
"autoload": {
|
||||
"files": [
|
||||
"src/functions.php"
|
||||
],
|
||||
"psr-4": {
|
||||
"FastRoute\\": "src/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"BSD-3-Clause"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Nikita Popov",
|
||||
"email": "nikic@php.net"
|
||||
}
|
||||
],
|
||||
"description": "Fast request router for PHP",
|
||||
"keywords": [
|
||||
"router",
|
||||
"routing"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/nikic/FastRoute/issues",
|
||||
"source": "https://github.com/nikic/FastRoute/tree/master"
|
||||
},
|
||||
"install-path": "../nikic/fast-route"
|
||||
},
|
||||
{
|
||||
"name": "psr/container",
|
||||
"version": "2.0.2",
|
||||
"version_normalized": "2.0.2.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/php-fig/container.git",
|
||||
"reference": "c71ecc56dfe541dbd90c5360474fbc405f8d5963"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/php-fig/container/zipball/c71ecc56dfe541dbd90c5360474fbc405f8d5963",
|
||||
"reference": "c71ecc56dfe541dbd90c5360474fbc405f8d5963",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=7.4.0"
|
||||
},
|
||||
"time": "2021-11-05T16:47:00+00:00",
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "2.0.x-dev"
|
||||
}
|
||||
},
|
||||
"installation-source": "dist",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Psr\\Container\\": "src/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "PHP-FIG",
|
||||
"homepage": "https://www.php-fig.org/"
|
||||
}
|
||||
],
|
||||
"description": "Common Container Interface (PHP FIG PSR-11)",
|
||||
"homepage": "https://github.com/php-fig/container",
|
||||
"keywords": [
|
||||
"PSR-11",
|
||||
"container",
|
||||
"container-interface",
|
||||
"container-interop",
|
||||
"psr"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/php-fig/container/issues",
|
||||
"source": "https://github.com/php-fig/container/tree/2.0.2"
|
||||
},
|
||||
"install-path": "../psr/container"
|
||||
},
|
||||
{
|
||||
"name": "psr/http-factory",
|
||||
"version": "1.0.1",
|
||||
"version_normalized": "1.0.1.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/php-fig/http-factory.git",
|
||||
"reference": "12ac7fcd07e5b077433f5f2bee95b3a771bf61be"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/php-fig/http-factory/zipball/12ac7fcd07e5b077433f5f2bee95b3a771bf61be",
|
||||
"reference": "12ac7fcd07e5b077433f5f2bee95b3a771bf61be",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=7.0.0",
|
||||
"psr/http-message": "^1.0"
|
||||
},
|
||||
"time": "2019-04-30T12:38:16+00:00",
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "1.0.x-dev"
|
||||
}
|
||||
},
|
||||
"installation-source": "dist",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Psr\\Http\\Message\\": "src/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "PHP-FIG",
|
||||
"homepage": "http://www.php-fig.org/"
|
||||
}
|
||||
],
|
||||
"description": "Common interfaces for PSR-7 HTTP message factories",
|
||||
"keywords": [
|
||||
"factory",
|
||||
"http",
|
||||
"message",
|
||||
"psr",
|
||||
"psr-17",
|
||||
"psr-7",
|
||||
"request",
|
||||
"response"
|
||||
],
|
||||
"support": {
|
||||
"source": "https://github.com/php-fig/http-factory/tree/master"
|
||||
},
|
||||
"install-path": "../psr/http-factory"
|
||||
},
|
||||
{
|
||||
"name": "psr/http-message",
|
||||
"version": "1.0.1",
|
||||
"version_normalized": "1.0.1.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/php-fig/http-message.git",
|
||||
"reference": "f6561bf28d520154e4b0ec72be95418abe6d9363"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/php-fig/http-message/zipball/f6561bf28d520154e4b0ec72be95418abe6d9363",
|
||||
"reference": "f6561bf28d520154e4b0ec72be95418abe6d9363",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=5.3.0"
|
||||
},
|
||||
"time": "2016-08-06T14:39:51+00:00",
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "1.0.x-dev"
|
||||
}
|
||||
},
|
||||
"installation-source": "dist",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Psr\\Http\\Message\\": "src/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "PHP-FIG",
|
||||
"homepage": "http://www.php-fig.org/"
|
||||
}
|
||||
],
|
||||
"description": "Common interface for HTTP messages",
|
||||
"homepage": "https://github.com/php-fig/http-message",
|
||||
"keywords": [
|
||||
"http",
|
||||
"http-message",
|
||||
"psr",
|
||||
"psr-7",
|
||||
"request",
|
||||
"response"
|
||||
],
|
||||
"support": {
|
||||
"source": "https://github.com/php-fig/http-message/tree/master"
|
||||
},
|
||||
"install-path": "../psr/http-message"
|
||||
},
|
||||
{
|
||||
"name": "psr/http-server-handler",
|
||||
"version": "1.0.1",
|
||||
"version_normalized": "1.0.1.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/php-fig/http-server-handler.git",
|
||||
"reference": "aff2f80e33b7f026ec96bb42f63242dc50ffcae7"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/php-fig/http-server-handler/zipball/aff2f80e33b7f026ec96bb42f63242dc50ffcae7",
|
||||
"reference": "aff2f80e33b7f026ec96bb42f63242dc50ffcae7",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=7.0",
|
||||
"psr/http-message": "^1.0"
|
||||
},
|
||||
"time": "2018-10-30T16:46:14+00:00",
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "1.0.x-dev"
|
||||
}
|
||||
},
|
||||
"installation-source": "dist",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Psr\\Http\\Server\\": "src/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "PHP-FIG",
|
||||
"homepage": "http://www.php-fig.org/"
|
||||
}
|
||||
],
|
||||
"description": "Common interface for HTTP server-side request handler",
|
||||
"keywords": [
|
||||
"handler",
|
||||
"http",
|
||||
"http-interop",
|
||||
"psr",
|
||||
"psr-15",
|
||||
"psr-7",
|
||||
"request",
|
||||
"response",
|
||||
"server"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/php-fig/http-server-handler/issues",
|
||||
"source": "https://github.com/php-fig/http-server-handler/tree/master"
|
||||
},
|
||||
"install-path": "../psr/http-server-handler"
|
||||
},
|
||||
{
|
||||
"name": "psr/http-server-middleware",
|
||||
"version": "1.0.1",
|
||||
"version_normalized": "1.0.1.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/php-fig/http-server-middleware.git",
|
||||
"reference": "2296f45510945530b9dceb8bcedb5cb84d40c5f5"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/php-fig/http-server-middleware/zipball/2296f45510945530b9dceb8bcedb5cb84d40c5f5",
|
||||
"reference": "2296f45510945530b9dceb8bcedb5cb84d40c5f5",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=7.0",
|
||||
"psr/http-message": "^1.0",
|
||||
"psr/http-server-handler": "^1.0"
|
||||
},
|
||||
"time": "2018-10-30T17:12:04+00:00",
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "1.0.x-dev"
|
||||
}
|
||||
},
|
||||
"installation-source": "dist",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Psr\\Http\\Server\\": "src/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "PHP-FIG",
|
||||
"homepage": "http://www.php-fig.org/"
|
||||
}
|
||||
],
|
||||
"description": "Common interface for HTTP server-side middleware",
|
||||
"keywords": [
|
||||
"http",
|
||||
"http-interop",
|
||||
"middleware",
|
||||
"psr",
|
||||
"psr-15",
|
||||
"psr-7",
|
||||
"request",
|
||||
"response"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/php-fig/http-server-middleware/issues",
|
||||
"source": "https://github.com/php-fig/http-server-middleware/tree/master"
|
||||
},
|
||||
"install-path": "../psr/http-server-middleware"
|
||||
},
|
||||
{
|
||||
"name": "psr/log",
|
||||
"version": "3.0.0",
|
||||
"version_normalized": "3.0.0.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/php-fig/log.git",
|
||||
"reference": "fe5ea303b0887d5caefd3d431c3e61ad47037001"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/php-fig/log/zipball/fe5ea303b0887d5caefd3d431c3e61ad47037001",
|
||||
"reference": "fe5ea303b0887d5caefd3d431c3e61ad47037001",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=8.0.0"
|
||||
},
|
||||
"time": "2021-07-14T16:46:02+00:00",
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "3.x-dev"
|
||||
}
|
||||
},
|
||||
"installation-source": "dist",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Psr\\Log\\": "src"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "PHP-FIG",
|
||||
"homepage": "https://www.php-fig.org/"
|
||||
}
|
||||
],
|
||||
"description": "Common interface for logging libraries",
|
||||
"homepage": "https://github.com/php-fig/log",
|
||||
"keywords": [
|
||||
"log",
|
||||
"psr",
|
||||
"psr-3"
|
||||
],
|
||||
"support": {
|
||||
"source": "https://github.com/php-fig/log/tree/3.0.0"
|
||||
},
|
||||
"install-path": "../psr/log"
|
||||
},
|
||||
{
|
||||
"name": "ralouphie/getallheaders",
|
||||
"version": "3.0.3",
|
||||
"version_normalized": "3.0.3.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/ralouphie/getallheaders.git",
|
||||
"reference": "120b605dfeb996808c31b6477290a714d356e822"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/ralouphie/getallheaders/zipball/120b605dfeb996808c31b6477290a714d356e822",
|
||||
"reference": "120b605dfeb996808c31b6477290a714d356e822",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=5.6"
|
||||
},
|
||||
"require-dev": {
|
||||
"php-coveralls/php-coveralls": "^2.1",
|
||||
"phpunit/phpunit": "^5 || ^6.5"
|
||||
},
|
||||
"time": "2019-03-08T08:55:37+00:00",
|
||||
"type": "library",
|
||||
"installation-source": "dist",
|
||||
"autoload": {
|
||||
"files": [
|
||||
"src/getallheaders.php"
|
||||
]
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Ralph Khattar",
|
||||
"email": "ralph.khattar@gmail.com"
|
||||
}
|
||||
],
|
||||
"description": "A polyfill for getallheaders.",
|
||||
"support": {
|
||||
"issues": "https://github.com/ralouphie/getallheaders/issues",
|
||||
"source": "https://github.com/ralouphie/getallheaders/tree/develop"
|
||||
},
|
||||
"install-path": "../ralouphie/getallheaders"
|
||||
},
|
||||
{
|
||||
"name": "slim/psr7",
|
||||
"version": "1.6",
|
||||
"version_normalized": "1.6.0.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/slimphp/Slim-Psr7.git",
|
||||
"reference": "3471c22c1a0d26c51c78f6aeb06489d38cf46a4d"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/slimphp/Slim-Psr7/zipball/3471c22c1a0d26c51c78f6aeb06489d38cf46a4d",
|
||||
"reference": "3471c22c1a0d26c51c78f6aeb06489d38cf46a4d",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"fig/http-message-util": "^1.1.5",
|
||||
"php": "^7.4 || ^8.0",
|
||||
"psr/http-factory": "^1.0",
|
||||
"psr/http-message": "^1.0",
|
||||
"ralouphie/getallheaders": "^3.0",
|
||||
"symfony/polyfill-php80": "^1.26"
|
||||
},
|
||||
"provide": {
|
||||
"psr/http-factory-implementation": "1.0",
|
||||
"psr/http-message-implementation": "1.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"adriansuter/php-autoload-override": "^1.3",
|
||||
"ext-json": "*",
|
||||
"http-interop/http-factory-tests": "^0.9.0",
|
||||
"php-http/psr7-integration-tests": "dev-master",
|
||||
"phpspec/prophecy": "^1.15",
|
||||
"phpspec/prophecy-phpunit": "^2.0",
|
||||
"phpstan/phpstan": "^1.8",
|
||||
"phpunit/phpunit": "^9.5",
|
||||
"squizlabs/php_codesniffer": "^3.7"
|
||||
},
|
||||
"time": "2022-11-05T18:50:24+00:00",
|
||||
"type": "library",
|
||||
"installation-source": "dist",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Slim\\Psr7\\": "src"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Josh Lockhart",
|
||||
"email": "hello@joshlockhart.com",
|
||||
"homepage": "http://joshlockhart.com"
|
||||
},
|
||||
{
|
||||
"name": "Andrew Smith",
|
||||
"email": "a.smith@silentworks.co.uk",
|
||||
"homepage": "http://silentworks.co.uk"
|
||||
},
|
||||
{
|
||||
"name": "Rob Allen",
|
||||
"email": "rob@akrabat.com",
|
||||
"homepage": "http://akrabat.com"
|
||||
},
|
||||
{
|
||||
"name": "Pierre Berube",
|
||||
"email": "pierre@lgse.com",
|
||||
"homepage": "http://www.lgse.com"
|
||||
}
|
||||
],
|
||||
"description": "Strict PSR-7 implementation",
|
||||
"homepage": "https://www.slimframework.com",
|
||||
"keywords": [
|
||||
"http",
|
||||
"psr-7",
|
||||
"psr7"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/slimphp/Slim-Psr7/issues",
|
||||
"source": "https://github.com/slimphp/Slim-Psr7/tree/1.6"
|
||||
},
|
||||
"install-path": "../slim/psr7"
|
||||
},
|
||||
{
|
||||
"name": "slim/slim",
|
||||
"version": "4.11.0",
|
||||
"version_normalized": "4.11.0.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/slimphp/Slim.git",
|
||||
"reference": "b0f4ca393ea037be9ac7292ba7d0a34d18bac0c7"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/slimphp/Slim/zipball/b0f4ca393ea037be9ac7292ba7d0a34d18bac0c7",
|
||||
"reference": "b0f4ca393ea037be9ac7292ba7d0a34d18bac0c7",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"ext-json": "*",
|
||||
"nikic/fast-route": "^1.3",
|
||||
"php": "^7.4 || ^8.0",
|
||||
"psr/container": "^1.0 || ^2.0",
|
||||
"psr/http-factory": "^1.0",
|
||||
"psr/http-message": "^1.0",
|
||||
"psr/http-server-handler": "^1.0",
|
||||
"psr/http-server-middleware": "^1.0",
|
||||
"psr/log": "^1.1 || ^2.0 || ^3.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"adriansuter/php-autoload-override": "^1.3",
|
||||
"ext-simplexml": "*",
|
||||
"guzzlehttp/psr7": "^2.4",
|
||||
"httpsoft/http-message": "^1.0",
|
||||
"httpsoft/http-server-request": "^1.0",
|
||||
"laminas/laminas-diactoros": "^2.17",
|
||||
"nyholm/psr7": "^1.5",
|
||||
"nyholm/psr7-server": "^1.0",
|
||||
"phpspec/prophecy": "^1.15",
|
||||
"phpspec/prophecy-phpunit": "^2.0",
|
||||
"phpstan/phpstan": "^1.8",
|
||||
"phpunit/phpunit": "^9.5",
|
||||
"slim/http": "^1.2",
|
||||
"slim/psr7": "^1.5",
|
||||
"squizlabs/php_codesniffer": "^3.7"
|
||||
},
|
||||
"suggest": {
|
||||
"ext-simplexml": "Needed to support XML format in BodyParsingMiddleware",
|
||||
"ext-xml": "Needed to support XML format in BodyParsingMiddleware",
|
||||
"php-di/php-di": "PHP-DI is the recommended container library to be used with Slim",
|
||||
"slim/psr7": "Slim PSR-7 implementation. See https://www.slimframework.com/docs/v4/start/installation.html for more information."
|
||||
},
|
||||
"time": "2022-11-06T16:33:39+00:00",
|
||||
"type": "library",
|
||||
"installation-source": "dist",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Slim\\": "Slim"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Josh Lockhart",
|
||||
"email": "hello@joshlockhart.com",
|
||||
"homepage": "https://joshlockhart.com"
|
||||
},
|
||||
{
|
||||
"name": "Andrew Smith",
|
||||
"email": "a.smith@silentworks.co.uk",
|
||||
"homepage": "http://silentworks.co.uk"
|
||||
},
|
||||
{
|
||||
"name": "Rob Allen",
|
||||
"email": "rob@akrabat.com",
|
||||
"homepage": "http://akrabat.com"
|
||||
},
|
||||
{
|
||||
"name": "Pierre Berube",
|
||||
"email": "pierre@lgse.com",
|
||||
"homepage": "http://www.lgse.com"
|
||||
},
|
||||
{
|
||||
"name": "Gabriel Manricks",
|
||||
"email": "gmanricks@me.com",
|
||||
"homepage": "http://gabrielmanricks.com"
|
||||
}
|
||||
],
|
||||
"description": "Slim is a PHP micro framework that helps you quickly write simple yet powerful web applications and APIs",
|
||||
"homepage": "https://www.slimframework.com",
|
||||
"keywords": [
|
||||
"api",
|
||||
"framework",
|
||||
"micro",
|
||||
"router"
|
||||
],
|
||||
"support": {
|
||||
"docs": "https://www.slimframework.com/docs/v4/",
|
||||
"forum": "https://discourse.slimframework.com/",
|
||||
"irc": "irc://irc.freenode.net:6667/slimphp",
|
||||
"issues": "https://github.com/slimphp/Slim/issues",
|
||||
"rss": "https://www.slimframework.com/blog/feed.rss",
|
||||
"slack": "https://slimphp.slack.com/",
|
||||
"source": "https://github.com/slimphp/Slim",
|
||||
"wiki": "https://github.com/slimphp/Slim/wiki"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
"url": "https://opencollective.com/slimphp",
|
||||
"type": "open_collective"
|
||||
},
|
||||
{
|
||||
"url": "https://tidelift.com/funding/github/packagist/slim/slim",
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"install-path": "../slim/slim"
|
||||
},
|
||||
{
|
||||
"name": "symfony/polyfill-php80",
|
||||
"version": "v1.27.0",
|
||||
"version_normalized": "1.27.0.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/polyfill-php80.git",
|
||||
"reference": "7a6ff3f1959bb01aefccb463a0f2cd3d3d2fd936"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/7a6ff3f1959bb01aefccb463a0f2cd3d3d2fd936",
|
||||
"reference": "7a6ff3f1959bb01aefccb463a0f2cd3d3d2fd936",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=7.1"
|
||||
},
|
||||
"time": "2022-11-03T14:55:06+00:00",
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-main": "1.27-dev"
|
||||
},
|
||||
"thanks": {
|
||||
"name": "symfony/polyfill",
|
||||
"url": "https://github.com/symfony/polyfill"
|
||||
}
|
||||
},
|
||||
"installation-source": "dist",
|
||||
"autoload": {
|
||||
"files": [
|
||||
"bootstrap.php"
|
||||
],
|
||||
"psr-4": {
|
||||
"Symfony\\Polyfill\\Php80\\": ""
|
||||
},
|
||||
"classmap": [
|
||||
"Resources/stubs"
|
||||
]
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Ion Bazan",
|
||||
"email": "ion.bazan@gmail.com"
|
||||
},
|
||||
{
|
||||
"name": "Nicolas Grekas",
|
||||
"email": "p@tchwork.com"
|
||||
},
|
||||
{
|
||||
"name": "Symfony Community",
|
||||
"homepage": "https://symfony.com/contributors"
|
||||
}
|
||||
],
|
||||
"description": "Symfony polyfill backporting some PHP 8.0+ features to lower PHP versions",
|
||||
"homepage": "https://symfony.com",
|
||||
"keywords": [
|
||||
"compatibility",
|
||||
"polyfill",
|
||||
"portable",
|
||||
"shim"
|
||||
],
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/polyfill-php80/tree/v1.27.0"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
"url": "https://symfony.com/sponsor",
|
||||
"type": "custom"
|
||||
},
|
||||
{
|
||||
"url": "https://github.com/fabpot",
|
||||
"type": "github"
|
||||
},
|
||||
{
|
||||
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"install-path": "../symfony/polyfill-php80"
|
||||
}
|
||||
],
|
||||
"dev": true,
|
||||
"dev-package-names": []
|
||||
}
|
@ -0,0 +1,143 @@
|
||||
<?php return array(
|
||||
'root' => array(
|
||||
'name' => '__root__',
|
||||
'pretty_version' => 'dev-master',
|
||||
'version' => 'dev-master',
|
||||
'reference' => '73550d684ab153fd8b1ce7c401c5d6a122727130',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../../',
|
||||
'aliases' => array(),
|
||||
'dev' => true,
|
||||
),
|
||||
'versions' => array(
|
||||
'__root__' => array(
|
||||
'pretty_version' => 'dev-master',
|
||||
'version' => 'dev-master',
|
||||
'reference' => '73550d684ab153fd8b1ce7c401c5d6a122727130',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../../',
|
||||
'aliases' => array(),
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'fig/http-message-util' => array(
|
||||
'pretty_version' => '1.1.5',
|
||||
'version' => '1.1.5.0',
|
||||
'reference' => '9d94dc0154230ac39e5bf89398b324a86f63f765',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../fig/http-message-util',
|
||||
'aliases' => array(),
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'nikic/fast-route' => array(
|
||||
'pretty_version' => 'v1.3.0',
|
||||
'version' => '1.3.0.0',
|
||||
'reference' => '181d480e08d9476e61381e04a71b34dc0432e812',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../nikic/fast-route',
|
||||
'aliases' => array(),
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'psr/container' => array(
|
||||
'pretty_version' => '2.0.2',
|
||||
'version' => '2.0.2.0',
|
||||
'reference' => 'c71ecc56dfe541dbd90c5360474fbc405f8d5963',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../psr/container',
|
||||
'aliases' => array(),
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'psr/http-factory' => array(
|
||||
'pretty_version' => '1.0.1',
|
||||
'version' => '1.0.1.0',
|
||||
'reference' => '12ac7fcd07e5b077433f5f2bee95b3a771bf61be',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../psr/http-factory',
|
||||
'aliases' => array(),
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'psr/http-factory-implementation' => array(
|
||||
'dev_requirement' => false,
|
||||
'provided' => array(
|
||||
0 => '1.0',
|
||||
),
|
||||
),
|
||||
'psr/http-message' => array(
|
||||
'pretty_version' => '1.0.1',
|
||||
'version' => '1.0.1.0',
|
||||
'reference' => 'f6561bf28d520154e4b0ec72be95418abe6d9363',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../psr/http-message',
|
||||
'aliases' => array(),
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'psr/http-message-implementation' => array(
|
||||
'dev_requirement' => false,
|
||||
'provided' => array(
|
||||
0 => '1.0',
|
||||
),
|
||||
),
|
||||
'psr/http-server-handler' => array(
|
||||
'pretty_version' => '1.0.1',
|
||||
'version' => '1.0.1.0',
|
||||
'reference' => 'aff2f80e33b7f026ec96bb42f63242dc50ffcae7',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../psr/http-server-handler',
|
||||
'aliases' => array(),
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'psr/http-server-middleware' => array(
|
||||
'pretty_version' => '1.0.1',
|
||||
'version' => '1.0.1.0',
|
||||
'reference' => '2296f45510945530b9dceb8bcedb5cb84d40c5f5',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../psr/http-server-middleware',
|
||||
'aliases' => array(),
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'psr/log' => array(
|
||||
'pretty_version' => '3.0.0',
|
||||
'version' => '3.0.0.0',
|
||||
'reference' => 'fe5ea303b0887d5caefd3d431c3e61ad47037001',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../psr/log',
|
||||
'aliases' => array(),
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'ralouphie/getallheaders' => array(
|
||||
'pretty_version' => '3.0.3',
|
||||
'version' => '3.0.3.0',
|
||||
'reference' => '120b605dfeb996808c31b6477290a714d356e822',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../ralouphie/getallheaders',
|
||||
'aliases' => array(),
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'slim/psr7' => array(
|
||||
'pretty_version' => '1.6',
|
||||
'version' => '1.6.0.0',
|
||||
'reference' => '3471c22c1a0d26c51c78f6aeb06489d38cf46a4d',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../slim/psr7',
|
||||
'aliases' => array(),
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'slim/slim' => array(
|
||||
'pretty_version' => '4.11.0',
|
||||
'version' => '4.11.0.0',
|
||||
'reference' => 'b0f4ca393ea037be9ac7292ba7d0a34d18bac0c7',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../slim/slim',
|
||||
'aliases' => array(),
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'symfony/polyfill-php80' => array(
|
||||
'pretty_version' => 'v1.27.0',
|
||||
'version' => '1.27.0.0',
|
||||
'reference' => '7a6ff3f1959bb01aefccb463a0f2cd3d3d2fd936',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../symfony/polyfill-php80',
|
||||
'aliases' => array(),
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
),
|
||||
);
|
@ -0,0 +1,26 @@
|
||||
<?php
|
||||
|
||||
// platform_check.php @generated by Composer
|
||||
|
||||
$issues = array();
|
||||
|
||||
if (!(PHP_VERSION_ID >= 80000)) {
|
||||
$issues[] = 'Your Composer dependencies require a PHP version ">= 8.0.0". You are running ' . PHP_VERSION . '.';
|
||||
}
|
||||
|
||||
if ($issues) {
|
||||
if (!headers_sent()) {
|
||||
header('HTTP/1.1 500 Internal Server Error');
|
||||
}
|
||||
if (!ini_get('display_errors')) {
|
||||
if (PHP_SAPI === 'cli' || PHP_SAPI === 'phpdbg') {
|
||||
fwrite(STDERR, 'Composer detected issues in your platform:' . PHP_EOL.PHP_EOL . implode(PHP_EOL, $issues) . PHP_EOL.PHP_EOL);
|
||||
} elseif (!headers_sent()) {
|
||||
echo 'Composer detected issues in your platform:' . PHP_EOL.PHP_EOL . str_replace('You are running '.PHP_VERSION.'.', '', implode(PHP_EOL, $issues)) . PHP_EOL.PHP_EOL;
|
||||
}
|
||||
}
|
||||
trigger_error(
|
||||
'Composer detected issues in your platform: ' . implode(' ', $issues),
|
||||
E_USER_ERROR
|
||||
);
|
||||
}
|
@ -0,0 +1 @@
|
||||
vendor/
|
@ -0,0 +1,147 @@
|
||||
# Changelog
|
||||
|
||||
All notable changes to this project will be documented in this file, in reverse chronological order by release.
|
||||
|
||||
## 1.1.5 - 2020-11-24
|
||||
|
||||
### Added
|
||||
|
||||
- [#19](https://github.com/php-fig/http-message-util/pull/19) adds support for PHP 8.
|
||||
|
||||
### Changed
|
||||
|
||||
- Nothing.
|
||||
|
||||
### Deprecated
|
||||
|
||||
- Nothing.
|
||||
|
||||
### Removed
|
||||
|
||||
- Nothing.
|
||||
|
||||
### Fixed
|
||||
|
||||
- Nothing.
|
||||
|
||||
## 1.1.4 - 2020-02-05
|
||||
|
||||
### Added
|
||||
|
||||
- Nothing.
|
||||
|
||||
### Changed
|
||||
|
||||
- Nothing.
|
||||
|
||||
### Deprecated
|
||||
|
||||
- Nothing.
|
||||
|
||||
### Removed
|
||||
|
||||
- [#15](https://github.com/php-fig/http-message-util/pull/15) removes the dependency on psr/http-message, as it is not technically necessary for usage of this package.
|
||||
|
||||
### Fixed
|
||||
|
||||
- Nothing.
|
||||
|
||||
## 1.1.3 - 2018-11-19
|
||||
|
||||
### Added
|
||||
|
||||
- [#10](https://github.com/php-fig/http-message-util/pull/10) adds the constants `StatusCodeInterface::STATUS_EARLY_HINTS` (103) and
|
||||
`StatusCodeInterface::STATUS_TOO_EARLY` (425).
|
||||
|
||||
### Changed
|
||||
|
||||
- Nothing.
|
||||
|
||||
### Deprecated
|
||||
|
||||
- Nothing.
|
||||
|
||||
### Removed
|
||||
|
||||
- Nothing.
|
||||
|
||||
### Fixed
|
||||
|
||||
- Nothing.
|
||||
|
||||
## 1.1.2 - 2017-02-09
|
||||
|
||||
### Added
|
||||
|
||||
- [#4](https://github.com/php-fig/http-message-util/pull/4) adds the constant
|
||||
`StatusCodeInterface::STATUS_MISDIRECTED_REQUEST` (421).
|
||||
|
||||
### Deprecated
|
||||
|
||||
- Nothing.
|
||||
|
||||
### Removed
|
||||
|
||||
- Nothing.
|
||||
|
||||
### Fixed
|
||||
|
||||
- Nothing.
|
||||
|
||||
## 1.1.1 - 2017-02-06
|
||||
|
||||
### Added
|
||||
|
||||
- [#3](https://github.com/php-fig/http-message-util/pull/3) adds the constant
|
||||
`StatusCodeInterface::STATUS_IM_A_TEAPOT` (418).
|
||||
|
||||
### Deprecated
|
||||
|
||||
- Nothing.
|
||||
|
||||
### Removed
|
||||
|
||||
- Nothing.
|
||||
|
||||
### Fixed
|
||||
|
||||
- Nothing.
|
||||
|
||||
## 1.1.0 - 2016-09-19
|
||||
|
||||
### Added
|
||||
|
||||
- [#1](https://github.com/php-fig/http-message-util/pull/1) adds
|
||||
`Fig\Http\Message\StatusCodeInterface`, with constants named after common
|
||||
status reason phrases, with values indicating the status codes themselves.
|
||||
|
||||
### Deprecated
|
||||
|
||||
- Nothing.
|
||||
|
||||
### Removed
|
||||
|
||||
- Nothing.
|
||||
|
||||
### Fixed
|
||||
|
||||
- Nothing.
|
||||
|
||||
## 1.0.0 - 2017-08-05
|
||||
|
||||
### Added
|
||||
|
||||
- Adds `Fig\Http\Message\RequestMethodInterface`, with constants covering the
|
||||
most common HTTP request methods as specified by the IETF.
|
||||
|
||||
### Deprecated
|
||||
|
||||
- Nothing.
|
||||
|
||||
### Removed
|
||||
|
||||
- Nothing.
|
||||
|
||||
### Fixed
|
||||
|
||||
- Nothing.
|
@ -0,0 +1,19 @@
|
||||
Copyright (c) 2016 PHP Framework Interoperability Group
|
||||
|
||||
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.
|
@ -0,0 +1,17 @@
|
||||
# PSR Http Message Util
|
||||
|
||||
This repository holds utility classes and constants to facilitate common
|
||||
operations of [PSR-7](https://www.php-fig.org/psr/psr-7/); the primary purpose is
|
||||
to provide constants for referring to request methods, response status codes and
|
||||
messages, and potentially common headers.
|
||||
|
||||
Implementation of PSR-7 interfaces is **not** within the scope of this package.
|
||||
|
||||
## Installation
|
||||
|
||||
Install by adding the package as a [Composer](https://getcomposer.org)
|
||||
requirement:
|
||||
|
||||
```bash
|
||||
$ composer require fig/http-message-util
|
||||
```
|
@ -0,0 +1,28 @@
|
||||
{
|
||||
"name": "fig/http-message-util",
|
||||
"description": "Utility classes and constants for use with PSR-7 (psr/http-message)",
|
||||
"keywords": ["psr", "psr-7", "http", "http-message", "request", "response"],
|
||||
"license": "MIT",
|
||||
"authors": [
|
||||
{
|
||||
"name": "PHP-FIG",
|
||||
"homepage": "https://www.php-fig.org/"
|
||||
}
|
||||
],
|
||||
"require": {
|
||||
"php": "^5.3 || ^7.0 || ^8.0"
|
||||
},
|
||||
"suggest": {
|
||||
"psr/http-message": "The package containing the PSR-7 interfaces"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Fig\\Http\\Message\\": "src/"
|
||||
}
|
||||
},
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "1.1.x-dev"
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,34 @@
|
||||
<?php
|
||||
|
||||
namespace Fig\Http\Message;
|
||||
|
||||
/**
|
||||
* Defines constants for common HTTP request methods.
|
||||
*
|
||||
* Usage:
|
||||
*
|
||||
* <code>
|
||||
* class RequestFactory implements RequestMethodInterface
|
||||
* {
|
||||
* public static function factory(
|
||||
* $uri = '/',
|
||||
* $method = self::METHOD_GET,
|
||||
* $data = []
|
||||
* ) {
|
||||
* }
|
||||
* }
|
||||
* </code>
|
||||
*/
|
||||
interface RequestMethodInterface
|
||||
{
|
||||
const METHOD_HEAD = 'HEAD';
|
||||
const METHOD_GET = 'GET';
|
||||
const METHOD_POST = 'POST';
|
||||
const METHOD_PUT = 'PUT';
|
||||
const METHOD_PATCH = 'PATCH';
|
||||
const METHOD_DELETE = 'DELETE';
|
||||
const METHOD_PURGE = 'PURGE';
|
||||
const METHOD_OPTIONS = 'OPTIONS';
|
||||
const METHOD_TRACE = 'TRACE';
|
||||
const METHOD_CONNECT = 'CONNECT';
|
||||
}
|
@ -0,0 +1,107 @@
|
||||
<?php
|
||||
|
||||
namespace Fig\Http\Message;
|
||||
|
||||
/**
|
||||
* Defines constants for common HTTP status code.
|
||||
*
|
||||
* @see https://tools.ietf.org/html/rfc2295#section-8.1
|
||||
* @see https://tools.ietf.org/html/rfc2324#section-2.3
|
||||
* @see https://tools.ietf.org/html/rfc2518#section-9.7
|
||||
* @see https://tools.ietf.org/html/rfc2774#section-7
|
||||
* @see https://tools.ietf.org/html/rfc3229#section-10.4
|
||||
* @see https://tools.ietf.org/html/rfc4918#section-11
|
||||
* @see https://tools.ietf.org/html/rfc5842#section-7.1
|
||||
* @see https://tools.ietf.org/html/rfc5842#section-7.2
|
||||
* @see https://tools.ietf.org/html/rfc6585#section-3
|
||||
* @see https://tools.ietf.org/html/rfc6585#section-4
|
||||
* @see https://tools.ietf.org/html/rfc6585#section-5
|
||||
* @see https://tools.ietf.org/html/rfc6585#section-6
|
||||
* @see https://tools.ietf.org/html/rfc7231#section-6
|
||||
* @see https://tools.ietf.org/html/rfc7238#section-3
|
||||
* @see https://tools.ietf.org/html/rfc7725#section-3
|
||||
* @see https://tools.ietf.org/html/rfc7540#section-9.1.2
|
||||
* @see https://tools.ietf.org/html/rfc8297#section-2
|
||||
* @see https://tools.ietf.org/html/rfc8470#section-7
|
||||
* Usage:
|
||||
*
|
||||
* <code>
|
||||
* class ResponseFactory implements StatusCodeInterface
|
||||
* {
|
||||
* public function createResponse($code = self::STATUS_OK)
|
||||
* {
|
||||
* }
|
||||
* }
|
||||
* </code>
|
||||
*/
|
||||
interface StatusCodeInterface
|
||||
{
|
||||
// Informational 1xx
|
||||
const STATUS_CONTINUE = 100;
|
||||
const STATUS_SWITCHING_PROTOCOLS = 101;
|
||||
const STATUS_PROCESSING = 102;
|
||||
const STATUS_EARLY_HINTS = 103;
|
||||
// Successful 2xx
|
||||
const STATUS_OK = 200;
|
||||
const STATUS_CREATED = 201;
|
||||
const STATUS_ACCEPTED = 202;
|
||||
const STATUS_NON_AUTHORITATIVE_INFORMATION = 203;
|
||||
const STATUS_NO_CONTENT = 204;
|
||||
const STATUS_RESET_CONTENT = 205;
|
||||
const STATUS_PARTIAL_CONTENT = 206;
|
||||
const STATUS_MULTI_STATUS = 207;
|
||||
const STATUS_ALREADY_REPORTED = 208;
|
||||
const STATUS_IM_USED = 226;
|
||||
// Redirection 3xx
|
||||
const STATUS_MULTIPLE_CHOICES = 300;
|
||||
const STATUS_MOVED_PERMANENTLY = 301;
|
||||
const STATUS_FOUND = 302;
|
||||
const STATUS_SEE_OTHER = 303;
|
||||
const STATUS_NOT_MODIFIED = 304;
|
||||
const STATUS_USE_PROXY = 305;
|
||||
const STATUS_RESERVED = 306;
|
||||
const STATUS_TEMPORARY_REDIRECT = 307;
|
||||
const STATUS_PERMANENT_REDIRECT = 308;
|
||||
// Client Errors 4xx
|
||||
const STATUS_BAD_REQUEST = 400;
|
||||
const STATUS_UNAUTHORIZED = 401;
|
||||
const STATUS_PAYMENT_REQUIRED = 402;
|
||||
const STATUS_FORBIDDEN = 403;
|
||||
const STATUS_NOT_FOUND = 404;
|
||||
const STATUS_METHOD_NOT_ALLOWED = 405;
|
||||
const STATUS_NOT_ACCEPTABLE = 406;
|
||||
const STATUS_PROXY_AUTHENTICATION_REQUIRED = 407;
|
||||
const STATUS_REQUEST_TIMEOUT = 408;
|
||||
const STATUS_CONFLICT = 409;
|
||||
const STATUS_GONE = 410;
|
||||
const STATUS_LENGTH_REQUIRED = 411;
|
||||
const STATUS_PRECONDITION_FAILED = 412;
|
||||
const STATUS_PAYLOAD_TOO_LARGE = 413;
|
||||
const STATUS_URI_TOO_LONG = 414;
|
||||
const STATUS_UNSUPPORTED_MEDIA_TYPE = 415;
|
||||
const STATUS_RANGE_NOT_SATISFIABLE = 416;
|
||||
const STATUS_EXPECTATION_FAILED = 417;
|
||||
const STATUS_IM_A_TEAPOT = 418;
|
||||
const STATUS_MISDIRECTED_REQUEST = 421;
|
||||
const STATUS_UNPROCESSABLE_ENTITY = 422;
|
||||
const STATUS_LOCKED = 423;
|
||||
const STATUS_FAILED_DEPENDENCY = 424;
|
||||
const STATUS_TOO_EARLY = 425;
|
||||
const STATUS_UPGRADE_REQUIRED = 426;
|
||||
const STATUS_PRECONDITION_REQUIRED = 428;
|
||||
const STATUS_TOO_MANY_REQUESTS = 429;
|
||||
const STATUS_REQUEST_HEADER_FIELDS_TOO_LARGE = 431;
|
||||
const STATUS_UNAVAILABLE_FOR_LEGAL_REASONS = 451;
|
||||
// Server Errors 5xx
|
||||
const STATUS_INTERNAL_SERVER_ERROR = 500;
|
||||
const STATUS_NOT_IMPLEMENTED = 501;
|
||||
const STATUS_BAD_GATEWAY = 502;
|
||||
const STATUS_SERVICE_UNAVAILABLE = 503;
|
||||
const STATUS_GATEWAY_TIMEOUT = 504;
|
||||
const STATUS_VERSION_NOT_SUPPORTED = 505;
|
||||
const STATUS_VARIANT_ALSO_NEGOTIATES = 506;
|
||||
const STATUS_INSUFFICIENT_STORAGE = 507;
|
||||
const STATUS_LOOP_DETECTED = 508;
|
||||
const STATUS_NOT_EXTENDED = 510;
|
||||
const STATUS_NETWORK_AUTHENTICATION_REQUIRED = 511;
|
||||
}
|
@ -0,0 +1,5 @@
|
||||
/vendor/
|
||||
.idea/
|
||||
|
||||
# ignore lock file since we have no extra dependencies
|
||||
composer.lock
|
@ -0,0 +1 @@
|
||||
assume_php=false
|
@ -0,0 +1,20 @@
|
||||
sudo: false
|
||||
language: php
|
||||
|
||||
php:
|
||||
- 5.4
|
||||
- 5.5
|
||||
- 5.6
|
||||
- 7.0
|
||||
- 7.1
|
||||
- 7.2
|
||||
- hhvm
|
||||
|
||||
script:
|
||||
- ./vendor/bin/phpunit
|
||||
|
||||
before_install:
|
||||
- travis_retry composer self-update
|
||||
|
||||
install:
|
||||
- composer install
|
@ -0,0 +1,126 @@
|
||||
<?hh // decl
|
||||
|
||||
namespace FastRoute {
|
||||
class BadRouteException extends \LogicException {
|
||||
}
|
||||
|
||||
interface RouteParser {
|
||||
public function parse(string $route): array<array>;
|
||||
}
|
||||
|
||||
class RouteCollector {
|
||||
public function __construct(RouteParser $routeParser, DataGenerator $dataGenerator);
|
||||
public function addRoute(mixed $httpMethod, string $route, mixed $handler): void;
|
||||
public function getData(): array;
|
||||
}
|
||||
|
||||
class Route {
|
||||
public function __construct(string $httpMethod, mixed $handler, string $regex, array $variables);
|
||||
public function matches(string $str): bool;
|
||||
}
|
||||
|
||||
interface DataGenerator {
|
||||
public function addRoute(string $httpMethod, array $routeData, mixed $handler);
|
||||
public function getData(): array;
|
||||
}
|
||||
|
||||
interface Dispatcher {
|
||||
const int NOT_FOUND = 0;
|
||||
const int FOUND = 1;
|
||||
const int METHOD_NOT_ALLOWED = 2;
|
||||
public function dispatch(string $httpMethod, string $uri): array;
|
||||
}
|
||||
|
||||
function simpleDispatcher(
|
||||
(function(RouteCollector): void) $routeDefinitionCallback,
|
||||
shape(
|
||||
?'routeParser' => classname<RouteParser>,
|
||||
?'dataGenerator' => classname<DataGenerator>,
|
||||
?'dispatcher' => classname<Dispatcher>,
|
||||
?'routeCollector' => classname<RouteCollector>,
|
||||
) $options = shape()): Dispatcher;
|
||||
|
||||
function cachedDispatcher(
|
||||
(function(RouteCollector): void) $routeDefinitionCallback,
|
||||
shape(
|
||||
?'routeParser' => classname<RouteParser>,
|
||||
?'dataGenerator' => classname<DataGenerator>,
|
||||
?'dispatcher' => classname<Dispatcher>,
|
||||
?'routeCollector' => classname<RouteCollector>,
|
||||
?'cacheDisabled' => bool,
|
||||
?'cacheFile' => string,
|
||||
) $options = shape()): Dispatcher;
|
||||
}
|
||||
|
||||
namespace FastRoute\DataGenerator {
|
||||
abstract class RegexBasedAbstract implements \FastRoute\DataGenerator {
|
||||
protected abstract function getApproxChunkSize();
|
||||
protected abstract function processChunk($regexToRoutesMap);
|
||||
|
||||
public function addRoute(string $httpMethod, array $routeData, mixed $handler): void;
|
||||
public function getData(): array;
|
||||
}
|
||||
|
||||
class CharCountBased extends RegexBasedAbstract {
|
||||
protected function getApproxChunkSize(): int;
|
||||
protected function processChunk(array<string, string> $regexToRoutesMap): array<string, mixed>;
|
||||
}
|
||||
|
||||
class GroupCountBased extends RegexBasedAbstract {
|
||||
protected function getApproxChunkSize(): int;
|
||||
protected function processChunk(array<string, string> $regexToRoutesMap): array<string, mixed>;
|
||||
}
|
||||
|
||||
class GroupPosBased extends RegexBasedAbstract {
|
||||
protected function getApproxChunkSize(): int;
|
||||
protected function processChunk(array<string, string> $regexToRoutesMap): array<string, mixed>;
|
||||
}
|
||||
|
||||
class MarkBased extends RegexBasedAbstract {
|
||||
protected function getApproxChunkSize(): int;
|
||||
protected function processChunk(array<string, string> $regexToRoutesMap): array<string, mixed>;
|
||||
}
|
||||
}
|
||||
|
||||
namespace FastRoute\Dispatcher {
|
||||
abstract class RegexBasedAbstract implements \FastRoute\Dispatcher {
|
||||
protected abstract function dispatchVariableRoute(array<array> $routeData, string $uri): array;
|
||||
|
||||
public function dispatch(string $httpMethod, string $uri): array;
|
||||
}
|
||||
|
||||
class GroupPosBased extends RegexBasedAbstract {
|
||||
public function __construct(array $data);
|
||||
protected function dispatchVariableRoute(array<array> $routeData, string $uri): array;
|
||||
}
|
||||
|
||||
class GroupCountBased extends RegexBasedAbstract {
|
||||
public function __construct(array $data);
|
||||
protected function dispatchVariableRoute(array<array> $routeData, string $uri): array;
|
||||
}
|
||||
|
||||
class CharCountBased extends RegexBasedAbstract {
|
||||
public function __construct(array $data);
|
||||
protected function dispatchVariableRoute(array<array> $routeData, string $uri): array;
|
||||
}
|
||||
|
||||
class MarkBased extends RegexBasedAbstract {
|
||||
public function __construct(array $data);
|
||||
protected function dispatchVariableRoute(array<array> $routeData, string $uri): array;
|
||||
}
|
||||
}
|
||||
|
||||
namespace FastRoute\RouteParser {
|
||||
class Std implements \FastRoute\RouteParser {
|
||||
const string VARIABLE_REGEX = <<<'REGEX'
|
||||
\{
|
||||
\s* ([a-zA-Z][a-zA-Z0-9_]*) \s*
|
||||
(?:
|
||||
: \s* ([^{}]*(?:\{(?-1)\}[^{}]*)*)
|
||||
)?
|
||||
\}
|
||||
REGEX;
|
||||
const string DEFAULT_DISPATCH_REGEX = '[^/]+';
|
||||
public function parse(string $route): array<array>;
|
||||
}
|
||||
}
|
@ -0,0 +1,31 @@
|
||||
Copyright (c) 2013 by Nikita Popov.
|
||||
|
||||
Some rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above
|
||||
copyright notice, this list of conditions and the following
|
||||
disclaimer in the documentation and/or other materials provided
|
||||
with the distribution.
|
||||
|
||||
* The names of the contributors may not be used to endorse or
|
||||
promote products derived from this software without specific
|
||||
prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
@ -0,0 +1,313 @@
|
||||
FastRoute - Fast request router for PHP
|
||||
=======================================
|
||||
|
||||
This library provides a fast implementation of a regular expression based router. [Blog post explaining how the
|
||||
implementation works and why it is fast.][blog_post]
|
||||
|
||||
Install
|
||||
-------
|
||||
|
||||
To install with composer:
|
||||
|
||||
```sh
|
||||
composer require nikic/fast-route
|
||||
```
|
||||
|
||||
Requires PHP 5.4 or newer.
|
||||
|
||||
Usage
|
||||
-----
|
||||
|
||||
Here's a basic usage example:
|
||||
|
||||
```php
|
||||
<?php
|
||||
|
||||
require '/path/to/vendor/autoload.php';
|
||||
|
||||
$dispatcher = FastRoute\simpleDispatcher(function(FastRoute\RouteCollector $r) {
|
||||
$r->addRoute('GET', '/users', 'get_all_users_handler');
|
||||
// {id} must be a number (\d+)
|
||||
$r->addRoute('GET', '/user/{id:\d+}', 'get_user_handler');
|
||||
// The /{title} suffix is optional
|
||||
$r->addRoute('GET', '/articles/{id:\d+}[/{title}]', 'get_article_handler');
|
||||
});
|
||||
|
||||
// Fetch method and URI from somewhere
|
||||
$httpMethod = $_SERVER['REQUEST_METHOD'];
|
||||
$uri = $_SERVER['REQUEST_URI'];
|
||||
|
||||
// Strip query string (?foo=bar) and decode URI
|
||||
if (false !== $pos = strpos($uri, '?')) {
|
||||
$uri = substr($uri, 0, $pos);
|
||||
}
|
||||
$uri = rawurldecode($uri);
|
||||
|
||||
$routeInfo = $dispatcher->dispatch($httpMethod, $uri);
|
||||
switch ($routeInfo[0]) {
|
||||
case FastRoute\Dispatcher::NOT_FOUND:
|
||||
// ... 404 Not Found
|
||||
break;
|
||||
case FastRoute\Dispatcher::METHOD_NOT_ALLOWED:
|
||||
$allowedMethods = $routeInfo[1];
|
||||
// ... 405 Method Not Allowed
|
||||
break;
|
||||
case FastRoute\Dispatcher::FOUND:
|
||||
$handler = $routeInfo[1];
|
||||
$vars = $routeInfo[2];
|
||||
// ... call $handler with $vars
|
||||
break;
|
||||
}
|
||||
```
|
||||
|
||||
### Defining routes
|
||||
|
||||
The routes are defined by calling the `FastRoute\simpleDispatcher()` function, which accepts
|
||||
a callable taking a `FastRoute\RouteCollector` instance. The routes are added by calling
|
||||
`addRoute()` on the collector instance:
|
||||
|
||||
```php
|
||||
$r->addRoute($method, $routePattern, $handler);
|
||||
```
|
||||
|
||||
The `$method` is an uppercase HTTP method string for which a certain route should match. It
|
||||
is possible to specify multiple valid methods using an array:
|
||||
|
||||
```php
|
||||
// These two calls
|
||||
$r->addRoute('GET', '/test', 'handler');
|
||||
$r->addRoute('POST', '/test', 'handler');
|
||||
// Are equivalent to this one call
|
||||
$r->addRoute(['GET', 'POST'], '/test', 'handler');
|
||||
```
|
||||
|
||||
By default the `$routePattern` uses a syntax where `{foo}` specifies a placeholder with name `foo`
|
||||
and matching the regex `[^/]+`. To adjust the pattern the placeholder matches, you can specify
|
||||
a custom pattern by writing `{bar:[0-9]+}`. Some examples:
|
||||
|
||||
```php
|
||||
// Matches /user/42, but not /user/xyz
|
||||
$r->addRoute('GET', '/user/{id:\d+}', 'handler');
|
||||
|
||||
// Matches /user/foobar, but not /user/foo/bar
|
||||
$r->addRoute('GET', '/user/{name}', 'handler');
|
||||
|
||||
// Matches /user/foo/bar as well
|
||||
$r->addRoute('GET', '/user/{name:.+}', 'handler');
|
||||
```
|
||||
|
||||
Custom patterns for route placeholders cannot use capturing groups. For example `{lang:(en|de)}`
|
||||
is not a valid placeholder, because `()` is a capturing group. Instead you can use either
|
||||
`{lang:en|de}` or `{lang:(?:en|de)}`.
|
||||
|
||||
Furthermore parts of the route enclosed in `[...]` are considered optional, so that `/foo[bar]`
|
||||
will match both `/foo` and `/foobar`. Optional parts are only supported in a trailing position,
|
||||
not in the middle of a route.
|
||||
|
||||
```php
|
||||
// This route
|
||||
$r->addRoute('GET', '/user/{id:\d+}[/{name}]', 'handler');
|
||||
// Is equivalent to these two routes
|
||||
$r->addRoute('GET', '/user/{id:\d+}', 'handler');
|
||||
$r->addRoute('GET', '/user/{id:\d+}/{name}', 'handler');
|
||||
|
||||
// Multiple nested optional parts are possible as well
|
||||
$r->addRoute('GET', '/user[/{id:\d+}[/{name}]]', 'handler');
|
||||
|
||||
// This route is NOT valid, because optional parts can only occur at the end
|
||||
$r->addRoute('GET', '/user[/{id:\d+}]/{name}', 'handler');
|
||||
```
|
||||
|
||||
The `$handler` parameter does not necessarily have to be a callback, it could also be a controller
|
||||
class name or any other kind of data you wish to associate with the route. FastRoute only tells you
|
||||
which handler corresponds to your URI, how you interpret it is up to you.
|
||||
|
||||
#### Shorcut methods for common request methods
|
||||
|
||||
For the `GET`, `POST`, `PUT`, `PATCH`, `DELETE` and `HEAD` request methods shortcut methods are available. For example:
|
||||
|
||||
```php
|
||||
$r->get('/get-route', 'get_handler');
|
||||
$r->post('/post-route', 'post_handler');
|
||||
```
|
||||
|
||||
Is equivalent to:
|
||||
|
||||
```php
|
||||
$r->addRoute('GET', '/get-route', 'get_handler');
|
||||
$r->addRoute('POST', '/post-route', 'post_handler');
|
||||
```
|
||||
|
||||
#### Route Groups
|
||||
|
||||
Additionally, you can specify routes inside of a group. All routes defined inside a group will have a common prefix.
|
||||
|
||||
For example, defining your routes as:
|
||||
|
||||
```php
|
||||
$r->addGroup('/admin', function (RouteCollector $r) {
|
||||
$r->addRoute('GET', '/do-something', 'handler');
|
||||
$r->addRoute('GET', '/do-another-thing', 'handler');
|
||||
$r->addRoute('GET', '/do-something-else', 'handler');
|
||||
});
|
||||
```
|
||||
|
||||
Will have the same result as:
|
||||
|
||||
```php
|
||||
$r->addRoute('GET', '/admin/do-something', 'handler');
|
||||
$r->addRoute('GET', '/admin/do-another-thing', 'handler');
|
||||
$r->addRoute('GET', '/admin/do-something-else', 'handler');
|
||||
```
|
||||
|
||||
Nested groups are also supported, in which case the prefixes of all the nested groups are combined.
|
||||
|
||||
### Caching
|
||||
|
||||
The reason `simpleDispatcher` accepts a callback for defining the routes is to allow seamless
|
||||
caching. By using `cachedDispatcher` instead of `simpleDispatcher` you can cache the generated
|
||||
routing data and construct the dispatcher from the cached information:
|
||||
|
||||
```php
|
||||
<?php
|
||||
|
||||
$dispatcher = FastRoute\cachedDispatcher(function(FastRoute\RouteCollector $r) {
|
||||
$r->addRoute('GET', '/user/{name}/{id:[0-9]+}', 'handler0');
|
||||
$r->addRoute('GET', '/user/{id:[0-9]+}', 'handler1');
|
||||
$r->addRoute('GET', '/user/{name}', 'handler2');
|
||||
}, [
|
||||
'cacheFile' => __DIR__ . '/route.cache', /* required */
|
||||
'cacheDisabled' => IS_DEBUG_ENABLED, /* optional, enabled by default */
|
||||
]);
|
||||
```
|
||||
|
||||
The second parameter to the function is an options array, which can be used to specify the cache
|
||||
file location, among other things.
|
||||
|
||||
### Dispatching a URI
|
||||
|
||||
A URI is dispatched by calling the `dispatch()` method of the created dispatcher. This method
|
||||
accepts the HTTP method and a URI. Getting those two bits of information (and normalizing them
|
||||
appropriately) is your job - this library is not bound to the PHP web SAPIs.
|
||||
|
||||
The `dispatch()` method returns an array whose first element contains a status code. It is one
|
||||
of `Dispatcher::NOT_FOUND`, `Dispatcher::METHOD_NOT_ALLOWED` and `Dispatcher::FOUND`. For the
|
||||
method not allowed status the second array element contains a list of HTTP methods allowed for
|
||||
the supplied URI. For example:
|
||||
|
||||
[FastRoute\Dispatcher::METHOD_NOT_ALLOWED, ['GET', 'POST']]
|
||||
|
||||
> **NOTE:** The HTTP specification requires that a `405 Method Not Allowed` response include the
|
||||
`Allow:` header to detail available methods for the requested resource. Applications using FastRoute
|
||||
should use the second array element to add this header when relaying a 405 response.
|
||||
|
||||
For the found status the second array element is the handler that was associated with the route
|
||||
and the third array element is a dictionary of placeholder names to their values. For example:
|
||||
|
||||
/* Routing against GET /user/nikic/42 */
|
||||
|
||||
[FastRoute\Dispatcher::FOUND, 'handler0', ['name' => 'nikic', 'id' => '42']]
|
||||
|
||||
### Overriding the route parser and dispatcher
|
||||
|
||||
The routing process makes use of three components: A route parser, a data generator and a
|
||||
dispatcher. The three components adhere to the following interfaces:
|
||||
|
||||
```php
|
||||
<?php
|
||||
|
||||
namespace FastRoute;
|
||||
|
||||
interface RouteParser {
|
||||
public function parse($route);
|
||||
}
|
||||
|
||||
interface DataGenerator {
|
||||
public function addRoute($httpMethod, $routeData, $handler);
|
||||
public function getData();
|
||||
}
|
||||
|
||||
interface Dispatcher {
|
||||
const NOT_FOUND = 0, FOUND = 1, METHOD_NOT_ALLOWED = 2;
|
||||
|
||||
public function dispatch($httpMethod, $uri);
|
||||
}
|
||||
```
|
||||
|
||||
The route parser takes a route pattern string and converts it into an array of route infos, where
|
||||
each route info is again an array of it's parts. The structure is best understood using an example:
|
||||
|
||||
/* The route /user/{id:\d+}[/{name}] converts to the following array: */
|
||||
[
|
||||
[
|
||||
'/user/',
|
||||
['id', '\d+'],
|
||||
],
|
||||
[
|
||||
'/user/',
|
||||
['id', '\d+'],
|
||||
'/',
|
||||
['name', '[^/]+'],
|
||||
],
|
||||
]
|
||||
|
||||
This array can then be passed to the `addRoute()` method of a data generator. After all routes have
|
||||
been added the `getData()` of the generator is invoked, which returns all the routing data required
|
||||
by the dispatcher. The format of this data is not further specified - it is tightly coupled to
|
||||
the corresponding dispatcher.
|
||||
|
||||
The dispatcher accepts the routing data via a constructor and provides a `dispatch()` method, which
|
||||
you're already familiar with.
|
||||
|
||||
The route parser can be overwritten individually (to make use of some different pattern syntax),
|
||||
however the data generator and dispatcher should always be changed as a pair, as the output from
|
||||
the former is tightly coupled to the input of the latter. The reason the generator and the
|
||||
dispatcher are separate is that only the latter is needed when using caching (as the output of
|
||||
the former is what is being cached.)
|
||||
|
||||
When using the `simpleDispatcher` / `cachedDispatcher` functions from above the override happens
|
||||
through the options array:
|
||||
|
||||
```php
|
||||
<?php
|
||||
|
||||
$dispatcher = FastRoute\simpleDispatcher(function(FastRoute\RouteCollector $r) {
|
||||
/* ... */
|
||||
}, [
|
||||
'routeParser' => 'FastRoute\\RouteParser\\Std',
|
||||
'dataGenerator' => 'FastRoute\\DataGenerator\\GroupCountBased',
|
||||
'dispatcher' => 'FastRoute\\Dispatcher\\GroupCountBased',
|
||||
]);
|
||||
```
|
||||
|
||||
The above options array corresponds to the defaults. By replacing `GroupCountBased` by
|
||||
`GroupPosBased` you could switch to a different dispatching strategy.
|
||||
|
||||
### A Note on HEAD Requests
|
||||
|
||||
The HTTP spec requires servers to [support both GET and HEAD methods][2616-511]:
|
||||
|
||||
> The methods GET and HEAD MUST be supported by all general-purpose servers
|
||||
|
||||
To avoid forcing users to manually register HEAD routes for each resource we fallback to matching an
|
||||
available GET route for a given resource. The PHP web SAPI transparently removes the entity body
|
||||
from HEAD responses so this behavior has no effect on the vast majority of users.
|
||||
|
||||
However, implementers using FastRoute outside the web SAPI environment (e.g. a custom server) MUST
|
||||
NOT send entity bodies generated in response to HEAD requests. If you are a non-SAPI user this is
|
||||
*your responsibility*; FastRoute has no purview to prevent you from breaking HTTP in such cases.
|
||||
|
||||
Finally, note that applications MAY always specify their own HEAD method route for a given
|
||||
resource to bypass this behavior entirely.
|
||||
|
||||
### Credits
|
||||
|
||||
This library is based on a router that [Levi Morrison][levi] implemented for the Aerys server.
|
||||
|
||||
A large number of tests, as well as HTTP compliance considerations, were provided by [Daniel Lowrey][rdlowrey].
|
||||
|
||||
|
||||
[2616-511]: http://www.w3.org/Protocols/rfc2616/rfc2616-sec5.html#sec5.1.1 "RFC 2616 Section 5.1.1"
|
||||
[blog_post]: http://nikic.github.io/2014/02/18/Fast-request-routing-using-regular-expressions.html
|
||||
[levi]: https://github.com/morrisonlevi
|
||||
[rdlowrey]: https://github.com/rdlowrey
|
@ -0,0 +1,24 @@
|
||||
{
|
||||
"name": "nikic/fast-route",
|
||||
"description": "Fast request router for PHP",
|
||||
"keywords": ["routing", "router"],
|
||||
"license": "BSD-3-Clause",
|
||||
"authors": [
|
||||
{
|
||||
"name": "Nikita Popov",
|
||||
"email": "nikic@php.net"
|
||||
}
|
||||
],
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"FastRoute\\": "src/"
|
||||
},
|
||||
"files": ["src/functions.php"]
|
||||
},
|
||||
"require": {
|
||||
"php": ">=5.4.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "^4.8.35|~5.7"
|
||||
}
|
||||
}
|
@ -0,0 +1,24 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<phpunit backupGlobals="false"
|
||||
backupStaticAttributes="false"
|
||||
colors="true"
|
||||
convertErrorsToExceptions="true"
|
||||
convertNoticesToExceptions="true"
|
||||
convertWarningsToExceptions="true"
|
||||
processIsolation="false"
|
||||
syntaxCheck="false"
|
||||
bootstrap="test/bootstrap.php"
|
||||
>
|
||||
<testsuites>
|
||||
<testsuite name="FastRoute Tests">
|
||||
<directory>./test/</directory>
|
||||
</testsuite>
|
||||
</testsuites>
|
||||
|
||||
<filter>
|
||||
<whitelist>
|
||||
<directory>./src/</directory>
|
||||
</whitelist>
|
||||
</filter>
|
||||
</phpunit>
|
@ -0,0 +1,28 @@
|
||||
<?xml version="1.0"?>
|
||||
<psalm
|
||||
name="Example Psalm config with recommended defaults"
|
||||
stopOnFirstError="false"
|
||||
useDocblockTypes="true"
|
||||
totallyTyped="false"
|
||||
requireVoidReturnType="false"
|
||||
>
|
||||
<projectFiles>
|
||||
<directory name="src" />
|
||||
</projectFiles>
|
||||
|
||||
<issueHandlers>
|
||||
<LessSpecificReturnType errorLevel="info" />
|
||||
|
||||
<!-- level 3 issues - slightly lazy code writing, but provably low false-negatives -->
|
||||
<DeprecatedMethod errorLevel="info" />
|
||||
|
||||
<MissingClosureReturnType errorLevel="info" />
|
||||
<MissingReturnType errorLevel="info" />
|
||||
<MissingPropertyType errorLevel="info" />
|
||||
<InvalidDocblock errorLevel="info" />
|
||||
<MisplacedRequiredParam errorLevel="info" />
|
||||
|
||||
<PropertyNotSetInConstructor errorLevel="info" />
|
||||
<MissingConstructor errorLevel="info" />
|
||||
</issueHandlers>
|
||||
</psalm>
|
@ -0,0 +1,7 @@
|
||||
<?php
|
||||
|
||||
namespace FastRoute;
|
||||
|
||||
class BadRouteException extends \LogicException
|
||||
{
|
||||
}
|
@ -0,0 +1,26 @@
|
||||
<?php
|
||||
|
||||
namespace FastRoute;
|
||||
|
||||
interface DataGenerator
|
||||
{
|
||||
/**
|
||||
* Adds a route to the data generator. The route data uses the
|
||||
* same format that is returned by RouterParser::parser().
|
||||
*
|
||||
* The handler doesn't necessarily need to be a callable, it
|
||||
* can be arbitrary data that will be returned when the route
|
||||
* matches.
|
||||
*
|
||||
* @param string $httpMethod
|
||||
* @param array $routeData
|
||||
* @param mixed $handler
|
||||
*/
|
||||
public function addRoute($httpMethod, $routeData, $handler);
|
||||
|
||||
/**
|
||||
* Returns dispatcher data in some unspecified format, which
|
||||
* depends on the used method of dispatch.
|
||||
*/
|
||||
public function getData();
|
||||
}
|
@ -0,0 +1,31 @@
|
||||
<?php
|
||||
|
||||
namespace FastRoute\DataGenerator;
|
||||
|
||||
class CharCountBased extends RegexBasedAbstract
|
||||
{
|
||||
protected function getApproxChunkSize()
|
||||
{
|
||||
return 30;
|
||||
}
|
||||
|
||||
protected function processChunk($regexToRoutesMap)
|
||||
{
|
||||
$routeMap = [];
|
||||
$regexes = [];
|
||||
|
||||
$suffixLen = 0;
|
||||
$suffix = '';
|
||||
$count = count($regexToRoutesMap);
|
||||
foreach ($regexToRoutesMap as $regex => $route) {
|
||||
$suffixLen++;
|
||||
$suffix .= "\t";
|
||||
|
||||
$regexes[] = '(?:' . $regex . '/(\t{' . $suffixLen . '})\t{' . ($count - $suffixLen) . '})';
|
||||
$routeMap[$suffix] = [$route->handler, $route->variables];
|
||||
}
|
||||
|
||||
$regex = '~^(?|' . implode('|', $regexes) . ')$~';
|
||||
return ['regex' => $regex, 'suffix' => '/' . $suffix, 'routeMap' => $routeMap];
|
||||
}
|
||||
}
|
@ -0,0 +1,30 @@
|
||||
<?php
|
||||
|
||||
namespace FastRoute\DataGenerator;
|
||||
|
||||
class GroupCountBased extends RegexBasedAbstract
|
||||
{
|
||||
protected function getApproxChunkSize()
|
||||
{
|
||||
return 10;
|
||||
}
|
||||
|
||||
protected function processChunk($regexToRoutesMap)
|
||||
{
|
||||
$routeMap = [];
|
||||
$regexes = [];
|
||||
$numGroups = 0;
|
||||
foreach ($regexToRoutesMap as $regex => $route) {
|
||||
$numVariables = count($route->variables);
|
||||
$numGroups = max($numGroups, $numVariables);
|
||||
|
||||
$regexes[] = $regex . str_repeat('()', $numGroups - $numVariables);
|
||||
$routeMap[$numGroups + 1] = [$route->handler, $route->variables];
|
||||
|
||||
++$numGroups;
|
||||
}
|
||||
|
||||
$regex = '~^(?|' . implode('|', $regexes) . ')$~';
|
||||
return ['regex' => $regex, 'routeMap' => $routeMap];
|
||||
}
|
||||
}
|
@ -0,0 +1,27 @@
|
||||
<?php
|
||||
|
||||
namespace FastRoute\DataGenerator;
|
||||
|
||||
class GroupPosBased extends RegexBasedAbstract
|
||||
{
|
||||
protected function getApproxChunkSize()
|
||||
{
|
||||
return 10;
|
||||
}
|
||||
|
||||
protected function processChunk($regexToRoutesMap)
|
||||
{
|
||||
$routeMap = [];
|
||||
$regexes = [];
|
||||
$offset = 1;
|
||||
foreach ($regexToRoutesMap as $regex => $route) {
|
||||
$regexes[] = $regex;
|
||||
$routeMap[$offset] = [$route->handler, $route->variables];
|
||||
|
||||
$offset += count($route->variables);
|
||||
}
|
||||
|
||||
$regex = '~^(?:' . implode('|', $regexes) . ')$~';
|
||||
return ['regex' => $regex, 'routeMap' => $routeMap];
|
||||
}
|
||||
}
|
@ -0,0 +1,27 @@
|
||||
<?php
|
||||
|
||||
namespace FastRoute\DataGenerator;
|
||||
|
||||
class MarkBased extends RegexBasedAbstract
|
||||
{
|
||||
protected function getApproxChunkSize()
|
||||
{
|
||||
return 30;
|
||||
}
|
||||
|
||||
protected function processChunk($regexToRoutesMap)
|
||||
{
|
||||
$routeMap = [];
|
||||
$regexes = [];
|
||||
$markName = 'a';
|
||||
foreach ($regexToRoutesMap as $regex => $route) {
|
||||
$regexes[] = $regex . '(*MARK:' . $markName . ')';
|
||||
$routeMap[$markName] = [$route->handler, $route->variables];
|
||||
|
||||
++$markName;
|
||||
}
|
||||
|
||||
$regex = '~^(?|' . implode('|', $regexes) . ')$~';
|
||||
return ['regex' => $regex, 'routeMap' => $routeMap];
|
||||
}
|
||||
}
|
@ -0,0 +1,186 @@
|
||||
<?php
|
||||
|
||||
namespace FastRoute\DataGenerator;
|
||||
|
||||
use FastRoute\BadRouteException;
|
||||
use FastRoute\DataGenerator;
|
||||
use FastRoute\Route;
|
||||
|
||||
abstract class RegexBasedAbstract implements DataGenerator
|
||||
{
|
||||
/** @var mixed[][] */
|
||||
protected $staticRoutes = [];
|
||||
|
||||
/** @var Route[][] */
|
||||
protected $methodToRegexToRoutesMap = [];
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
abstract protected function getApproxChunkSize();
|
||||
|
||||
/**
|
||||
* @return mixed[]
|
||||
*/
|
||||
abstract protected function processChunk($regexToRoutesMap);
|
||||
|
||||
public function addRoute($httpMethod, $routeData, $handler)
|
||||
{
|
||||
if ($this->isStaticRoute($routeData)) {
|
||||
$this->addStaticRoute($httpMethod, $routeData, $handler);
|
||||
} else {
|
||||
$this->addVariableRoute($httpMethod, $routeData, $handler);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed[]
|
||||
*/
|
||||
public function getData()
|
||||
{
|
||||
if (empty($this->methodToRegexToRoutesMap)) {
|
||||
return [$this->staticRoutes, []];
|
||||
}
|
||||
|
||||
return [$this->staticRoutes, $this->generateVariableRouteData()];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed[]
|
||||
*/
|
||||
private function generateVariableRouteData()
|
||||
{
|
||||
$data = [];
|
||||
foreach ($this->methodToRegexToRoutesMap as $method => $regexToRoutesMap) {
|
||||
$chunkSize = $this->computeChunkSize(count($regexToRoutesMap));
|
||||
$chunks = array_chunk($regexToRoutesMap, $chunkSize, true);
|
||||
$data[$method] = array_map([$this, 'processChunk'], $chunks);
|
||||
}
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int
|
||||
* @return int
|
||||
*/
|
||||
private function computeChunkSize($count)
|
||||
{
|
||||
$numParts = max(1, round($count / $this->getApproxChunkSize()));
|
||||
return (int) ceil($count / $numParts);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed[]
|
||||
* @return bool
|
||||
*/
|
||||
private function isStaticRoute($routeData)
|
||||
{
|
||||
return count($routeData) === 1 && is_string($routeData[0]);
|
||||
}
|
||||
|
||||
private function addStaticRoute($httpMethod, $routeData, $handler)
|
||||
{
|
||||
$routeStr = $routeData[0];
|
||||
|
||||
if (isset($this->staticRoutes[$httpMethod][$routeStr])) {
|
||||
throw new BadRouteException(sprintf(
|
||||
'Cannot register two routes matching "%s" for method "%s"',
|
||||
$routeStr, $httpMethod
|
||||
));
|
||||
}
|
||||
|
||||
if (isset($this->methodToRegexToRoutesMap[$httpMethod])) {
|
||||
foreach ($this->methodToRegexToRoutesMap[$httpMethod] as $route) {
|
||||
if ($route->matches($routeStr)) {
|
||||
throw new BadRouteException(sprintf(
|
||||
'Static route "%s" is shadowed by previously defined variable route "%s" for method "%s"',
|
||||
$routeStr, $route->regex, $httpMethod
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$this->staticRoutes[$httpMethod][$routeStr] = $handler;
|
||||
}
|
||||
|
||||
private function addVariableRoute($httpMethod, $routeData, $handler)
|
||||
{
|
||||
list($regex, $variables) = $this->buildRegexForRoute($routeData);
|
||||
|
||||
if (isset($this->methodToRegexToRoutesMap[$httpMethod][$regex])) {
|
||||
throw new BadRouteException(sprintf(
|
||||
'Cannot register two routes matching "%s" for method "%s"',
|
||||
$regex, $httpMethod
|
||||
));
|
||||
}
|
||||
|
||||
$this->methodToRegexToRoutesMap[$httpMethod][$regex] = new Route(
|
||||
$httpMethod, $handler, $regex, $variables
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed[]
|
||||
* @return mixed[]
|
||||
*/
|
||||
private function buildRegexForRoute($routeData)
|
||||
{
|
||||
$regex = '';
|
||||
$variables = [];
|
||||
foreach ($routeData as $part) {
|
||||
if (is_string($part)) {
|
||||
$regex .= preg_quote($part, '~');
|
||||
continue;
|
||||
}
|
||||
|
||||
list($varName, $regexPart) = $part;
|
||||
|
||||
if (isset($variables[$varName])) {
|
||||
throw new BadRouteException(sprintf(
|
||||
'Cannot use the same placeholder "%s" twice', $varName
|
||||
));
|
||||
}
|
||||
|
||||
if ($this->regexHasCapturingGroups($regexPart)) {
|
||||
throw new BadRouteException(sprintf(
|
||||
'Regex "%s" for parameter "%s" contains a capturing group',
|
||||
$regexPart, $varName
|
||||
));
|
||||
}
|
||||
|
||||
$variables[$varName] = $varName;
|
||||
$regex .= '(' . $regexPart . ')';
|
||||
}
|
||||
|
||||
return [$regex, $variables];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string
|
||||
* @return bool
|
||||
*/
|
||||
private function regexHasCapturingGroups($regex)
|
||||
{
|
||||
if (false === strpos($regex, '(')) {
|
||||
// Needs to have at least a ( to contain a capturing group
|
||||
return false;
|
||||
}
|
||||
|
||||
// Semi-accurate detection for capturing groups
|
||||
return (bool) preg_match(
|
||||
'~
|
||||
(?:
|
||||
\(\?\(
|
||||
| \[ [^\]\\\\]* (?: \\\\ . [^\]\\\\]* )* \]
|
||||
| \\\\ .
|
||||
) (*SKIP)(*FAIL) |
|
||||
\(
|
||||
(?!
|
||||
\? (?! <(?![!=]) | P< | \' )
|
||||
| \*
|
||||
)
|
||||
~x',
|
||||
$regex
|
||||
);
|
||||
}
|
||||
}
|
@ -0,0 +1,26 @@
|
||||
<?php
|
||||
|
||||
namespace FastRoute;
|
||||
|
||||
interface Dispatcher
|
||||
{
|
||||
const NOT_FOUND = 0;
|
||||
const FOUND = 1;
|
||||
const METHOD_NOT_ALLOWED = 2;
|
||||
|
||||
/**
|
||||
* Dispatches against the provided HTTP method verb and URI.
|
||||
*
|
||||
* Returns array with one of the following formats:
|
||||
*
|
||||
* [self::NOT_FOUND]
|
||||
* [self::METHOD_NOT_ALLOWED, ['GET', 'OTHER_ALLOWED_METHODS']]
|
||||
* [self::FOUND, $handler, ['varName' => 'value', ...]]
|
||||
*
|
||||
* @param string $httpMethod
|
||||
* @param string $uri
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function dispatch($httpMethod, $uri);
|
||||
}
|
@ -0,0 +1,31 @@
|
||||
<?php
|
||||
|
||||
namespace FastRoute\Dispatcher;
|
||||
|
||||
class CharCountBased extends RegexBasedAbstract
|
||||
{
|
||||
public function __construct($data)
|
||||
{
|
||||
list($this->staticRouteMap, $this->variableRouteData) = $data;
|
||||
}
|
||||
|
||||
protected function dispatchVariableRoute($routeData, $uri)
|
||||
{
|
||||
foreach ($routeData as $data) {
|
||||
if (!preg_match($data['regex'], $uri . $data['suffix'], $matches)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
list($handler, $varNames) = $data['routeMap'][end($matches)];
|
||||
|
||||
$vars = [];
|
||||
$i = 0;
|
||||
foreach ($varNames as $varName) {
|
||||
$vars[$varName] = $matches[++$i];
|
||||
}
|
||||
return [self::FOUND, $handler, $vars];
|
||||
}
|
||||
|
||||
return [self::NOT_FOUND];
|
||||
}
|
||||
}
|
@ -0,0 +1,31 @@
|
||||
<?php
|
||||
|
||||
namespace FastRoute\Dispatcher;
|
||||
|
||||
class GroupCountBased extends RegexBasedAbstract
|
||||
{
|
||||
public function __construct($data)
|
||||
{
|
||||
list($this->staticRouteMap, $this->variableRouteData) = $data;
|
||||
}
|
||||
|
||||
protected function dispatchVariableRoute($routeData, $uri)
|
||||
{
|
||||
foreach ($routeData as $data) {
|
||||
if (!preg_match($data['regex'], $uri, $matches)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
list($handler, $varNames) = $data['routeMap'][count($matches)];
|
||||
|
||||
$vars = [];
|
||||
$i = 0;
|
||||
foreach ($varNames as $varName) {
|
||||
$vars[$varName] = $matches[++$i];
|
||||
}
|
||||
return [self::FOUND, $handler, $vars];
|
||||
}
|
||||
|
||||
return [self::NOT_FOUND];
|
||||
}
|
||||
}
|
@ -0,0 +1,33 @@
|
||||
<?php
|
||||
|
||||
namespace FastRoute\Dispatcher;
|
||||
|
||||
class GroupPosBased extends RegexBasedAbstract
|
||||
{
|
||||
public function __construct($data)
|
||||
{
|
||||
list($this->staticRouteMap, $this->variableRouteData) = $data;
|
||||
}
|
||||
|
||||
protected function dispatchVariableRoute($routeData, $uri)
|
||||
{
|
||||
foreach ($routeData as $data) {
|
||||
if (!preg_match($data['regex'], $uri, $matches)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// find first non-empty match
|
||||
for ($i = 1; '' === $matches[$i]; ++$i);
|
||||
|
||||
list($handler, $varNames) = $data['routeMap'][$i];
|
||||
|
||||
$vars = [];
|
||||
foreach ($varNames as $varName) {
|
||||
$vars[$varName] = $matches[$i++];
|
||||
}
|
||||
return [self::FOUND, $handler, $vars];
|
||||
}
|
||||
|
||||
return [self::NOT_FOUND];
|
||||
}
|
||||
}
|
@ -0,0 +1,31 @@
|
||||
<?php
|
||||
|
||||
namespace FastRoute\Dispatcher;
|
||||
|
||||
class MarkBased extends RegexBasedAbstract
|
||||
{
|
||||
public function __construct($data)
|
||||
{
|
||||
list($this->staticRouteMap, $this->variableRouteData) = $data;
|
||||
}
|
||||
|
||||
protected function dispatchVariableRoute($routeData, $uri)
|
||||
{
|
||||
foreach ($routeData as $data) {
|
||||
if (!preg_match($data['regex'], $uri, $matches)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
list($handler, $varNames) = $data['routeMap'][$matches['MARK']];
|
||||
|
||||
$vars = [];
|
||||
$i = 0;
|
||||
foreach ($varNames as $varName) {
|
||||
$vars[$varName] = $matches[++$i];
|
||||
}
|
||||
return [self::FOUND, $handler, $vars];
|
||||
}
|
||||
|
||||
return [self::NOT_FOUND];
|
||||
}
|
||||
}
|
@ -0,0 +1,88 @@
|
||||
<?php
|
||||
|
||||
namespace FastRoute\Dispatcher;
|
||||
|
||||
use FastRoute\Dispatcher;
|
||||
|
||||
abstract class RegexBasedAbstract implements Dispatcher
|
||||
{
|
||||
/** @var mixed[][] */
|
||||
protected $staticRouteMap = [];
|
||||
|
||||
/** @var mixed[] */
|
||||
protected $variableRouteData = [];
|
||||
|
||||
/**
|
||||
* @return mixed[]
|
||||
*/
|
||||
abstract protected function dispatchVariableRoute($routeData, $uri);
|
||||
|
||||
public function dispatch($httpMethod, $uri)
|
||||
{
|
||||
if (isset($this->staticRouteMap[$httpMethod][$uri])) {
|
||||
$handler = $this->staticRouteMap[$httpMethod][$uri];
|
||||
return [self::FOUND, $handler, []];
|
||||
}
|
||||
|
||||
$varRouteData = $this->variableRouteData;
|
||||
if (isset($varRouteData[$httpMethod])) {
|
||||
$result = $this->dispatchVariableRoute($varRouteData[$httpMethod], $uri);
|
||||
if ($result[0] === self::FOUND) {
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
|
||||
// For HEAD requests, attempt fallback to GET
|
||||
if ($httpMethod === 'HEAD') {
|
||||
if (isset($this->staticRouteMap['GET'][$uri])) {
|
||||
$handler = $this->staticRouteMap['GET'][$uri];
|
||||
return [self::FOUND, $handler, []];
|
||||
}
|
||||
if (isset($varRouteData['GET'])) {
|
||||
$result = $this->dispatchVariableRoute($varRouteData['GET'], $uri);
|
||||
if ($result[0] === self::FOUND) {
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If nothing else matches, try fallback routes
|
||||
if (isset($this->staticRouteMap['*'][$uri])) {
|
||||
$handler = $this->staticRouteMap['*'][$uri];
|
||||
return [self::FOUND, $handler, []];
|
||||
}
|
||||
if (isset($varRouteData['*'])) {
|
||||
$result = $this->dispatchVariableRoute($varRouteData['*'], $uri);
|
||||
if ($result[0] === self::FOUND) {
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
|
||||
// Find allowed methods for this URI by matching against all other HTTP methods as well
|
||||
$allowedMethods = [];
|
||||
|
||||
foreach ($this->staticRouteMap as $method => $uriMap) {
|
||||
if ($method !== $httpMethod && isset($uriMap[$uri])) {
|
||||
$allowedMethods[] = $method;
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($varRouteData as $method => $routeData) {
|
||||
if ($method === $httpMethod) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$result = $this->dispatchVariableRoute($routeData, $uri);
|
||||
if ($result[0] === self::FOUND) {
|
||||
$allowedMethods[] = $method;
|
||||
}
|
||||
}
|
||||
|
||||
// If there are no allowed methods the route simply does not exist
|
||||
if ($allowedMethods) {
|
||||
return [self::METHOD_NOT_ALLOWED, $allowedMethods];
|
||||
}
|
||||
|
||||
return [self::NOT_FOUND];
|
||||
}
|
||||
}
|
@ -0,0 +1,47 @@
|
||||
<?php
|
||||
|
||||
namespace FastRoute;
|
||||
|
||||
class Route
|
||||
{
|
||||
/** @var string */
|
||||
public $httpMethod;
|
||||
|
||||
/** @var string */
|
||||
public $regex;
|
||||
|
||||
/** @var array */
|
||||
public $variables;
|
||||
|
||||
/** @var mixed */
|
||||
public $handler;
|
||||
|
||||
/**
|
||||
* Constructs a route (value object).
|
||||
*
|
||||
* @param string $httpMethod
|
||||
* @param mixed $handler
|
||||
* @param string $regex
|
||||
* @param array $variables
|
||||
*/
|
||||
public function __construct($httpMethod, $handler, $regex, $variables)
|
||||
{
|
||||
$this->httpMethod = $httpMethod;
|
||||
$this->handler = $handler;
|
||||
$this->regex = $regex;
|
||||
$this->variables = $variables;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests whether this route matches the given string.
|
||||
*
|
||||
* @param string $str
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function matches($str)
|
||||
{
|
||||
$regex = '~^' . $this->regex . '$~';
|
||||
return (bool) preg_match($regex, $str);
|
||||
}
|
||||
}
|
@ -0,0 +1,152 @@
|
||||
<?php
|
||||
|
||||
namespace FastRoute;
|
||||
|
||||
class RouteCollector
|
||||
{
|
||||
/** @var RouteParser */
|
||||
protected $routeParser;
|
||||
|
||||
/** @var DataGenerator */
|
||||
protected $dataGenerator;
|
||||
|
||||
/** @var string */
|
||||
protected $currentGroupPrefix;
|
||||
|
||||
/**
|
||||
* Constructs a route collector.
|
||||
*
|
||||
* @param RouteParser $routeParser
|
||||
* @param DataGenerator $dataGenerator
|
||||
*/
|
||||
public function __construct(RouteParser $routeParser, DataGenerator $dataGenerator)
|
||||
{
|
||||
$this->routeParser = $routeParser;
|
||||
$this->dataGenerator = $dataGenerator;
|
||||
$this->currentGroupPrefix = '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a route to the collection.
|
||||
*
|
||||
* The syntax used in the $route string depends on the used route parser.
|
||||
*
|
||||
* @param string|string[] $httpMethod
|
||||
* @param string $route
|
||||
* @param mixed $handler
|
||||
*/
|
||||
public function addRoute($httpMethod, $route, $handler)
|
||||
{
|
||||
$route = $this->currentGroupPrefix . $route;
|
||||
$routeDatas = $this->routeParser->parse($route);
|
||||
foreach ((array) $httpMethod as $method) {
|
||||
foreach ($routeDatas as $routeData) {
|
||||
$this->dataGenerator->addRoute($method, $routeData, $handler);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a route group with a common prefix.
|
||||
*
|
||||
* All routes created in the passed callback will have the given group prefix prepended.
|
||||
*
|
||||
* @param string $prefix
|
||||
* @param callable $callback
|
||||
*/
|
||||
public function addGroup($prefix, callable $callback)
|
||||
{
|
||||
$previousGroupPrefix = $this->currentGroupPrefix;
|
||||
$this->currentGroupPrefix = $previousGroupPrefix . $prefix;
|
||||
$callback($this);
|
||||
$this->currentGroupPrefix = $previousGroupPrefix;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a GET route to the collection
|
||||
*
|
||||
* This is simply an alias of $this->addRoute('GET', $route, $handler)
|
||||
*
|
||||
* @param string $route
|
||||
* @param mixed $handler
|
||||
*/
|
||||
public function get($route, $handler)
|
||||
{
|
||||
$this->addRoute('GET', $route, $handler);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a POST route to the collection
|
||||
*
|
||||
* This is simply an alias of $this->addRoute('POST', $route, $handler)
|
||||
*
|
||||
* @param string $route
|
||||
* @param mixed $handler
|
||||
*/
|
||||
public function post($route, $handler)
|
||||
{
|
||||
$this->addRoute('POST', $route, $handler);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a PUT route to the collection
|
||||
*
|
||||
* This is simply an alias of $this->addRoute('PUT', $route, $handler)
|
||||
*
|
||||
* @param string $route
|
||||
* @param mixed $handler
|
||||
*/
|
||||
public function put($route, $handler)
|
||||
{
|
||||
$this->addRoute('PUT', $route, $handler);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a DELETE route to the collection
|
||||
*
|
||||
* This is simply an alias of $this->addRoute('DELETE', $route, $handler)
|
||||
*
|
||||
* @param string $route
|
||||
* @param mixed $handler
|
||||
*/
|
||||
public function delete($route, $handler)
|
||||
{
|
||||
$this->addRoute('DELETE', $route, $handler);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a PATCH route to the collection
|
||||
*
|
||||
* This is simply an alias of $this->addRoute('PATCH', $route, $handler)
|
||||
*
|
||||
* @param string $route
|
||||
* @param mixed $handler
|
||||
*/
|
||||
public function patch($route, $handler)
|
||||
{
|
||||
$this->addRoute('PATCH', $route, $handler);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a HEAD route to the collection
|
||||
*
|
||||
* This is simply an alias of $this->addRoute('HEAD', $route, $handler)
|
||||
*
|
||||
* @param string $route
|
||||
* @param mixed $handler
|
||||
*/
|
||||
public function head($route, $handler)
|
||||
{
|
||||
$this->addRoute('HEAD', $route, $handler);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the collected route data, as provided by the data generator.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getData()
|
||||
{
|
||||
return $this->dataGenerator->getData();
|
||||
}
|
||||
}
|
@ -0,0 +1,37 @@
|
||||
<?php
|
||||
|
||||
namespace FastRoute;
|
||||
|
||||
interface RouteParser
|
||||
{
|
||||
/**
|
||||
* Parses a route string into multiple route data arrays.
|
||||
*
|
||||
* The expected output is defined using an example:
|
||||
*
|
||||
* For the route string "/fixedRoutePart/{varName}[/moreFixed/{varName2:\d+}]", if {varName} is interpreted as
|
||||
* a placeholder and [...] is interpreted as an optional route part, the expected result is:
|
||||
*
|
||||
* [
|
||||
* // first route: without optional part
|
||||
* [
|
||||
* "/fixedRoutePart/",
|
||||
* ["varName", "[^/]+"],
|
||||
* ],
|
||||
* // second route: with optional part
|
||||
* [
|
||||
* "/fixedRoutePart/",
|
||||
* ["varName", "[^/]+"],
|
||||
* "/moreFixed/",
|
||||
* ["varName2", [0-9]+"],
|
||||
* ],
|
||||
* ]
|
||||
*
|
||||
* Here one route string was converted into two route data arrays.
|
||||
*
|
||||
* @param string $route Route string to parse
|
||||
*
|
||||
* @return mixed[][] Array of route data arrays
|
||||
*/
|
||||
public function parse($route);
|
||||
}
|
@ -0,0 +1,87 @@
|
||||
<?php
|
||||
|
||||
namespace FastRoute\RouteParser;
|
||||
|
||||
use FastRoute\BadRouteException;
|
||||
use FastRoute\RouteParser;
|
||||
|
||||
/**
|
||||
* Parses route strings of the following form:
|
||||
*
|
||||
* "/user/{name}[/{id:[0-9]+}]"
|
||||
*/
|
||||
class Std implements RouteParser
|
||||
{
|
||||
const VARIABLE_REGEX = <<<'REGEX'
|
||||
\{
|
||||
\s* ([a-zA-Z_][a-zA-Z0-9_-]*) \s*
|
||||
(?:
|
||||
: \s* ([^{}]*(?:\{(?-1)\}[^{}]*)*)
|
||||
)?
|
||||
\}
|
||||
REGEX;
|
||||
const DEFAULT_DISPATCH_REGEX = '[^/]+';
|
||||
|
||||
public function parse($route)
|
||||
{
|
||||
$routeWithoutClosingOptionals = rtrim($route, ']');
|
||||
$numOptionals = strlen($route) - strlen($routeWithoutClosingOptionals);
|
||||
|
||||
// Split on [ while skipping placeholders
|
||||
$segments = preg_split('~' . self::VARIABLE_REGEX . '(*SKIP)(*F) | \[~x', $routeWithoutClosingOptionals);
|
||||
if ($numOptionals !== count($segments) - 1) {
|
||||
// If there are any ] in the middle of the route, throw a more specific error message
|
||||
if (preg_match('~' . self::VARIABLE_REGEX . '(*SKIP)(*F) | \]~x', $routeWithoutClosingOptionals)) {
|
||||
throw new BadRouteException('Optional segments can only occur at the end of a route');
|
||||
}
|
||||
throw new BadRouteException("Number of opening '[' and closing ']' does not match");
|
||||
}
|
||||
|
||||
$currentRoute = '';
|
||||
$routeDatas = [];
|
||||
foreach ($segments as $n => $segment) {
|
||||
if ($segment === '' && $n !== 0) {
|
||||
throw new BadRouteException('Empty optional part');
|
||||
}
|
||||
|
||||
$currentRoute .= $segment;
|
||||
$routeDatas[] = $this->parsePlaceholders($currentRoute);
|
||||
}
|
||||
return $routeDatas;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses a route string that does not contain optional segments.
|
||||
*
|
||||
* @param string
|
||||
* @return mixed[]
|
||||
*/
|
||||
private function parsePlaceholders($route)
|
||||
{
|
||||
if (!preg_match_all(
|
||||
'~' . self::VARIABLE_REGEX . '~x', $route, $matches,
|
||||
PREG_OFFSET_CAPTURE | PREG_SET_ORDER
|
||||
)) {
|
||||
return [$route];
|
||||
}
|
||||
|
||||
$offset = 0;
|
||||
$routeData = [];
|
||||
foreach ($matches as $set) {
|
||||
if ($set[0][1] > $offset) {
|
||||
$routeData[] = substr($route, $offset, $set[0][1] - $offset);
|
||||
}
|
||||
$routeData[] = [
|
||||
$set[1][0],
|
||||
isset($set[2]) ? trim($set[2][0]) : self::DEFAULT_DISPATCH_REGEX
|
||||
];
|
||||
$offset = $set[0][1] + strlen($set[0][0]);
|
||||
}
|
||||
|
||||
if ($offset !== strlen($route)) {
|
||||
$routeData[] = substr($route, $offset);
|
||||
}
|
||||
|
||||
return $routeData;
|
||||
}
|
||||
}
|
@ -0,0 +1,12 @@
|
||||
<?php
|
||||
|
||||
namespace FastRoute;
|
||||
|
||||
require __DIR__ . '/functions.php';
|
||||
|
||||
spl_autoload_register(function ($class) {
|
||||
if (strpos($class, 'FastRoute\\') === 0) {
|
||||
$name = substr($class, strlen('FastRoute'));
|
||||
require __DIR__ . strtr($name, '\\', DIRECTORY_SEPARATOR) . '.php';
|
||||
}
|
||||
});
|
@ -0,0 +1,74 @@
|
||||
<?php
|
||||
|
||||
namespace FastRoute;
|
||||
|
||||
if (!function_exists('FastRoute\simpleDispatcher')) {
|
||||
/**
|
||||
* @param callable $routeDefinitionCallback
|
||||
* @param array $options
|
||||
*
|
||||
* @return Dispatcher
|
||||
*/
|
||||
function simpleDispatcher(callable $routeDefinitionCallback, array $options = [])
|
||||
{
|
||||
$options += [
|
||||
'routeParser' => 'FastRoute\\RouteParser\\Std',
|
||||
'dataGenerator' => 'FastRoute\\DataGenerator\\GroupCountBased',
|
||||
'dispatcher' => 'FastRoute\\Dispatcher\\GroupCountBased',
|
||||
'routeCollector' => 'FastRoute\\RouteCollector',
|
||||
];
|
||||
|
||||
/** @var RouteCollector $routeCollector */
|
||||
$routeCollector = new $options['routeCollector'](
|
||||
new $options['routeParser'], new $options['dataGenerator']
|
||||
);
|
||||
$routeDefinitionCallback($routeCollector);
|
||||
|
||||
return new $options['dispatcher']($routeCollector->getData());
|
||||
}
|
||||
|
||||
/**
|
||||
* @param callable $routeDefinitionCallback
|
||||
* @param array $options
|
||||
*
|
||||
* @return Dispatcher
|
||||
*/
|
||||
function cachedDispatcher(callable $routeDefinitionCallback, array $options = [])
|
||||
{
|
||||
$options += [
|
||||
'routeParser' => 'FastRoute\\RouteParser\\Std',
|
||||
'dataGenerator' => 'FastRoute\\DataGenerator\\GroupCountBased',
|
||||
'dispatcher' => 'FastRoute\\Dispatcher\\GroupCountBased',
|
||||
'routeCollector' => 'FastRoute\\RouteCollector',
|
||||
'cacheDisabled' => false,
|
||||
];
|
||||
|
||||
if (!isset($options['cacheFile'])) {
|
||||
throw new \LogicException('Must specify "cacheFile" option');
|
||||
}
|
||||
|
||||
if (!$options['cacheDisabled'] && file_exists($options['cacheFile'])) {
|
||||
$dispatchData = require $options['cacheFile'];
|
||||
if (!is_array($dispatchData)) {
|
||||
throw new \RuntimeException('Invalid cache file "' . $options['cacheFile'] . '"');
|
||||
}
|
||||
return new $options['dispatcher']($dispatchData);
|
||||
}
|
||||
|
||||
$routeCollector = new $options['routeCollector'](
|
||||
new $options['routeParser'], new $options['dataGenerator']
|
||||
);
|
||||
$routeDefinitionCallback($routeCollector);
|
||||
|
||||
/** @var RouteCollector $routeCollector */
|
||||
$dispatchData = $routeCollector->getData();
|
||||
if (!$options['cacheDisabled']) {
|
||||
file_put_contents(
|
||||
$options['cacheFile'],
|
||||
'<?php return ' . var_export($dispatchData, true) . ';'
|
||||
);
|
||||
}
|
||||
|
||||
return new $options['dispatcher']($dispatchData);
|
||||
}
|
||||
}
|
@ -0,0 +1,16 @@
|
||||
<?php
|
||||
|
||||
namespace FastRoute\Dispatcher;
|
||||
|
||||
class CharCountBasedTest extends DispatcherTest
|
||||
{
|
||||
protected function getDispatcherClass()
|
||||
{
|
||||
return 'FastRoute\\Dispatcher\\CharCountBased';
|
||||
}
|
||||
|
||||
protected function getDataGeneratorClass()
|
||||
{
|
||||
return 'FastRoute\\DataGenerator\\CharCountBased';
|
||||
}
|
||||
}
|
@ -0,0 +1,581 @@
|
||||
<?php
|
||||
|
||||
namespace FastRoute\Dispatcher;
|
||||
|
||||
use FastRoute\RouteCollector;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
abstract class DispatcherTest extends TestCase
|
||||
{
|
||||
/**
|
||||
* Delegate dispatcher selection to child test classes
|
||||
*/
|
||||
abstract protected function getDispatcherClass();
|
||||
|
||||
/**
|
||||
* Delegate dataGenerator selection to child test classes
|
||||
*/
|
||||
abstract protected function getDataGeneratorClass();
|
||||
|
||||
/**
|
||||
* Set appropriate options for the specific Dispatcher class we're testing
|
||||
*/
|
||||
private function generateDispatcherOptions()
|
||||
{
|
||||
return [
|
||||
'dataGenerator' => $this->getDataGeneratorClass(),
|
||||
'dispatcher' => $this->getDispatcherClass()
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider provideFoundDispatchCases
|
||||
*/
|
||||
public function testFoundDispatches($method, $uri, $callback, $handler, $argDict)
|
||||
{
|
||||
$dispatcher = \FastRoute\simpleDispatcher($callback, $this->generateDispatcherOptions());
|
||||
$info = $dispatcher->dispatch($method, $uri);
|
||||
$this->assertSame($dispatcher::FOUND, $info[0]);
|
||||
$this->assertSame($handler, $info[1]);
|
||||
$this->assertSame($argDict, $info[2]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider provideNotFoundDispatchCases
|
||||
*/
|
||||
public function testNotFoundDispatches($method, $uri, $callback)
|
||||
{
|
||||
$dispatcher = \FastRoute\simpleDispatcher($callback, $this->generateDispatcherOptions());
|
||||
$routeInfo = $dispatcher->dispatch($method, $uri);
|
||||
$this->assertArrayNotHasKey(1, $routeInfo,
|
||||
'NOT_FOUND result must only contain a single element in the returned info array'
|
||||
);
|
||||
$this->assertSame($dispatcher::NOT_FOUND, $routeInfo[0]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider provideMethodNotAllowedDispatchCases
|
||||
*/
|
||||
public function testMethodNotAllowedDispatches($method, $uri, $callback, $availableMethods)
|
||||
{
|
||||
$dispatcher = \FastRoute\simpleDispatcher($callback, $this->generateDispatcherOptions());
|
||||
$routeInfo = $dispatcher->dispatch($method, $uri);
|
||||
$this->assertArrayHasKey(1, $routeInfo,
|
||||
'METHOD_NOT_ALLOWED result must return an array of allowed methods at index 1'
|
||||
);
|
||||
|
||||
list($routedStatus, $methodArray) = $dispatcher->dispatch($method, $uri);
|
||||
$this->assertSame($dispatcher::METHOD_NOT_ALLOWED, $routedStatus);
|
||||
$this->assertSame($availableMethods, $methodArray);
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException \FastRoute\BadRouteException
|
||||
* @expectedExceptionMessage Cannot use the same placeholder "test" twice
|
||||
*/
|
||||
public function testDuplicateVariableNameError()
|
||||
{
|
||||
\FastRoute\simpleDispatcher(function (RouteCollector $r) {
|
||||
$r->addRoute('GET', '/foo/{test}/{test:\d+}', 'handler0');
|
||||
}, $this->generateDispatcherOptions());
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException \FastRoute\BadRouteException
|
||||
* @expectedExceptionMessage Cannot register two routes matching "/user/([^/]+)" for method "GET"
|
||||
*/
|
||||
public function testDuplicateVariableRoute()
|
||||
{
|
||||
\FastRoute\simpleDispatcher(function (RouteCollector $r) {
|
||||
$r->addRoute('GET', '/user/{id}', 'handler0'); // oops, forgot \d+ restriction ;)
|
||||
$r->addRoute('GET', '/user/{name}', 'handler1');
|
||||
}, $this->generateDispatcherOptions());
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException \FastRoute\BadRouteException
|
||||
* @expectedExceptionMessage Cannot register two routes matching "/user" for method "GET"
|
||||
*/
|
||||
public function testDuplicateStaticRoute()
|
||||
{
|
||||
\FastRoute\simpleDispatcher(function (RouteCollector $r) {
|
||||
$r->addRoute('GET', '/user', 'handler0');
|
||||
$r->addRoute('GET', '/user', 'handler1');
|
||||
}, $this->generateDispatcherOptions());
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException \FastRoute\BadRouteException
|
||||
* @expectedExceptionMessage Static route "/user/nikic" is shadowed by previously defined variable route "/user/([^/]+)" for method "GET"
|
||||
*/
|
||||
public function testShadowedStaticRoute()
|
||||
{
|
||||
\FastRoute\simpleDispatcher(function (RouteCollector $r) {
|
||||
$r->addRoute('GET', '/user/{name}', 'handler0');
|
||||
$r->addRoute('GET', '/user/nikic', 'handler1');
|
||||
}, $this->generateDispatcherOptions());
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException \FastRoute\BadRouteException
|
||||
* @expectedExceptionMessage Regex "(en|de)" for parameter "lang" contains a capturing group
|
||||
*/
|
||||
public function testCapturing()
|
||||
{
|
||||
\FastRoute\simpleDispatcher(function (RouteCollector $r) {
|
||||
$r->addRoute('GET', '/{lang:(en|de)}', 'handler0');
|
||||
}, $this->generateDispatcherOptions());
|
||||
}
|
||||
|
||||
public function provideFoundDispatchCases()
|
||||
{
|
||||
$cases = [];
|
||||
|
||||
// 0 -------------------------------------------------------------------------------------->
|
||||
|
||||
$callback = function (RouteCollector $r) {
|
||||
$r->addRoute('GET', '/resource/123/456', 'handler0');
|
||||
};
|
||||
|
||||
$method = 'GET';
|
||||
$uri = '/resource/123/456';
|
||||
$handler = 'handler0';
|
||||
$argDict = [];
|
||||
|
||||
$cases[] = [$method, $uri, $callback, $handler, $argDict];
|
||||
|
||||
// 1 -------------------------------------------------------------------------------------->
|
||||
|
||||
$callback = function (RouteCollector $r) {
|
||||
$r->addRoute('GET', '/handler0', 'handler0');
|
||||
$r->addRoute('GET', '/handler1', 'handler1');
|
||||
$r->addRoute('GET', '/handler2', 'handler2');
|
||||
};
|
||||
|
||||
$method = 'GET';
|
||||
$uri = '/handler2';
|
||||
$handler = 'handler2';
|
||||
$argDict = [];
|
||||
|
||||
$cases[] = [$method, $uri, $callback, $handler, $argDict];
|
||||
|
||||
// 2 -------------------------------------------------------------------------------------->
|
||||
|
||||
$callback = function (RouteCollector $r) {
|
||||
$r->addRoute('GET', '/user/{name}/{id:[0-9]+}', 'handler0');
|
||||
$r->addRoute('GET', '/user/{id:[0-9]+}', 'handler1');
|
||||
$r->addRoute('GET', '/user/{name}', 'handler2');
|
||||
};
|
||||
|
||||
$method = 'GET';
|
||||
$uri = '/user/rdlowrey';
|
||||
$handler = 'handler2';
|
||||
$argDict = ['name' => 'rdlowrey'];
|
||||
|
||||
$cases[] = [$method, $uri, $callback, $handler, $argDict];
|
||||
|
||||
// 3 -------------------------------------------------------------------------------------->
|
||||
|
||||
// reuse $callback from #2
|
||||
|
||||
$method = 'GET';
|
||||
$uri = '/user/12345';
|
||||
$handler = 'handler1';
|
||||
$argDict = ['id' => '12345'];
|
||||
|
||||
$cases[] = [$method, $uri, $callback, $handler, $argDict];
|
||||
|
||||
// 4 -------------------------------------------------------------------------------------->
|
||||
|
||||
// reuse $callback from #3
|
||||
|
||||
$method = 'GET';
|
||||
$uri = '/user/NaN';
|
||||
$handler = 'handler2';
|
||||
$argDict = ['name' => 'NaN'];
|
||||
|
||||
$cases[] = [$method, $uri, $callback, $handler, $argDict];
|
||||
|
||||
// 5 -------------------------------------------------------------------------------------->
|
||||
|
||||
// reuse $callback from #4
|
||||
|
||||
$method = 'GET';
|
||||
$uri = '/user/rdlowrey/12345';
|
||||
$handler = 'handler0';
|
||||
$argDict = ['name' => 'rdlowrey', 'id' => '12345'];
|
||||
|
||||
$cases[] = [$method, $uri, $callback, $handler, $argDict];
|
||||
|
||||
// 6 -------------------------------------------------------------------------------------->
|
||||
|
||||
$callback = function (RouteCollector $r) {
|
||||
$r->addRoute('GET', '/user/{id:[0-9]+}', 'handler0');
|
||||
$r->addRoute('GET', '/user/12345/extension', 'handler1');
|
||||
$r->addRoute('GET', '/user/{id:[0-9]+}.{extension}', 'handler2');
|
||||
};
|
||||
|
||||
$method = 'GET';
|
||||
$uri = '/user/12345.svg';
|
||||
$handler = 'handler2';
|
||||
$argDict = ['id' => '12345', 'extension' => 'svg'];
|
||||
|
||||
$cases[] = [$method, $uri, $callback, $handler, $argDict];
|
||||
|
||||
// 7 ----- Test GET method fallback on HEAD route miss ------------------------------------>
|
||||
|
||||
$callback = function (RouteCollector $r) {
|
||||
$r->addRoute('GET', '/user/{name}', 'handler0');
|
||||
$r->addRoute('GET', '/user/{name}/{id:[0-9]+}', 'handler1');
|
||||
$r->addRoute('GET', '/static0', 'handler2');
|
||||
$r->addRoute('GET', '/static1', 'handler3');
|
||||
$r->addRoute('HEAD', '/static1', 'handler4');
|
||||
};
|
||||
|
||||
$method = 'HEAD';
|
||||
$uri = '/user/rdlowrey';
|
||||
$handler = 'handler0';
|
||||
$argDict = ['name' => 'rdlowrey'];
|
||||
|
||||
$cases[] = [$method, $uri, $callback, $handler, $argDict];
|
||||
|
||||
// 8 ----- Test GET method fallback on HEAD route miss ------------------------------------>
|
||||
|
||||
// reuse $callback from #7
|
||||
|
||||
$method = 'HEAD';
|
||||
$uri = '/user/rdlowrey/1234';
|
||||
$handler = 'handler1';
|
||||
$argDict = ['name' => 'rdlowrey', 'id' => '1234'];
|
||||
|
||||
$cases[] = [$method, $uri, $callback, $handler, $argDict];
|
||||
|
||||
// 9 ----- Test GET method fallback on HEAD route miss ------------------------------------>
|
||||
|
||||
// reuse $callback from #8
|
||||
|
||||
$method = 'HEAD';
|
||||
$uri = '/static0';
|
||||
$handler = 'handler2';
|
||||
$argDict = [];
|
||||
|
||||
$cases[] = [$method, $uri, $callback, $handler, $argDict];
|
||||
|
||||
// 10 ---- Test existing HEAD route used if available (no fallback) ----------------------->
|
||||
|
||||
// reuse $callback from #9
|
||||
|
||||
$method = 'HEAD';
|
||||
$uri = '/static1';
|
||||
$handler = 'handler4';
|
||||
$argDict = [];
|
||||
|
||||
$cases[] = [$method, $uri, $callback, $handler, $argDict];
|
||||
|
||||
// 11 ---- More specified routes are not shadowed by less specific of another method ------>
|
||||
|
||||
$callback = function (RouteCollector $r) {
|
||||
$r->addRoute('GET', '/user/{name}', 'handler0');
|
||||
$r->addRoute('POST', '/user/{name:[a-z]+}', 'handler1');
|
||||
};
|
||||
|
||||
$method = 'POST';
|
||||
$uri = '/user/rdlowrey';
|
||||
$handler = 'handler1';
|
||||
$argDict = ['name' => 'rdlowrey'];
|
||||
|
||||
$cases[] = [$method, $uri, $callback, $handler, $argDict];
|
||||
|
||||
// 12 ---- Handler of more specific routes is used, if it occurs first -------------------->
|
||||
|
||||
$callback = function (RouteCollector $r) {
|
||||
$r->addRoute('GET', '/user/{name}', 'handler0');
|
||||
$r->addRoute('POST', '/user/{name:[a-z]+}', 'handler1');
|
||||
$r->addRoute('POST', '/user/{name}', 'handler2');
|
||||
};
|
||||
|
||||
$method = 'POST';
|
||||
$uri = '/user/rdlowrey';
|
||||
$handler = 'handler1';
|
||||
$argDict = ['name' => 'rdlowrey'];
|
||||
|
||||
$cases[] = [$method, $uri, $callback, $handler, $argDict];
|
||||
|
||||
// 13 ---- Route with constant suffix ----------------------------------------------------->
|
||||
|
||||
$callback = function (RouteCollector $r) {
|
||||
$r->addRoute('GET', '/user/{name}', 'handler0');
|
||||
$r->addRoute('GET', '/user/{name}/edit', 'handler1');
|
||||
};
|
||||
|
||||
$method = 'GET';
|
||||
$uri = '/user/rdlowrey/edit';
|
||||
$handler = 'handler1';
|
||||
$argDict = ['name' => 'rdlowrey'];
|
||||
|
||||
$cases[] = [$method, $uri, $callback, $handler, $argDict];
|
||||
|
||||
// 14 ---- Handle multiple methods with the same handler ---------------------------------->
|
||||
|
||||
$callback = function (RouteCollector $r) {
|
||||
$r->addRoute(['GET', 'POST'], '/user', 'handlerGetPost');
|
||||
$r->addRoute(['DELETE'], '/user', 'handlerDelete');
|
||||
$r->addRoute([], '/user', 'handlerNone');
|
||||
};
|
||||
|
||||
$argDict = [];
|
||||
$cases[] = ['GET', '/user', $callback, 'handlerGetPost', $argDict];
|
||||
$cases[] = ['POST', '/user', $callback, 'handlerGetPost', $argDict];
|
||||
$cases[] = ['DELETE', '/user', $callback, 'handlerDelete', $argDict];
|
||||
|
||||
// 17 ----
|
||||
|
||||
$callback = function (RouteCollector $r) {
|
||||
$r->addRoute('POST', '/user.json', 'handler0');
|
||||
$r->addRoute('GET', '/{entity}.json', 'handler1');
|
||||
};
|
||||
|
||||
$cases[] = ['GET', '/user.json', $callback, 'handler1', ['entity' => 'user']];
|
||||
|
||||
// 18 ----
|
||||
|
||||
$callback = function (RouteCollector $r) {
|
||||
$r->addRoute('GET', '', 'handler0');
|
||||
};
|
||||
|
||||
$cases[] = ['GET', '', $callback, 'handler0', []];
|
||||
|
||||
// 19 ----
|
||||
|
||||
$callback = function (RouteCollector $r) {
|
||||
$r->addRoute('HEAD', '/a/{foo}', 'handler0');
|
||||
$r->addRoute('GET', '/b/{foo}', 'handler1');
|
||||
};
|
||||
|
||||
$cases[] = ['HEAD', '/b/bar', $callback, 'handler1', ['foo' => 'bar']];
|
||||
|
||||
// 20 ----
|
||||
|
||||
$callback = function (RouteCollector $r) {
|
||||
$r->addRoute('HEAD', '/a', 'handler0');
|
||||
$r->addRoute('GET', '/b', 'handler1');
|
||||
};
|
||||
|
||||
$cases[] = ['HEAD', '/b', $callback, 'handler1', []];
|
||||
|
||||
// 21 ----
|
||||
|
||||
$callback = function (RouteCollector $r) {
|
||||
$r->addRoute('GET', '/foo', 'handler0');
|
||||
$r->addRoute('HEAD', '/{bar}', 'handler1');
|
||||
};
|
||||
|
||||
$cases[] = ['HEAD', '/foo', $callback, 'handler1', ['bar' => 'foo']];
|
||||
|
||||
// 22 ----
|
||||
|
||||
$callback = function (RouteCollector $r) {
|
||||
$r->addRoute('*', '/user', 'handler0');
|
||||
$r->addRoute('*', '/{user}', 'handler1');
|
||||
$r->addRoute('GET', '/user', 'handler2');
|
||||
};
|
||||
|
||||
$cases[] = ['GET', '/user', $callback, 'handler2', []];
|
||||
|
||||
// 23 ----
|
||||
|
||||
$callback = function (RouteCollector $r) {
|
||||
$r->addRoute('*', '/user', 'handler0');
|
||||
$r->addRoute('GET', '/user', 'handler1');
|
||||
};
|
||||
|
||||
$cases[] = ['POST', '/user', $callback, 'handler0', []];
|
||||
|
||||
// 24 ----
|
||||
|
||||
$cases[] = ['HEAD', '/user', $callback, 'handler1', []];
|
||||
|
||||
// 25 ----
|
||||
|
||||
$callback = function (RouteCollector $r) {
|
||||
$r->addRoute('GET', '/{bar}', 'handler0');
|
||||
$r->addRoute('*', '/foo', 'handler1');
|
||||
};
|
||||
|
||||
$cases[] = ['GET', '/foo', $callback, 'handler0', ['bar' => 'foo']];
|
||||
|
||||
// 26 ----
|
||||
|
||||
$callback = function(RouteCollector $r) {
|
||||
$r->addRoute('GET', '/user', 'handler0');
|
||||
$r->addRoute('*', '/{foo:.*}', 'handler1');
|
||||
};
|
||||
|
||||
$cases[] = ['POST', '/bar', $callback, 'handler1', ['foo' => 'bar']];
|
||||
|
||||
// x -------------------------------------------------------------------------------------->
|
||||
|
||||
return $cases;
|
||||
}
|
||||
|
||||
public function provideNotFoundDispatchCases()
|
||||
{
|
||||
$cases = [];
|
||||
|
||||
// 0 -------------------------------------------------------------------------------------->
|
||||
|
||||
$callback = function (RouteCollector $r) {
|
||||
$r->addRoute('GET', '/resource/123/456', 'handler0');
|
||||
};
|
||||
|
||||
$method = 'GET';
|
||||
$uri = '/not-found';
|
||||
|
||||
$cases[] = [$method, $uri, $callback];
|
||||
|
||||
// 1 -------------------------------------------------------------------------------------->
|
||||
|
||||
// reuse callback from #0
|
||||
$method = 'POST';
|
||||
$uri = '/not-found';
|
||||
|
||||
$cases[] = [$method, $uri, $callback];
|
||||
|
||||
// 2 -------------------------------------------------------------------------------------->
|
||||
|
||||
// reuse callback from #1
|
||||
$method = 'PUT';
|
||||
$uri = '/not-found';
|
||||
|
||||
$cases[] = [$method, $uri, $callback];
|
||||
|
||||
// 3 -------------------------------------------------------------------------------------->
|
||||
|
||||
$callback = function (RouteCollector $r) {
|
||||
$r->addRoute('GET', '/handler0', 'handler0');
|
||||
$r->addRoute('GET', '/handler1', 'handler1');
|
||||
$r->addRoute('GET', '/handler2', 'handler2');
|
||||
};
|
||||
|
||||
$method = 'GET';
|
||||
$uri = '/not-found';
|
||||
|
||||
$cases[] = [$method, $uri, $callback];
|
||||
|
||||
// 4 -------------------------------------------------------------------------------------->
|
||||
|
||||
$callback = function (RouteCollector $r) {
|
||||
$r->addRoute('GET', '/user/{name}/{id:[0-9]+}', 'handler0');
|
||||
$r->addRoute('GET', '/user/{id:[0-9]+}', 'handler1');
|
||||
$r->addRoute('GET', '/user/{name}', 'handler2');
|
||||
};
|
||||
|
||||
$method = 'GET';
|
||||
$uri = '/not-found';
|
||||
|
||||
$cases[] = [$method, $uri, $callback];
|
||||
|
||||
// 5 -------------------------------------------------------------------------------------->
|
||||
|
||||
// reuse callback from #4
|
||||
$method = 'GET';
|
||||
$uri = '/user/rdlowrey/12345/not-found';
|
||||
|
||||
$cases[] = [$method, $uri, $callback];
|
||||
|
||||
// 6 -------------------------------------------------------------------------------------->
|
||||
|
||||
// reuse callback from #5
|
||||
$method = 'HEAD';
|
||||
|
||||
$cases[] = [$method, $uri, $callback];
|
||||
|
||||
// x -------------------------------------------------------------------------------------->
|
||||
|
||||
return $cases;
|
||||
}
|
||||
|
||||
public function provideMethodNotAllowedDispatchCases()
|
||||
{
|
||||
$cases = [];
|
||||
|
||||
// 0 -------------------------------------------------------------------------------------->
|
||||
|
||||
$callback = function (RouteCollector $r) {
|
||||
$r->addRoute('GET', '/resource/123/456', 'handler0');
|
||||
};
|
||||
|
||||
$method = 'POST';
|
||||
$uri = '/resource/123/456';
|
||||
$allowedMethods = ['GET'];
|
||||
|
||||
$cases[] = [$method, $uri, $callback, $allowedMethods];
|
||||
|
||||
// 1 -------------------------------------------------------------------------------------->
|
||||
|
||||
$callback = function (RouteCollector $r) {
|
||||
$r->addRoute('GET', '/resource/123/456', 'handler0');
|
||||
$r->addRoute('POST', '/resource/123/456', 'handler1');
|
||||
$r->addRoute('PUT', '/resource/123/456', 'handler2');
|
||||
$r->addRoute('*', '/', 'handler3');
|
||||
};
|
||||
|
||||
$method = 'DELETE';
|
||||
$uri = '/resource/123/456';
|
||||
$allowedMethods = ['GET', 'POST', 'PUT'];
|
||||
|
||||
$cases[] = [$method, $uri, $callback, $allowedMethods];
|
||||
|
||||
// 2 -------------------------------------------------------------------------------------->
|
||||
|
||||
$callback = function (RouteCollector $r) {
|
||||
$r->addRoute('GET', '/user/{name}/{id:[0-9]+}', 'handler0');
|
||||
$r->addRoute('POST', '/user/{name}/{id:[0-9]+}', 'handler1');
|
||||
$r->addRoute('PUT', '/user/{name}/{id:[0-9]+}', 'handler2');
|
||||
$r->addRoute('PATCH', '/user/{name}/{id:[0-9]+}', 'handler3');
|
||||
};
|
||||
|
||||
$method = 'DELETE';
|
||||
$uri = '/user/rdlowrey/42';
|
||||
$allowedMethods = ['GET', 'POST', 'PUT', 'PATCH'];
|
||||
|
||||
$cases[] = [$method, $uri, $callback, $allowedMethods];
|
||||
|
||||
// 3 -------------------------------------------------------------------------------------->
|
||||
|
||||
$callback = function (RouteCollector $r) {
|
||||
$r->addRoute('POST', '/user/{name}', 'handler1');
|
||||
$r->addRoute('PUT', '/user/{name:[a-z]+}', 'handler2');
|
||||
$r->addRoute('PATCH', '/user/{name:[a-z]+}', 'handler3');
|
||||
};
|
||||
|
||||
$method = 'GET';
|
||||
$uri = '/user/rdlowrey';
|
||||
$allowedMethods = ['POST', 'PUT', 'PATCH'];
|
||||
|
||||
$cases[] = [$method, $uri, $callback, $allowedMethods];
|
||||
|
||||
// 4 -------------------------------------------------------------------------------------->
|
||||
|
||||
$callback = function (RouteCollector $r) {
|
||||
$r->addRoute(['GET', 'POST'], '/user', 'handlerGetPost');
|
||||
$r->addRoute(['DELETE'], '/user', 'handlerDelete');
|
||||
$r->addRoute([], '/user', 'handlerNone');
|
||||
};
|
||||
|
||||
$cases[] = ['PUT', '/user', $callback, ['GET', 'POST', 'DELETE']];
|
||||
|
||||
// 5
|
||||
|
||||
$callback = function (RouteCollector $r) {
|
||||
$r->addRoute('POST', '/user.json', 'handler0');
|
||||
$r->addRoute('GET', '/{entity}.json', 'handler1');
|
||||
};
|
||||
|
||||
$cases[] = ['PUT', '/user.json', $callback, ['POST', 'GET']];
|
||||
|
||||
// x -------------------------------------------------------------------------------------->
|
||||
|
||||
return $cases;
|
||||
}
|
||||
}
|
@ -0,0 +1,16 @@
|
||||
<?php
|
||||
|
||||
namespace FastRoute\Dispatcher;
|
||||
|
||||
class GroupCountBasedTest extends DispatcherTest
|
||||
{
|
||||
protected function getDispatcherClass()
|
||||
{
|
||||
return 'FastRoute\\Dispatcher\\GroupCountBased';
|
||||
}
|
||||
|
||||
protected function getDataGeneratorClass()
|
||||
{
|
||||
return 'FastRoute\\DataGenerator\\GroupCountBased';
|
||||
}
|
||||
}
|
@ -0,0 +1,16 @@
|
||||
<?php
|
||||
|
||||
namespace FastRoute\Dispatcher;
|
||||
|
||||
class GroupPosBasedTest extends DispatcherTest
|
||||
{
|
||||
protected function getDispatcherClass()
|
||||
{
|
||||
return 'FastRoute\\Dispatcher\\GroupPosBased';
|
||||
}
|
||||
|
||||
protected function getDataGeneratorClass()
|
||||
{
|
||||
return 'FastRoute\\DataGenerator\\GroupPosBased';
|
||||
}
|
||||
}
|
@ -0,0 +1,24 @@
|
||||
<?php
|
||||
|
||||
namespace FastRoute\Dispatcher;
|
||||
|
||||
class MarkBasedTest extends DispatcherTest
|
||||
{
|
||||
public function setUp()
|
||||
{
|
||||
preg_match('/(*MARK:A)a/', 'a', $matches);
|
||||
if (!isset($matches['MARK'])) {
|
||||
$this->markTestSkipped('PHP 5.6 required for MARK support');
|
||||
}
|
||||
}
|
||||
|
||||
protected function getDispatcherClass()
|
||||
{
|
||||
return 'FastRoute\\Dispatcher\\MarkBased';
|
||||
}
|
||||
|
||||
protected function getDataGeneratorClass()
|
||||
{
|
||||
return 'FastRoute\\DataGenerator\\MarkBased';
|
||||
}
|
||||
}
|
@ -0,0 +1,44 @@
|
||||
<?php
|
||||
|
||||
namespace FastRoute;
|
||||
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
class HackTypecheckerTest extends TestCase
|
||||
{
|
||||
const SERVER_ALREADY_RUNNING_CODE = 77;
|
||||
|
||||
public function testTypechecks($recurse = true)
|
||||
{
|
||||
if (!defined('HHVM_VERSION')) {
|
||||
$this->markTestSkipped('HHVM only');
|
||||
}
|
||||
if (!version_compare(HHVM_VERSION, '3.9.0', '>=')) {
|
||||
$this->markTestSkipped('classname<T> requires HHVM 3.9+');
|
||||
}
|
||||
|
||||
// The typechecker recurses the whole tree, so it makes sure
|
||||
// that everything in fixtures/ is valid when this runs.
|
||||
|
||||
$output = [];
|
||||
$exit_code = null;
|
||||
exec(
|
||||
'hh_server --check ' . escapeshellarg(__DIR__ . '/../../') . ' 2>&1',
|
||||
$output,
|
||||
$exit_code
|
||||
);
|
||||
if ($exit_code === self::SERVER_ALREADY_RUNNING_CODE) {
|
||||
$this->assertTrue(
|
||||
$recurse,
|
||||
'Typechecker still running after running hh_client stop'
|
||||
);
|
||||
// Server already running - 3.10 => 3.11 regression:
|
||||
// https://github.com/facebook/hhvm/issues/6646
|
||||
exec('hh_client stop 2>/dev/null');
|
||||
$this->testTypechecks(/* recurse = */ false);
|
||||
return;
|
||||
|
||||
}
|
||||
$this->assertSame(0, $exit_code, implode("\n", $output));
|
||||
}
|
||||
}
|
@ -0,0 +1,29 @@
|
||||
<?hh
|
||||
|
||||
namespace FastRoute\TestFixtures;
|
||||
|
||||
function all_options_simple(): \FastRoute\Dispatcher {
|
||||
return \FastRoute\simpleDispatcher(
|
||||
$collector ==> {},
|
||||
shape(
|
||||
'routeParser' => \FastRoute\RouteParser\Std::class,
|
||||
'dataGenerator' => \FastRoute\DataGenerator\GroupCountBased::class,
|
||||
'dispatcher' => \FastRoute\Dispatcher\GroupCountBased::class,
|
||||
'routeCollector' => \FastRoute\RouteCollector::class,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
function all_options_cached(): \FastRoute\Dispatcher {
|
||||
return \FastRoute\cachedDispatcher(
|
||||
$collector ==> {},
|
||||
shape(
|
||||
'routeParser' => \FastRoute\RouteParser\Std::class,
|
||||
'dataGenerator' => \FastRoute\DataGenerator\GroupCountBased::class,
|
||||
'dispatcher' => \FastRoute\Dispatcher\GroupCountBased::class,
|
||||
'routeCollector' => \FastRoute\RouteCollector::class,
|
||||
'cacheFile' => '/dev/null',
|
||||
'cacheDisabled' => false,
|
||||
),
|
||||
);
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
<?hh
|
||||
|
||||
namespace FastRoute\TestFixtures;
|
||||
|
||||
function empty_options_simple(): \FastRoute\Dispatcher {
|
||||
return \FastRoute\simpleDispatcher($collector ==> {}, shape());
|
||||
}
|
||||
|
||||
function empty_options_cached(): \FastRoute\Dispatcher {
|
||||
return \FastRoute\cachedDispatcher($collector ==> {}, shape());
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
<?hh
|
||||
|
||||
namespace FastRoute\TestFixtures;
|
||||
|
||||
function no_options_simple(): \FastRoute\Dispatcher {
|
||||
return \FastRoute\simpleDispatcher($collector ==> {});
|
||||
}
|
||||
|
||||
function no_options_cached(): \FastRoute\Dispatcher {
|
||||
return \FastRoute\cachedDispatcher($collector ==> {});
|
||||
}
|
@ -0,0 +1,108 @@
|
||||
<?php
|
||||
|
||||
namespace FastRoute;
|
||||
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
class RouteCollectorTest extends TestCase
|
||||
{
|
||||
public function testShortcuts()
|
||||
{
|
||||
$r = new DummyRouteCollector();
|
||||
|
||||
$r->delete('/delete', 'delete');
|
||||
$r->get('/get', 'get');
|
||||
$r->head('/head', 'head');
|
||||
$r->patch('/patch', 'patch');
|
||||
$r->post('/post', 'post');
|
||||
$r->put('/put', 'put');
|
||||
|
||||
$expected = [
|
||||
['DELETE', '/delete', 'delete'],
|
||||
['GET', '/get', 'get'],
|
||||
['HEAD', '/head', 'head'],
|
||||
['PATCH', '/patch', 'patch'],
|
||||
['POST', '/post', 'post'],
|
||||
['PUT', '/put', 'put'],
|
||||
];
|
||||
|
||||
$this->assertSame($expected, $r->routes);
|
||||
}
|
||||
|
||||
public function testGroups()
|
||||
{
|
||||
$r = new DummyRouteCollector();
|
||||
|
||||
$r->delete('/delete', 'delete');
|
||||
$r->get('/get', 'get');
|
||||
$r->head('/head', 'head');
|
||||
$r->patch('/patch', 'patch');
|
||||
$r->post('/post', 'post');
|
||||
$r->put('/put', 'put');
|
||||
|
||||
$r->addGroup('/group-one', function (DummyRouteCollector $r) {
|
||||
$r->delete('/delete', 'delete');
|
||||
$r->get('/get', 'get');
|
||||
$r->head('/head', 'head');
|
||||
$r->patch('/patch', 'patch');
|
||||
$r->post('/post', 'post');
|
||||
$r->put('/put', 'put');
|
||||
|
||||
$r->addGroup('/group-two', function (DummyRouteCollector $r) {
|
||||
$r->delete('/delete', 'delete');
|
||||
$r->get('/get', 'get');
|
||||
$r->head('/head', 'head');
|
||||
$r->patch('/patch', 'patch');
|
||||
$r->post('/post', 'post');
|
||||
$r->put('/put', 'put');
|
||||
});
|
||||
});
|
||||
|
||||
$r->addGroup('/admin', function (DummyRouteCollector $r) {
|
||||
$r->get('-some-info', 'admin-some-info');
|
||||
});
|
||||
$r->addGroup('/admin-', function (DummyRouteCollector $r) {
|
||||
$r->get('more-info', 'admin-more-info');
|
||||
});
|
||||
|
||||
$expected = [
|
||||
['DELETE', '/delete', 'delete'],
|
||||
['GET', '/get', 'get'],
|
||||
['HEAD', '/head', 'head'],
|
||||
['PATCH', '/patch', 'patch'],
|
||||
['POST', '/post', 'post'],
|
||||
['PUT', '/put', 'put'],
|
||||
['DELETE', '/group-one/delete', 'delete'],
|
||||
['GET', '/group-one/get', 'get'],
|
||||
['HEAD', '/group-one/head', 'head'],
|
||||
['PATCH', '/group-one/patch', 'patch'],
|
||||
['POST', '/group-one/post', 'post'],
|
||||
['PUT', '/group-one/put', 'put'],
|
||||
['DELETE', '/group-one/group-two/delete', 'delete'],
|
||||
['GET', '/group-one/group-two/get', 'get'],
|
||||
['HEAD', '/group-one/group-two/head', 'head'],
|
||||
['PATCH', '/group-one/group-two/patch', 'patch'],
|
||||
['POST', '/group-one/group-two/post', 'post'],
|
||||
['PUT', '/group-one/group-two/put', 'put'],
|
||||
['GET', '/admin-some-info', 'admin-some-info'],
|
||||
['GET', '/admin-more-info', 'admin-more-info'],
|
||||
];
|
||||
|
||||
$this->assertSame($expected, $r->routes);
|
||||
}
|
||||
}
|
||||
|
||||
class DummyRouteCollector extends RouteCollector
|
||||
{
|
||||
public $routes = [];
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
}
|
||||
|
||||
public function addRoute($method, $route, $handler)
|
||||
{
|
||||
$route = $this->currentGroupPrefix . $route;
|
||||
$this->routes[] = [$method, $route, $handler];
|
||||
}
|
||||
}
|
@ -0,0 +1,154 @@
|
||||
<?php
|
||||
|
||||
namespace FastRoute\RouteParser;
|
||||
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
class StdTest extends TestCase
|
||||
{
|
||||
/** @dataProvider provideTestParse */
|
||||
public function testParse($routeString, $expectedRouteDatas)
|
||||
{
|
||||
$parser = new Std();
|
||||
$routeDatas = $parser->parse($routeString);
|
||||
$this->assertSame($expectedRouteDatas, $routeDatas);
|
||||
}
|
||||
|
||||
/** @dataProvider provideTestParseError */
|
||||
public function testParseError($routeString, $expectedExceptionMessage)
|
||||
{
|
||||
$parser = new Std();
|
||||
$this->setExpectedException('FastRoute\\BadRouteException', $expectedExceptionMessage);
|
||||
$parser->parse($routeString);
|
||||
}
|
||||
|
||||
public function provideTestParse()
|
||||
{
|
||||
return [
|
||||
[
|
||||
'/test',
|
||||
[
|
||||
['/test'],
|
||||
]
|
||||
],
|
||||
[
|
||||
'/test/{param}',
|
||||
[
|
||||
['/test/', ['param', '[^/]+']],
|
||||
]
|
||||
],
|
||||
[
|
||||
'/te{ param }st',
|
||||
[
|
||||
['/te', ['param', '[^/]+'], 'st']
|
||||
]
|
||||
],
|
||||
[
|
||||
'/test/{param1}/test2/{param2}',
|
||||
[
|
||||
['/test/', ['param1', '[^/]+'], '/test2/', ['param2', '[^/]+']]
|
||||
]
|
||||
],
|
||||
[
|
||||
'/test/{param:\d+}',
|
||||
[
|
||||
['/test/', ['param', '\d+']]
|
||||
]
|
||||
],
|
||||
[
|
||||
'/test/{ param : \d{1,9} }',
|
||||
[
|
||||
['/test/', ['param', '\d{1,9}']]
|
||||
]
|
||||
],
|
||||
[
|
||||
'/test[opt]',
|
||||
[
|
||||
['/test'],
|
||||
['/testopt'],
|
||||
]
|
||||
],
|
||||
[
|
||||
'/test[/{param}]',
|
||||
[
|
||||
['/test'],
|
||||
['/test/', ['param', '[^/]+']],
|
||||
]
|
||||
],
|
||||
[
|
||||
'/{param}[opt]',
|
||||
[
|
||||
['/', ['param', '[^/]+']],
|
||||
['/', ['param', '[^/]+'], 'opt']
|
||||
]
|
||||
],
|
||||
[
|
||||
'/test[/{name}[/{id:[0-9]+}]]',
|
||||
[
|
||||
['/test'],
|
||||
['/test/', ['name', '[^/]+']],
|
||||
['/test/', ['name', '[^/]+'], '/', ['id', '[0-9]+']],
|
||||
]
|
||||
],
|
||||
[
|
||||
'',
|
||||
[
|
||||
[''],
|
||||
]
|
||||
],
|
||||
[
|
||||
'[test]',
|
||||
[
|
||||
[''],
|
||||
['test'],
|
||||
]
|
||||
],
|
||||
[
|
||||
'/{foo-bar}',
|
||||
[
|
||||
['/', ['foo-bar', '[^/]+']]
|
||||
]
|
||||
],
|
||||
[
|
||||
'/{_foo:.*}',
|
||||
[
|
||||
['/', ['_foo', '.*']]
|
||||
]
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
public function provideTestParseError()
|
||||
{
|
||||
return [
|
||||
[
|
||||
'/test[opt',
|
||||
"Number of opening '[' and closing ']' does not match"
|
||||
],
|
||||
[
|
||||
'/test[opt[opt2]',
|
||||
"Number of opening '[' and closing ']' does not match"
|
||||
],
|
||||
[
|
||||
'/testopt]',
|
||||
"Number of opening '[' and closing ']' does not match"
|
||||
],
|
||||
[
|
||||
'/test[]',
|
||||
'Empty optional part'
|
||||
],
|
||||
[
|
||||
'/test[[opt]]',
|
||||
'Empty optional part'
|
||||
],
|
||||
[
|
||||
'[[test]]',
|
||||
'Empty optional part'
|
||||
],
|
||||
[
|
||||
'/test[/opt]/required',
|
||||
'Optional segments can only occur at the end of a route'
|
||||
],
|
||||
];
|
||||
}
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
<?php
|
||||
|
||||
require_once __DIR__ . '/../src/functions.php';
|
||||
|
||||
spl_autoload_register(function ($class) {
|
||||
if (strpos($class, 'FastRoute\\') === 0) {
|
||||
$dir = strcasecmp(substr($class, -4), 'Test') ? 'src/' : 'test/';
|
||||
$name = substr($class, strlen('FastRoute'));
|
||||
require __DIR__ . '/../' . $dir . strtr($name, '\\', DIRECTORY_SEPARATOR) . '.php';
|
||||
}
|
||||
});
|
@ -0,0 +1,3 @@
|
||||
composer.lock
|
||||
composer.phar
|
||||
/vendor/
|
@ -0,0 +1,21 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2013-2016 container-interop
|
||||
Copyright (c) 2016 PHP Framework Interoperability Group
|
||||
|
||||
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.
|
@ -0,0 +1,13 @@
|
||||
Container interface
|
||||
==============
|
||||
|
||||
This repository holds all interfaces related to [PSR-11 (Container Interface)][psr-url].
|
||||
|
||||
Note that this is not a Container implementation of its own. It is merely abstractions that describe the components of a Dependency Injection Container.
|
||||
|
||||
The installable [package][package-url] and [implementations][implementation-url] are listed on Packagist.
|
||||
|
||||
[psr-url]: https://www.php-fig.org/psr/psr-11/
|
||||
[package-url]: https://packagist.org/packages/psr/container
|
||||
[implementation-url]: https://packagist.org/providers/psr/container-implementation
|
||||
|
@ -0,0 +1,27 @@
|
||||
{
|
||||
"name": "psr/container",
|
||||
"type": "library",
|
||||
"description": "Common Container Interface (PHP FIG PSR-11)",
|
||||
"keywords": ["psr", "psr-11", "container", "container-interop", "container-interface"],
|
||||
"homepage": "https://github.com/php-fig/container",
|
||||
"license": "MIT",
|
||||
"authors": [
|
||||
{
|
||||
"name": "PHP-FIG",
|
||||
"homepage": "https://www.php-fig.org/"
|
||||
}
|
||||
],
|
||||
"require": {
|
||||
"php": ">=7.4.0"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Psr\\Container\\": "src/"
|
||||
}
|
||||
},
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "2.0.x-dev"
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,12 @@
|
||||
<?php
|
||||
|
||||
namespace Psr\Container;
|
||||
|
||||
use Throwable;
|
||||
|
||||
/**
|
||||
* Base interface representing a generic exception in a container.
|
||||
*/
|
||||
interface ContainerExceptionInterface extends Throwable
|
||||
{
|
||||
}
|
@ -0,0 +1,36 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Psr\Container;
|
||||
|
||||
/**
|
||||
* Describes the interface of a container that exposes methods to read its entries.
|
||||
*/
|
||||
interface ContainerInterface
|
||||
{
|
||||
/**
|
||||
* Finds an entry of the container by its identifier and returns it.
|
||||
*
|
||||
* @param string $id Identifier of the entry to look for.
|
||||
*
|
||||
* @throws NotFoundExceptionInterface No entry was found for **this** identifier.
|
||||
* @throws ContainerExceptionInterface Error while retrieving the entry.
|
||||
*
|
||||
* @return mixed Entry.
|
||||
*/
|
||||
public function get(string $id);
|
||||
|
||||
/**
|
||||
* Returns true if the container can return an entry for the given identifier.
|
||||
* Returns false otherwise.
|
||||
*
|
||||
* `has($id)` returning true does not mean that `get($id)` will not throw an exception.
|
||||
* It does however mean that `get($id)` will not throw a `NotFoundExceptionInterface`.
|
||||
*
|
||||
* @param string $id Identifier of the entry to look for.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function has(string $id): bool;
|
||||
}
|
@ -0,0 +1,10 @@
|
||||
<?php
|
||||
|
||||
namespace Psr\Container;
|
||||
|
||||
/**
|
||||
* No entry was found in the container.
|
||||
*/
|
||||
interface NotFoundExceptionInterface extends ContainerExceptionInterface
|
||||
{
|
||||
}
|
@ -0,0 +1,2 @@
|
||||
composer.lock
|
||||
vendor/
|
@ -0,0 +1,7 @@
|
||||
extends: default
|
||||
reviewers:
|
||||
-
|
||||
name: contributors
|
||||
required: 1
|
||||
teams:
|
||||
- http-factory-contributors
|
@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2018 PHP-FIG
|
||||
|
||||
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.
|
@ -0,0 +1,10 @@
|
||||
HTTP Factories
|
||||
==============
|
||||
|
||||
This repository holds all interfaces related to [PSR-17 (HTTP Message Factories)][psr-17].
|
||||
Please refer to the specification for a description.
|
||||
|
||||
You can find implementations of the specification by looking for packages providing the
|
||||
[psr/http-factory-implementation](https://packagist.org/providers/psr/http-factory-implementation) virtual package.
|
||||
|
||||
[psr-17]: https://www.php-fig.org/psr/psr-17/
|
@ -0,0 +1,35 @@
|
||||
{
|
||||
"name": "psr/http-factory",
|
||||
"description": "Common interfaces for PSR-7 HTTP message factories",
|
||||
"keywords": [
|
||||
"psr",
|
||||
"psr-7",
|
||||
"psr-17",
|
||||
"http",
|
||||
"factory",
|
||||
"message",
|
||||
"request",
|
||||
"response"
|
||||
],
|
||||
"license": "MIT",
|
||||
"authors": [
|
||||
{
|
||||
"name": "PHP-FIG",
|
||||
"homepage": "http://www.php-fig.org/"
|
||||
}
|
||||
],
|
||||
"require": {
|
||||
"php": ">=7.0.0",
|
||||
"psr/http-message": "^1.0"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Psr\\Http\\Message\\": "src/"
|
||||
}
|
||||
},
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "1.0.x-dev"
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,18 @@
|
||||
<?php
|
||||
|
||||
namespace Psr\Http\Message;
|
||||
|
||||
interface RequestFactoryInterface
|
||||
{
|
||||
/**
|
||||
* Create a new request.
|
||||
*
|
||||
* @param string $method The HTTP method associated with the request.
|
||||
* @param UriInterface|string $uri The URI associated with the request. If
|
||||
* the value is a string, the factory MUST create a UriInterface
|
||||
* instance based on it.
|
||||
*
|
||||
* @return RequestInterface
|
||||
*/
|
||||
public function createRequest(string $method, $uri): RequestInterface;
|
||||
}
|
@ -0,0 +1,18 @@
|
||||
<?php
|
||||
|
||||
namespace Psr\Http\Message;
|
||||
|
||||
interface ResponseFactoryInterface
|
||||
{
|
||||
/**
|
||||
* Create a new response.
|
||||
*
|
||||
* @param int $code HTTP status code; defaults to 200
|
||||
* @param string $reasonPhrase Reason phrase to associate with status code
|
||||
* in generated response; if none is provided implementations MAY use
|
||||
* the defaults as suggested in the HTTP specification.
|
||||
*
|
||||
* @return ResponseInterface
|
||||
*/
|
||||
public function createResponse(int $code = 200, string $reasonPhrase = ''): ResponseInterface;
|
||||
}
|
@ -0,0 +1,24 @@
|
||||
<?php
|
||||
|
||||
namespace Psr\Http\Message;
|
||||
|
||||
interface ServerRequestFactoryInterface
|
||||
{
|
||||
/**
|
||||
* Create a new server request.
|
||||
*
|
||||
* Note that server-params are taken precisely as given - no parsing/processing
|
||||
* of the given values is performed, and, in particular, no attempt is made to
|
||||
* determine the HTTP method or URI, which must be provided explicitly.
|
||||
*
|
||||
* @param string $method The HTTP method associated with the request.
|
||||
* @param UriInterface|string $uri The URI associated with the request. If
|
||||
* the value is a string, the factory MUST create a UriInterface
|
||||
* instance based on it.
|
||||
* @param array $serverParams Array of SAPI parameters with which to seed
|
||||
* the generated request instance.
|
||||
*
|
||||
* @return ServerRequestInterface
|
||||
*/
|
||||
public function createServerRequest(string $method, $uri, array $serverParams = []): ServerRequestInterface;
|
||||
}
|
@ -0,0 +1,45 @@
|
||||
<?php
|
||||
|
||||
namespace Psr\Http\Message;
|
||||
|
||||
interface StreamFactoryInterface
|
||||
{
|
||||
/**
|
||||
* Create a new stream from a string.
|
||||
*
|
||||
* The stream SHOULD be created with a temporary resource.
|
||||
*
|
||||
* @param string $content String content with which to populate the stream.
|
||||
*
|
||||
* @return StreamInterface
|
||||
*/
|
||||
public function createStream(string $content = ''): StreamInterface;
|
||||
|
||||
/**
|
||||
* Create a stream from an existing file.
|
||||
*
|
||||
* The file MUST be opened using the given mode, which may be any mode
|
||||
* supported by the `fopen` function.
|
||||
*
|
||||
* The `$filename` MAY be any string supported by `fopen()`.
|
||||
*
|
||||
* @param string $filename Filename or stream URI to use as basis of stream.
|
||||
* @param string $mode Mode with which to open the underlying filename/stream.
|
||||
*
|
||||
* @return StreamInterface
|
||||
* @throws \RuntimeException If the file cannot be opened.
|
||||
* @throws \InvalidArgumentException If the mode is invalid.
|
||||
*/
|
||||
public function createStreamFromFile(string $filename, string $mode = 'r'): StreamInterface;
|
||||
|
||||
/**
|
||||
* Create a new stream from an existing resource.
|
||||
*
|
||||
* The stream MUST be readable and may be writable.
|
||||
*
|
||||
* @param resource $resource PHP resource to use as basis of stream.
|
||||
*
|
||||
* @return StreamInterface
|
||||
*/
|
||||
public function createStreamFromResource($resource): StreamInterface;
|
||||
}
|
@ -0,0 +1,34 @@
|
||||
<?php
|
||||
|
||||
namespace Psr\Http\Message;
|
||||
|
||||
interface UploadedFileFactoryInterface
|
||||
{
|
||||
/**
|
||||
* Create a new uploaded file.
|
||||
*
|
||||
* If a size is not provided it will be determined by checking the size of
|
||||
* the file.
|
||||
*
|
||||
* @see http://php.net/manual/features.file-upload.post-method.php
|
||||
* @see http://php.net/manual/features.file-upload.errors.php
|
||||
*
|
||||
* @param StreamInterface $stream Underlying stream representing the
|
||||
* uploaded file content.
|
||||
* @param int $size in bytes
|
||||
* @param int $error PHP file upload error
|
||||
* @param string $clientFilename Filename as provided by the client, if any.
|
||||
* @param string $clientMediaType Media type as provided by the client, if any.
|
||||
*
|
||||
* @return UploadedFileInterface
|
||||
*
|
||||
* @throws \InvalidArgumentException If the file resource is not readable.
|
||||
*/
|
||||
public function createUploadedFile(
|
||||
StreamInterface $stream,
|
||||
int $size = null,
|
||||
int $error = \UPLOAD_ERR_OK,
|
||||
string $clientFilename = null,
|
||||
string $clientMediaType = null
|
||||
): UploadedFileInterface;
|
||||
}
|
@ -0,0 +1,17 @@
|
||||
<?php
|
||||
|
||||
namespace Psr\Http\Message;
|
||||
|
||||
interface UriFactoryInterface
|
||||
{
|
||||
/**
|
||||
* Create a new URI.
|
||||
*
|
||||
* @param string $uri
|
||||
*
|
||||
* @return UriInterface
|
||||
*
|
||||
* @throws \InvalidArgumentException If the given URI cannot be parsed.
|
||||
*/
|
||||
public function createUri(string $uri = ''): UriInterface;
|
||||
}
|
@ -0,0 +1,36 @@
|
||||
# Changelog
|
||||
|
||||
All notable changes to this project will be documented in this file, in reverse chronological order by release.
|
||||
|
||||
## 1.0.1 - 2016-08-06
|
||||
|
||||
### Added
|
||||
|
||||
- Nothing.
|
||||
|
||||
### Deprecated
|
||||
|
||||
- Nothing.
|
||||
|
||||
### Removed
|
||||
|
||||
- Nothing.
|
||||
|
||||
### Fixed
|
||||
|
||||
- Updated all `@return self` annotation references in interfaces to use
|
||||
`@return static`, which more closelly follows the semantics of the
|
||||
specification.
|
||||
- Updated the `MessageInterface::getHeaders()` return annotation to use the
|
||||
value `string[][]`, indicating the format is a nested array of strings.
|
||||
- Updated the `@link` annotation for `RequestInterface::withRequestTarget()`
|
||||
to point to the correct section of RFC 7230.
|
||||
- Updated the `ServerRequestInterface::withUploadedFiles()` parameter annotation
|
||||
to add the parameter name (`$uploadedFiles`).
|
||||
- Updated a `@throws` annotation for the `UploadedFileInterface::moveTo()`
|
||||
method to correctly reference the method parameter (it was referencing an
|
||||
incorrect parameter name previously).
|
||||
|
||||
## 1.0.0 - 2016-05-18
|
||||
|
||||
Initial stable release; reflects accepted PSR-7 specification.
|
@ -0,0 +1,19 @@
|
||||
Copyright (c) 2014 PHP Framework Interoperability Group
|
||||
|
||||
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.
|
@ -0,0 +1,13 @@
|
||||
PSR Http Message
|
||||
================
|
||||
|
||||
This repository holds all interfaces/classes/traits related to
|
||||
[PSR-7](http://www.php-fig.org/psr/psr-7/).
|
||||
|
||||
Note that this is not a HTTP message implementation of its own. It is merely an
|
||||
interface that describes a HTTP message. See the specification for more details.
|
||||
|
||||
Usage
|
||||
-----
|
||||
|
||||
We'll certainly need some stuff in here.
|
@ -0,0 +1,26 @@
|
||||
{
|
||||
"name": "psr/http-message",
|
||||
"description": "Common interface for HTTP messages",
|
||||
"keywords": ["psr", "psr-7", "http", "http-message", "request", "response"],
|
||||
"homepage": "https://github.com/php-fig/http-message",
|
||||
"license": "MIT",
|
||||
"authors": [
|
||||
{
|
||||
"name": "PHP-FIG",
|
||||
"homepage": "http://www.php-fig.org/"
|
||||
}
|
||||
],
|
||||
"require": {
|
||||
"php": ">=5.3.0"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Psr\\Http\\Message\\": "src/"
|
||||
}
|
||||
},
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "1.0.x-dev"
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,187 @@
|
||||
<?php
|
||||
|
||||
namespace Psr\Http\Message;
|
||||
|
||||
/**
|
||||
* HTTP messages consist of requests from a client to a server and responses
|
||||
* from a server to a client. This interface defines the methods common to
|
||||
* each.
|
||||
*
|
||||
* Messages are considered immutable; all methods that might change state MUST
|
||||
* be implemented such that they retain the internal state of the current
|
||||
* message and return an instance that contains the changed state.
|
||||
*
|
||||
* @link http://www.ietf.org/rfc/rfc7230.txt
|
||||
* @link http://www.ietf.org/rfc/rfc7231.txt
|
||||
*/
|
||||
interface MessageInterface
|
||||
{
|
||||
/**
|
||||
* Retrieves the HTTP protocol version as a string.
|
||||
*
|
||||
* The string MUST contain only the HTTP version number (e.g., "1.1", "1.0").
|
||||
*
|
||||
* @return string HTTP protocol version.
|
||||
*/
|
||||
public function getProtocolVersion();
|
||||
|
||||
/**
|
||||
* Return an instance with the specified HTTP protocol version.
|
||||
*
|
||||
* The version string MUST contain only the HTTP version number (e.g.,
|
||||
* "1.1", "1.0").
|
||||
*
|
||||
* This method MUST be implemented in such a way as to retain the
|
||||
* immutability of the message, and MUST return an instance that has the
|
||||
* new protocol version.
|
||||
*
|
||||
* @param string $version HTTP protocol version
|
||||
* @return static
|
||||
*/
|
||||
public function withProtocolVersion($version);
|
||||
|
||||
/**
|
||||
* Retrieves all message header values.
|
||||
*
|
||||
* The keys represent the header name as it will be sent over the wire, and
|
||||
* each value is an array of strings associated with the header.
|
||||
*
|
||||
* // Represent the headers as a string
|
||||
* foreach ($message->getHeaders() as $name => $values) {
|
||||
* echo $name . ": " . implode(", ", $values);
|
||||
* }
|
||||
*
|
||||
* // Emit headers iteratively:
|
||||
* foreach ($message->getHeaders() as $name => $values) {
|
||||
* foreach ($values as $value) {
|
||||
* header(sprintf('%s: %s', $name, $value), false);
|
||||
* }
|
||||
* }
|
||||
*
|
||||
* While header names are not case-sensitive, getHeaders() will preserve the
|
||||
* exact case in which headers were originally specified.
|
||||
*
|
||||
* @return string[][] Returns an associative array of the message's headers. Each
|
||||
* key MUST be a header name, and each value MUST be an array of strings
|
||||
* for that header.
|
||||
*/
|
||||
public function getHeaders();
|
||||
|
||||
/**
|
||||
* Checks if a header exists by the given case-insensitive name.
|
||||
*
|
||||
* @param string $name Case-insensitive header field name.
|
||||
* @return bool Returns true if any header names match the given header
|
||||
* name using a case-insensitive string comparison. Returns false if
|
||||
* no matching header name is found in the message.
|
||||
*/
|
||||
public function hasHeader($name);
|
||||
|
||||
/**
|
||||
* Retrieves a message header value by the given case-insensitive name.
|
||||
*
|
||||
* This method returns an array of all the header values of the given
|
||||
* case-insensitive header name.
|
||||
*
|
||||
* If the header does not appear in the message, this method MUST return an
|
||||
* empty array.
|
||||
*
|
||||
* @param string $name Case-insensitive header field name.
|
||||
* @return string[] An array of string values as provided for the given
|
||||
* header. If the header does not appear in the message, this method MUST
|
||||
* return an empty array.
|
||||
*/
|
||||
public function getHeader($name);
|
||||
|
||||
/**
|
||||
* Retrieves a comma-separated string of the values for a single header.
|
||||
*
|
||||
* This method returns all of the header values of the given
|
||||
* case-insensitive header name as a string concatenated together using
|
||||
* a comma.
|
||||
*
|
||||
* NOTE: Not all header values may be appropriately represented using
|
||||
* comma concatenation. For such headers, use getHeader() instead
|
||||
* and supply your own delimiter when concatenating.
|
||||
*
|
||||
* If the header does not appear in the message, this method MUST return
|
||||
* an empty string.
|
||||
*
|
||||
* @param string $name Case-insensitive header field name.
|
||||
* @return string A string of values as provided for the given header
|
||||
* concatenated together using a comma. If the header does not appear in
|
||||
* the message, this method MUST return an empty string.
|
||||
*/
|
||||
public function getHeaderLine($name);
|
||||
|
||||
/**
|
||||
* Return an instance with the provided value replacing the specified header.
|
||||
*
|
||||
* While header names are case-insensitive, the casing of the header will
|
||||
* be preserved by this function, and returned from getHeaders().
|
||||
*
|
||||
* This method MUST be implemented in such a way as to retain the
|
||||
* immutability of the message, and MUST return an instance that has the
|
||||
* new and/or updated header and value.
|
||||
*
|
||||
* @param string $name Case-insensitive header field name.
|
||||
* @param string|string[] $value Header value(s).
|
||||
* @return static
|
||||
* @throws \InvalidArgumentException for invalid header names or values.
|
||||
*/
|
||||
public function withHeader($name, $value);
|
||||
|
||||
/**
|
||||
* Return an instance with the specified header appended with the given value.
|
||||
*
|
||||
* Existing values for the specified header will be maintained. The new
|
||||
* value(s) will be appended to the existing list. If the header did not
|
||||
* exist previously, it will be added.
|
||||
*
|
||||
* This method MUST be implemented in such a way as to retain the
|
||||
* immutability of the message, and MUST return an instance that has the
|
||||
* new header and/or value.
|
||||
*
|
||||
* @param string $name Case-insensitive header field name to add.
|
||||
* @param string|string[] $value Header value(s).
|
||||
* @return static
|
||||
* @throws \InvalidArgumentException for invalid header names or values.
|
||||
*/
|
||||
public function withAddedHeader($name, $value);
|
||||
|
||||
/**
|
||||
* Return an instance without the specified header.
|
||||
*
|
||||
* Header resolution MUST be done without case-sensitivity.
|
||||
*
|
||||
* This method MUST be implemented in such a way as to retain the
|
||||
* immutability of the message, and MUST return an instance that removes
|
||||
* the named header.
|
||||
*
|
||||
* @param string $name Case-insensitive header field name to remove.
|
||||
* @return static
|
||||
*/
|
||||
public function withoutHeader($name);
|
||||
|
||||
/**
|
||||
* Gets the body of the message.
|
||||
*
|
||||
* @return StreamInterface Returns the body as a stream.
|
||||
*/
|
||||
public function getBody();
|
||||
|
||||
/**
|
||||
* Return an instance with the specified message body.
|
||||
*
|
||||
* The body MUST be a StreamInterface object.
|
||||
*
|
||||
* This method MUST be implemented in such a way as to retain the
|
||||
* immutability of the message, and MUST return a new instance that has the
|
||||
* new body stream.
|
||||
*
|
||||
* @param StreamInterface $body Body.
|
||||
* @return static
|
||||
* @throws \InvalidArgumentException When the body is not valid.
|
||||
*/
|
||||
public function withBody(StreamInterface $body);
|
||||
}
|
@ -0,0 +1,129 @@
|
||||
<?php
|
||||
|
||||
namespace Psr\Http\Message;
|
||||
|
||||
/**
|
||||
* Representation of an outgoing, client-side request.
|
||||
*
|
||||
* Per the HTTP specification, this interface includes properties for
|
||||
* each of the following:
|
||||
*
|
||||
* - Protocol version
|
||||
* - HTTP method
|
||||
* - URI
|
||||
* - Headers
|
||||
* - Message body
|
||||
*
|
||||
* During construction, implementations MUST attempt to set the Host header from
|
||||
* a provided URI if no Host header is provided.
|
||||
*
|
||||
* Requests are considered immutable; all methods that might change state MUST
|
||||
* be implemented such that they retain the internal state of the current
|
||||
* message and return an instance that contains the changed state.
|
||||
*/
|
||||
interface RequestInterface extends MessageInterface
|
||||
{
|
||||
/**
|
||||
* Retrieves the message's request target.
|
||||
*
|
||||
* Retrieves the message's request-target either as it will appear (for
|
||||
* clients), as it appeared at request (for servers), or as it was
|
||||
* specified for the instance (see withRequestTarget()).
|
||||
*
|
||||
* In most cases, this will be the origin-form of the composed URI,
|
||||
* unless a value was provided to the concrete implementation (see
|
||||
* withRequestTarget() below).
|
||||
*
|
||||
* If no URI is available, and no request-target has been specifically
|
||||
* provided, this method MUST return the string "/".
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getRequestTarget();
|
||||
|
||||
/**
|
||||
* Return an instance with the specific request-target.
|
||||
*
|
||||
* If the request needs a non-origin-form request-target — e.g., for
|
||||
* specifying an absolute-form, authority-form, or asterisk-form —
|
||||
* this method may be used to create an instance with the specified
|
||||
* request-target, verbatim.
|
||||
*
|
||||
* This method MUST be implemented in such a way as to retain the
|
||||
* immutability of the message, and MUST return an instance that has the
|
||||
* changed request target.
|
||||
*
|
||||
* @link http://tools.ietf.org/html/rfc7230#section-5.3 (for the various
|
||||
* request-target forms allowed in request messages)
|
||||
* @param mixed $requestTarget
|
||||
* @return static
|
||||
*/
|
||||
public function withRequestTarget($requestTarget);
|
||||
|
||||
/**
|
||||
* Retrieves the HTTP method of the request.
|
||||
*
|
||||
* @return string Returns the request method.
|
||||
*/
|
||||
public function getMethod();
|
||||
|
||||
/**
|
||||
* Return an instance with the provided HTTP method.
|
||||
*
|
||||
* While HTTP method names are typically all uppercase characters, HTTP
|
||||
* method names are case-sensitive and thus implementations SHOULD NOT
|
||||
* modify the given string.
|
||||
*
|
||||
* This method MUST be implemented in such a way as to retain the
|
||||
* immutability of the message, and MUST return an instance that has the
|
||||
* changed request method.
|
||||
*
|
||||
* @param string $method Case-sensitive method.
|
||||
* @return static
|
||||
* @throws \InvalidArgumentException for invalid HTTP methods.
|
||||
*/
|
||||
public function withMethod($method);
|
||||
|
||||
/**
|
||||
* Retrieves the URI instance.
|
||||
*
|
||||
* This method MUST return a UriInterface instance.
|
||||
*
|
||||
* @link http://tools.ietf.org/html/rfc3986#section-4.3
|
||||
* @return UriInterface Returns a UriInterface instance
|
||||
* representing the URI of the request.
|
||||
*/
|
||||
public function getUri();
|
||||
|
||||
/**
|
||||
* Returns an instance with the provided URI.
|
||||
*
|
||||
* This method MUST update the Host header of the returned request by
|
||||
* default if the URI contains a host component. If the URI does not
|
||||
* contain a host component, any pre-existing Host header MUST be carried
|
||||
* over to the returned request.
|
||||
*
|
||||
* You can opt-in to preserving the original state of the Host header by
|
||||
* setting `$preserveHost` to `true`. When `$preserveHost` is set to
|
||||
* `true`, this method interacts with the Host header in the following ways:
|
||||
*
|
||||
* - If the Host header is missing or empty, and the new URI contains
|
||||
* a host component, this method MUST update the Host header in the returned
|
||||
* request.
|
||||
* - If the Host header is missing or empty, and the new URI does not contain a
|
||||
* host component, this method MUST NOT update the Host header in the returned
|
||||
* request.
|
||||
* - If a Host header is present and non-empty, this method MUST NOT update
|
||||
* the Host header in the returned request.
|
||||
*
|
||||
* This method MUST be implemented in such a way as to retain the
|
||||
* immutability of the message, and MUST return an instance that has the
|
||||
* new UriInterface instance.
|
||||
*
|
||||
* @link http://tools.ietf.org/html/rfc3986#section-4.3
|
||||
* @param UriInterface $uri New request URI to use.
|
||||
* @param bool $preserveHost Preserve the original state of the Host header.
|
||||
* @return static
|
||||
*/
|
||||
public function withUri(UriInterface $uri, $preserveHost = false);
|
||||
}
|
@ -0,0 +1,68 @@
|
||||
<?php
|
||||
|
||||
namespace Psr\Http\Message;
|
||||
|
||||
/**
|
||||
* Representation of an outgoing, server-side response.
|
||||
*
|
||||
* Per the HTTP specification, this interface includes properties for
|
||||
* each of the following:
|
||||
*
|
||||
* - Protocol version
|
||||
* - Status code and reason phrase
|
||||
* - Headers
|
||||
* - Message body
|
||||
*
|
||||
* Responses are considered immutable; all methods that might change state MUST
|
||||
* be implemented such that they retain the internal state of the current
|
||||
* message and return an instance that contains the changed state.
|
||||
*/
|
||||
interface ResponseInterface extends MessageInterface
|
||||
{
|
||||
/**
|
||||
* Gets the response status code.
|
||||
*
|
||||
* The status code is a 3-digit integer result code of the server's attempt
|
||||
* to understand and satisfy the request.
|
||||
*
|
||||
* @return int Status code.
|
||||
*/
|
||||
public function getStatusCode();
|
||||
|
||||
/**
|
||||
* Return an instance with the specified status code and, optionally, reason phrase.
|
||||
*
|
||||
* If no reason phrase is specified, implementations MAY choose to default
|
||||
* to the RFC 7231 or IANA recommended reason phrase for the response's
|
||||
* status code.
|
||||
*
|
||||
* This method MUST be implemented in such a way as to retain the
|
||||
* immutability of the message, and MUST return an instance that has the
|
||||
* updated status and reason phrase.
|
||||
*
|
||||
* @link http://tools.ietf.org/html/rfc7231#section-6
|
||||
* @link http://www.iana.org/assignments/http-status-codes/http-status-codes.xhtml
|
||||
* @param int $code The 3-digit integer result code to set.
|
||||
* @param string $reasonPhrase The reason phrase to use with the
|
||||
* provided status code; if none is provided, implementations MAY
|
||||
* use the defaults as suggested in the HTTP specification.
|
||||
* @return static
|
||||
* @throws \InvalidArgumentException For invalid status code arguments.
|
||||
*/
|
||||
public function withStatus($code, $reasonPhrase = '');
|
||||
|
||||
/**
|
||||
* Gets the response reason phrase associated with the status code.
|
||||
*
|
||||
* Because a reason phrase is not a required element in a response
|
||||
* status line, the reason phrase value MAY be null. Implementations MAY
|
||||
* choose to return the default RFC 7231 recommended reason phrase (or those
|
||||
* listed in the IANA HTTP Status Code Registry) for the response's
|
||||
* status code.
|
||||
*
|
||||
* @link http://tools.ietf.org/html/rfc7231#section-6
|
||||
* @link http://www.iana.org/assignments/http-status-codes/http-status-codes.xhtml
|
||||
* @return string Reason phrase; must return an empty string if none present.
|
||||
*/
|
||||
public function getReasonPhrase();
|
||||
}
|
@ -0,0 +1,261 @@
|
||||
<?php
|
||||
|
||||
namespace Psr\Http\Message;
|
||||
|
||||
/**
|
||||
* Representation of an incoming, server-side HTTP request.
|
||||
*
|
||||
* Per the HTTP specification, this interface includes properties for
|
||||
* each of the following:
|
||||
*
|
||||
* - Protocol version
|
||||
* - HTTP method
|
||||
* - URI
|
||||
* - Headers
|
||||
* - Message body
|
||||
*
|
||||
* Additionally, it encapsulates all data as it has arrived to the
|
||||
* application from the CGI and/or PHP environment, including:
|
||||
*
|
||||
* - The values represented in $_SERVER.
|
||||
* - Any cookies provided (generally via $_COOKIE)
|
||||
* - Query string arguments (generally via $_GET, or as parsed via parse_str())
|
||||
* - Upload files, if any (as represented by $_FILES)
|
||||
* - Deserialized body parameters (generally from $_POST)
|
||||
*
|
||||
* $_SERVER values MUST be treated as immutable, as they represent application
|
||||
* state at the time of request; as such, no methods are provided to allow
|
||||
* modification of those values. The other values provide such methods, as they
|
||||
* can be restored from $_SERVER or the request body, and may need treatment
|
||||
* during the application (e.g., body parameters may be deserialized based on
|
||||
* content type).
|
||||
*
|
||||
* Additionally, this interface recognizes the utility of introspecting a
|
||||
* request to derive and match additional parameters (e.g., via URI path
|
||||
* matching, decrypting cookie values, deserializing non-form-encoded body
|
||||
* content, matching authorization headers to users, etc). These parameters
|
||||
* are stored in an "attributes" property.
|
||||
*
|
||||
* Requests are considered immutable; all methods that might change state MUST
|
||||
* be implemented such that they retain the internal state of the current
|
||||
* message and return an instance that contains the changed state.
|
||||
*/
|
||||
interface ServerRequestInterface extends RequestInterface
|
||||
{
|
||||
/**
|
||||
* Retrieve server parameters.
|
||||
*
|
||||
* Retrieves data related to the incoming request environment,
|
||||
* typically derived from PHP's $_SERVER superglobal. The data IS NOT
|
||||
* REQUIRED to originate from $_SERVER.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getServerParams();
|
||||
|
||||
/**
|
||||
* Retrieve cookies.
|
||||
*
|
||||
* Retrieves cookies sent by the client to the server.
|
||||
*
|
||||
* The data MUST be compatible with the structure of the $_COOKIE
|
||||
* superglobal.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getCookieParams();
|
||||
|
||||
/**
|
||||
* Return an instance with the specified cookies.
|
||||
*
|
||||
* The data IS NOT REQUIRED to come from the $_COOKIE superglobal, but MUST
|
||||
* be compatible with the structure of $_COOKIE. Typically, this data will
|
||||
* be injected at instantiation.
|
||||
*
|
||||
* This method MUST NOT update the related Cookie header of the request
|
||||
* instance, nor related values in the server params.
|
||||
*
|
||||
* This method MUST be implemented in such a way as to retain the
|
||||
* immutability of the message, and MUST return an instance that has the
|
||||
* updated cookie values.
|
||||
*
|
||||
* @param array $cookies Array of key/value pairs representing cookies.
|
||||
* @return static
|
||||
*/
|
||||
public function withCookieParams(array $cookies);
|
||||
|
||||
/**
|
||||
* Retrieve query string arguments.
|
||||
*
|
||||
* Retrieves the deserialized query string arguments, if any.
|
||||
*
|
||||
* Note: the query params might not be in sync with the URI or server
|
||||
* params. If you need to ensure you are only getting the original
|
||||
* values, you may need to parse the query string from `getUri()->getQuery()`
|
||||
* or from the `QUERY_STRING` server param.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getQueryParams();
|
||||
|
||||
/**
|
||||
* Return an instance with the specified query string arguments.
|
||||
*
|
||||
* These values SHOULD remain immutable over the course of the incoming
|
||||
* request. They MAY be injected during instantiation, such as from PHP's
|
||||
* $_GET superglobal, or MAY be derived from some other value such as the
|
||||
* URI. In cases where the arguments are parsed from the URI, the data
|
||||
* MUST be compatible with what PHP's parse_str() would return for
|
||||
* purposes of how duplicate query parameters are handled, and how nested
|
||||
* sets are handled.
|
||||
*
|
||||
* Setting query string arguments MUST NOT change the URI stored by the
|
||||
* request, nor the values in the server params.
|
||||
*
|
||||
* This method MUST be implemented in such a way as to retain the
|
||||
* immutability of the message, and MUST return an instance that has the
|
||||
* updated query string arguments.
|
||||
*
|
||||
* @param array $query Array of query string arguments, typically from
|
||||
* $_GET.
|
||||
* @return static
|
||||
*/
|
||||
public function withQueryParams(array $query);
|
||||
|
||||
/**
|
||||
* Retrieve normalized file upload data.
|
||||
*
|
||||
* This method returns upload metadata in a normalized tree, with each leaf
|
||||
* an instance of Psr\Http\Message\UploadedFileInterface.
|
||||
*
|
||||
* These values MAY be prepared from $_FILES or the message body during
|
||||
* instantiation, or MAY be injected via withUploadedFiles().
|
||||
*
|
||||
* @return array An array tree of UploadedFileInterface instances; an empty
|
||||
* array MUST be returned if no data is present.
|
||||
*/
|
||||
public function getUploadedFiles();
|
||||
|
||||
/**
|
||||
* Create a new instance with the specified uploaded files.
|
||||
*
|
||||
* This method MUST be implemented in such a way as to retain the
|
||||
* immutability of the message, and MUST return an instance that has the
|
||||
* updated body parameters.
|
||||
*
|
||||
* @param array $uploadedFiles An array tree of UploadedFileInterface instances.
|
||||
* @return static
|
||||
* @throws \InvalidArgumentException if an invalid structure is provided.
|
||||
*/
|
||||
public function withUploadedFiles(array $uploadedFiles);
|
||||
|
||||
/**
|
||||
* Retrieve any parameters provided in the request body.
|
||||
*
|
||||
* If the request Content-Type is either application/x-www-form-urlencoded
|
||||
* or multipart/form-data, and the request method is POST, this method MUST
|
||||
* return the contents of $_POST.
|
||||
*
|
||||
* Otherwise, this method may return any results of deserializing
|
||||
* the request body content; as parsing returns structured content, the
|
||||
* potential types MUST be arrays or objects only. A null value indicates
|
||||
* the absence of body content.
|
||||
*
|
||||
* @return null|array|object The deserialized body parameters, if any.
|
||||
* These will typically be an array or object.
|
||||
*/
|
||||
public function getParsedBody();
|
||||
|
||||
/**
|
||||
* Return an instance with the specified body parameters.
|
||||
*
|
||||
* These MAY be injected during instantiation.
|
||||
*
|
||||
* If the request Content-Type is either application/x-www-form-urlencoded
|
||||
* or multipart/form-data, and the request method is POST, use this method
|
||||
* ONLY to inject the contents of $_POST.
|
||||
*
|
||||
* The data IS NOT REQUIRED to come from $_POST, but MUST be the results of
|
||||
* deserializing the request body content. Deserialization/parsing returns
|
||||
* structured data, and, as such, this method ONLY accepts arrays or objects,
|
||||
* or a null value if nothing was available to parse.
|
||||
*
|
||||
* As an example, if content negotiation determines that the request data
|
||||
* is a JSON payload, this method could be used to create a request
|
||||
* instance with the deserialized parameters.
|
||||
*
|
||||
* This method MUST be implemented in such a way as to retain the
|
||||
* immutability of the message, and MUST return an instance that has the
|
||||
* updated body parameters.
|
||||
*
|
||||
* @param null|array|object $data The deserialized body data. This will
|
||||
* typically be in an array or object.
|
||||
* @return static
|
||||
* @throws \InvalidArgumentException if an unsupported argument type is
|
||||
* provided.
|
||||
*/
|
||||
public function withParsedBody($data);
|
||||
|
||||
/**
|
||||
* Retrieve attributes derived from the request.
|
||||
*
|
||||
* The request "attributes" may be used to allow injection of any
|
||||
* parameters derived from the request: e.g., the results of path
|
||||
* match operations; the results of decrypting cookies; the results of
|
||||
* deserializing non-form-encoded message bodies; etc. Attributes
|
||||
* will be application and request specific, and CAN be mutable.
|
||||
*
|
||||
* @return array Attributes derived from the request.
|
||||
*/
|
||||
public function getAttributes();
|
||||
|
||||
/**
|
||||
* Retrieve a single derived request attribute.
|
||||
*
|
||||
* Retrieves a single derived request attribute as described in
|
||||
* getAttributes(). If the attribute has not been previously set, returns
|
||||
* the default value as provided.
|
||||
*
|
||||
* This method obviates the need for a hasAttribute() method, as it allows
|
||||
* specifying a default value to return if the attribute is not found.
|
||||
*
|
||||
* @see getAttributes()
|
||||
* @param string $name The attribute name.
|
||||
* @param mixed $default Default value to return if the attribute does not exist.
|
||||
* @return mixed
|
||||
*/
|
||||
public function getAttribute($name, $default = null);
|
||||
|
||||
/**
|
||||
* Return an instance with the specified derived request attribute.
|
||||
*
|
||||
* This method allows setting a single derived request attribute as
|
||||
* described in getAttributes().
|
||||
*
|
||||
* This method MUST be implemented in such a way as to retain the
|
||||
* immutability of the message, and MUST return an instance that has the
|
||||
* updated attribute.
|
||||
*
|
||||
* @see getAttributes()
|
||||
* @param string $name The attribute name.
|
||||
* @param mixed $value The value of the attribute.
|
||||
* @return static
|
||||
*/
|
||||
public function withAttribute($name, $value);
|
||||
|
||||
/**
|
||||
* Return an instance that removes the specified derived request attribute.
|
||||
*
|
||||
* This method allows removing a single derived request attribute as
|
||||
* described in getAttributes().
|
||||
*
|
||||
* This method MUST be implemented in such a way as to retain the
|
||||
* immutability of the message, and MUST return an instance that removes
|
||||
* the attribute.
|
||||
*
|
||||
* @see getAttributes()
|
||||
* @param string $name The attribute name.
|
||||
* @return static
|
||||
*/
|
||||
public function withoutAttribute($name);
|
||||
}
|
@ -0,0 +1,158 @@
|
||||
<?php
|
||||
|
||||
namespace Psr\Http\Message;
|
||||
|
||||
/**
|
||||
* Describes a data stream.
|
||||
*
|
||||
* Typically, an instance will wrap a PHP stream; this interface provides
|
||||
* a wrapper around the most common operations, including serialization of
|
||||
* the entire stream to a string.
|
||||
*/
|
||||
interface StreamInterface
|
||||
{
|
||||
/**
|
||||
* Reads all data from the stream into a string, from the beginning to end.
|
||||
*
|
||||
* This method MUST attempt to seek to the beginning of the stream before
|
||||
* reading data and read the stream until the end is reached.
|
||||
*
|
||||
* Warning: This could attempt to load a large amount of data into memory.
|
||||
*
|
||||
* This method MUST NOT raise an exception in order to conform with PHP's
|
||||
* string casting operations.
|
||||
*
|
||||
* @see http://php.net/manual/en/language.oop5.magic.php#object.tostring
|
||||
* @return string
|
||||
*/
|
||||
public function __toString();
|
||||
|
||||
/**
|
||||
* Closes the stream and any underlying resources.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function close();
|
||||
|
||||
/**
|
||||
* Separates any underlying resources from the stream.
|
||||
*
|
||||
* After the stream has been detached, the stream is in an unusable state.
|
||||
*
|
||||
* @return resource|null Underlying PHP stream, if any
|
||||
*/
|
||||
public function detach();
|
||||
|
||||
/**
|
||||
* Get the size of the stream if known.
|
||||
*
|
||||
* @return int|null Returns the size in bytes if known, or null if unknown.
|
||||
*/
|
||||
public function getSize();
|
||||
|
||||
/**
|
||||
* Returns the current position of the file read/write pointer
|
||||
*
|
||||
* @return int Position of the file pointer
|
||||
* @throws \RuntimeException on error.
|
||||
*/
|
||||
public function tell();
|
||||
|
||||
/**
|
||||
* Returns true if the stream is at the end of the stream.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function eof();
|
||||
|
||||
/**
|
||||
* Returns whether or not the stream is seekable.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isSeekable();
|
||||
|
||||
/**
|
||||
* Seek to a position in the stream.
|
||||
*
|
||||
* @link http://www.php.net/manual/en/function.fseek.php
|
||||
* @param int $offset Stream offset
|
||||
* @param int $whence Specifies how the cursor position will be calculated
|
||||
* based on the seek offset. Valid values are identical to the built-in
|
||||
* PHP $whence values for `fseek()`. SEEK_SET: Set position equal to
|
||||
* offset bytes SEEK_CUR: Set position to current location plus offset
|
||||
* SEEK_END: Set position to end-of-stream plus offset.
|
||||
* @throws \RuntimeException on failure.
|
||||
*/
|
||||
public function seek($offset, $whence = SEEK_SET);
|
||||
|
||||
/**
|
||||
* Seek to the beginning of the stream.
|
||||
*
|
||||
* If the stream is not seekable, this method will raise an exception;
|
||||
* otherwise, it will perform a seek(0).
|
||||
*
|
||||
* @see seek()
|
||||
* @link http://www.php.net/manual/en/function.fseek.php
|
||||
* @throws \RuntimeException on failure.
|
||||
*/
|
||||
public function rewind();
|
||||
|
||||
/**
|
||||
* Returns whether or not the stream is writable.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isWritable();
|
||||
|
||||
/**
|
||||
* Write data to the stream.
|
||||
*
|
||||
* @param string $string The string that is to be written.
|
||||
* @return int Returns the number of bytes written to the stream.
|
||||
* @throws \RuntimeException on failure.
|
||||
*/
|
||||
public function write($string);
|
||||
|
||||
/**
|
||||
* Returns whether or not the stream is readable.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isReadable();
|
||||
|
||||
/**
|
||||
* Read data from the stream.
|
||||
*
|
||||
* @param int $length Read up to $length bytes from the object and return
|
||||
* them. Fewer than $length bytes may be returned if underlying stream
|
||||
* call returns fewer bytes.
|
||||
* @return string Returns the data read from the stream, or an empty string
|
||||
* if no bytes are available.
|
||||
* @throws \RuntimeException if an error occurs.
|
||||
*/
|
||||
public function read($length);
|
||||
|
||||
/**
|
||||
* Returns the remaining contents in a string
|
||||
*
|
||||
* @return string
|
||||
* @throws \RuntimeException if unable to read or an error occurs while
|
||||
* reading.
|
||||
*/
|
||||
public function getContents();
|
||||
|
||||
/**
|
||||
* Get stream metadata as an associative array or retrieve a specific key.
|
||||
*
|
||||
* The keys returned are identical to the keys returned from PHP's
|
||||
* stream_get_meta_data() function.
|
||||
*
|
||||
* @link http://php.net/manual/en/function.stream-get-meta-data.php
|
||||
* @param string $key Specific metadata to retrieve.
|
||||
* @return array|mixed|null Returns an associative array if no key is
|
||||
* provided. Returns a specific key value if a key is provided and the
|
||||
* value is found, or null if the key is not found.
|
||||
*/
|
||||
public function getMetadata($key = null);
|
||||
}
|
@ -0,0 +1,123 @@
|
||||
<?php
|
||||
|
||||
namespace Psr\Http\Message;
|
||||
|
||||
/**
|
||||
* Value object representing a file uploaded through an HTTP request.
|
||||
*
|
||||
* Instances of this interface are considered immutable; all methods that
|
||||
* might change state MUST be implemented such that they retain the internal
|
||||
* state of the current instance and return an instance that contains the
|
||||
* changed state.
|
||||
*/
|
||||
interface UploadedFileInterface
|
||||
{
|
||||
/**
|
||||
* Retrieve a stream representing the uploaded file.
|
||||
*
|
||||
* This method MUST return a StreamInterface instance, representing the
|
||||
* uploaded file. The purpose of this method is to allow utilizing native PHP
|
||||
* stream functionality to manipulate the file upload, such as
|
||||
* stream_copy_to_stream() (though the result will need to be decorated in a
|
||||
* native PHP stream wrapper to work with such functions).
|
||||
*
|
||||
* If the moveTo() method has been called previously, this method MUST raise
|
||||
* an exception.
|
||||
*
|
||||
* @return StreamInterface Stream representation of the uploaded file.
|
||||
* @throws \RuntimeException in cases when no stream is available or can be
|
||||
* created.
|
||||
*/
|
||||
public function getStream();
|
||||
|
||||
/**
|
||||
* Move the uploaded file to a new location.
|
||||
*
|
||||
* Use this method as an alternative to move_uploaded_file(). This method is
|
||||
* guaranteed to work in both SAPI and non-SAPI environments.
|
||||
* Implementations must determine which environment they are in, and use the
|
||||
* appropriate method (move_uploaded_file(), rename(), or a stream
|
||||
* operation) to perform the operation.
|
||||
*
|
||||
* $targetPath may be an absolute path, or a relative path. If it is a
|
||||
* relative path, resolution should be the same as used by PHP's rename()
|
||||
* function.
|
||||
*
|
||||
* The original file or stream MUST be removed on completion.
|
||||
*
|
||||
* If this method is called more than once, any subsequent calls MUST raise
|
||||
* an exception.
|
||||
*
|
||||
* When used in an SAPI environment where $_FILES is populated, when writing
|
||||
* files via moveTo(), is_uploaded_file() and move_uploaded_file() SHOULD be
|
||||
* used to ensure permissions and upload status are verified correctly.
|
||||
*
|
||||
* If you wish to move to a stream, use getStream(), as SAPI operations
|
||||
* cannot guarantee writing to stream destinations.
|
||||
*
|
||||
* @see http://php.net/is_uploaded_file
|
||||
* @see http://php.net/move_uploaded_file
|
||||
* @param string $targetPath Path to which to move the uploaded file.
|
||||
* @throws \InvalidArgumentException if the $targetPath specified is invalid.
|
||||
* @throws \RuntimeException on any error during the move operation, or on
|
||||
* the second or subsequent call to the method.
|
||||
*/
|
||||
public function moveTo($targetPath);
|
||||
|
||||
/**
|
||||
* Retrieve the file size.
|
||||
*
|
||||
* Implementations SHOULD return the value stored in the "size" key of
|
||||
* the file in the $_FILES array if available, as PHP calculates this based
|
||||
* on the actual size transmitted.
|
||||
*
|
||||
* @return int|null The file size in bytes or null if unknown.
|
||||
*/
|
||||
public function getSize();
|
||||
|
||||
/**
|
||||
* Retrieve the error associated with the uploaded file.
|
||||
*
|
||||
* The return value MUST be one of PHP's UPLOAD_ERR_XXX constants.
|
||||
*
|
||||
* If the file was uploaded successfully, this method MUST return
|
||||
* UPLOAD_ERR_OK.
|
||||
*
|
||||
* Implementations SHOULD return the value stored in the "error" key of
|
||||
* the file in the $_FILES array.
|
||||
*
|
||||
* @see http://php.net/manual/en/features.file-upload.errors.php
|
||||
* @return int One of PHP's UPLOAD_ERR_XXX constants.
|
||||
*/
|
||||
public function getError();
|
||||
|
||||
/**
|
||||
* Retrieve the filename sent by the client.
|
||||
*
|
||||
* Do not trust the value returned by this method. A client could send
|
||||
* a malicious filename with the intention to corrupt or hack your
|
||||
* application.
|
||||
*
|
||||
* Implementations SHOULD return the value stored in the "name" key of
|
||||
* the file in the $_FILES array.
|
||||
*
|
||||
* @return string|null The filename sent by the client or null if none
|
||||
* was provided.
|
||||
*/
|
||||
public function getClientFilename();
|
||||
|
||||
/**
|
||||
* Retrieve the media type sent by the client.
|
||||
*
|
||||
* Do not trust the value returned by this method. A client could send
|
||||
* a malicious media type with the intention to corrupt or hack your
|
||||
* application.
|
||||
*
|
||||
* Implementations SHOULD return the value stored in the "type" key of
|
||||
* the file in the $_FILES array.
|
||||
*
|
||||
* @return string|null The media type sent by the client or null if none
|
||||
* was provided.
|
||||
*/
|
||||
public function getClientMediaType();
|
||||
}
|
@ -0,0 +1,323 @@
|
||||
<?php
|
||||
namespace Psr\Http\Message;
|
||||
|
||||
/**
|
||||
* Value object representing a URI.
|
||||
*
|
||||
* This interface is meant to represent URIs according to RFC 3986 and to
|
||||
* provide methods for most common operations. Additional functionality for
|
||||
* working with URIs can be provided on top of the interface or externally.
|
||||
* Its primary use is for HTTP requests, but may also be used in other
|
||||
* contexts.
|
||||
*
|
||||
* Instances of this interface are considered immutable; all methods that
|
||||
* might change state MUST be implemented such that they retain the internal
|
||||
* state of the current instance and return an instance that contains the
|
||||
* changed state.
|
||||
*
|
||||
* Typically the Host header will be also be present in the request message.
|
||||
* For server-side requests, the scheme will typically be discoverable in the
|
||||
* server parameters.
|
||||
*
|
||||
* @link http://tools.ietf.org/html/rfc3986 (the URI specification)
|
||||
*/
|
||||
interface UriInterface
|
||||
{
|
||||
/**
|
||||
* Retrieve the scheme component of the URI.
|
||||
*
|
||||
* If no scheme is present, this method MUST return an empty string.
|
||||
*
|
||||
* The value returned MUST be normalized to lowercase, per RFC 3986
|
||||
* Section 3.1.
|
||||
*
|
||||
* The trailing ":" character is not part of the scheme and MUST NOT be
|
||||
* added.
|
||||
*
|
||||
* @see https://tools.ietf.org/html/rfc3986#section-3.1
|
||||
* @return string The URI scheme.
|
||||
*/
|
||||
public function getScheme();
|
||||
|
||||
/**
|
||||
* Retrieve the authority component of the URI.
|
||||
*
|
||||
* If no authority information is present, this method MUST return an empty
|
||||
* string.
|
||||
*
|
||||
* The authority syntax of the URI is:
|
||||
*
|
||||
* <pre>
|
||||
* [user-info@]host[:port]
|
||||
* </pre>
|
||||
*
|
||||
* If the port component is not set or is the standard port for the current
|
||||
* scheme, it SHOULD NOT be included.
|
||||
*
|
||||
* @see https://tools.ietf.org/html/rfc3986#section-3.2
|
||||
* @return string The URI authority, in "[user-info@]host[:port]" format.
|
||||
*/
|
||||
public function getAuthority();
|
||||
|
||||
/**
|
||||
* Retrieve the user information component of the URI.
|
||||
*
|
||||
* If no user information is present, this method MUST return an empty
|
||||
* string.
|
||||
*
|
||||
* If a user is present in the URI, this will return that value;
|
||||
* additionally, if the password is also present, it will be appended to the
|
||||
* user value, with a colon (":") separating the values.
|
||||
*
|
||||
* The trailing "@" character is not part of the user information and MUST
|
||||
* NOT be added.
|
||||
*
|
||||
* @return string The URI user information, in "username[:password]" format.
|
||||
*/
|
||||
public function getUserInfo();
|
||||
|
||||
/**
|
||||
* Retrieve the host component of the URI.
|
||||
*
|
||||
* If no host is present, this method MUST return an empty string.
|
||||
*
|
||||
* The value returned MUST be normalized to lowercase, per RFC 3986
|
||||
* Section 3.2.2.
|
||||
*
|
||||
* @see http://tools.ietf.org/html/rfc3986#section-3.2.2
|
||||
* @return string The URI host.
|
||||
*/
|
||||
public function getHost();
|
||||
|
||||
/**
|
||||
* Retrieve the port component of the URI.
|
||||
*
|
||||
* If a port is present, and it is non-standard for the current scheme,
|
||||
* this method MUST return it as an integer. If the port is the standard port
|
||||
* used with the current scheme, this method SHOULD return null.
|
||||
*
|
||||
* If no port is present, and no scheme is present, this method MUST return
|
||||
* a null value.
|
||||
*
|
||||
* If no port is present, but a scheme is present, this method MAY return
|
||||
* the standard port for that scheme, but SHOULD return null.
|
||||
*
|
||||
* @return null|int The URI port.
|
||||
*/
|
||||
public function getPort();
|
||||
|
||||
/**
|
||||
* Retrieve the path component of the URI.
|
||||
*
|
||||
* The path can either be empty or absolute (starting with a slash) or
|
||||
* rootless (not starting with a slash). Implementations MUST support all
|
||||
* three syntaxes.
|
||||
*
|
||||
* Normally, the empty path "" and absolute path "/" are considered equal as
|
||||
* defined in RFC 7230 Section 2.7.3. But this method MUST NOT automatically
|
||||
* do this normalization because in contexts with a trimmed base path, e.g.
|
||||
* the front controller, this difference becomes significant. It's the task
|
||||
* of the user to handle both "" and "/".
|
||||
*
|
||||
* The value returned MUST be percent-encoded, but MUST NOT double-encode
|
||||
* any characters. To determine what characters to encode, please refer to
|
||||
* RFC 3986, Sections 2 and 3.3.
|
||||
*
|
||||
* As an example, if the value should include a slash ("/") not intended as
|
||||
* delimiter between path segments, that value MUST be passed in encoded
|
||||
* form (e.g., "%2F") to the instance.
|
||||
*
|
||||
* @see https://tools.ietf.org/html/rfc3986#section-2
|
||||
* @see https://tools.ietf.org/html/rfc3986#section-3.3
|
||||
* @return string The URI path.
|
||||
*/
|
||||
public function getPath();
|
||||
|
||||
/**
|
||||
* Retrieve the query string of the URI.
|
||||
*
|
||||
* If no query string is present, this method MUST return an empty string.
|
||||
*
|
||||
* The leading "?" character is not part of the query and MUST NOT be
|
||||
* added.
|
||||
*
|
||||
* The value returned MUST be percent-encoded, but MUST NOT double-encode
|
||||
* any characters. To determine what characters to encode, please refer to
|
||||
* RFC 3986, Sections 2 and 3.4.
|
||||
*
|
||||
* As an example, if a value in a key/value pair of the query string should
|
||||
* include an ampersand ("&") not intended as a delimiter between values,
|
||||
* that value MUST be passed in encoded form (e.g., "%26") to the instance.
|
||||
*
|
||||
* @see https://tools.ietf.org/html/rfc3986#section-2
|
||||
* @see https://tools.ietf.org/html/rfc3986#section-3.4
|
||||
* @return string The URI query string.
|
||||
*/
|
||||
public function getQuery();
|
||||
|
||||
/**
|
||||
* Retrieve the fragment component of the URI.
|
||||
*
|
||||
* If no fragment is present, this method MUST return an empty string.
|
||||
*
|
||||
* The leading "#" character is not part of the fragment and MUST NOT be
|
||||
* added.
|
||||
*
|
||||
* The value returned MUST be percent-encoded, but MUST NOT double-encode
|
||||
* any characters. To determine what characters to encode, please refer to
|
||||
* RFC 3986, Sections 2 and 3.5.
|
||||
*
|
||||
* @see https://tools.ietf.org/html/rfc3986#section-2
|
||||
* @see https://tools.ietf.org/html/rfc3986#section-3.5
|
||||
* @return string The URI fragment.
|
||||
*/
|
||||
public function getFragment();
|
||||
|
||||
/**
|
||||
* Return an instance with the specified scheme.
|
||||
*
|
||||
* This method MUST retain the state of the current instance, and return
|
||||
* an instance that contains the specified scheme.
|
||||
*
|
||||
* Implementations MUST support the schemes "http" and "https" case
|
||||
* insensitively, and MAY accommodate other schemes if required.
|
||||
*
|
||||
* An empty scheme is equivalent to removing the scheme.
|
||||
*
|
||||
* @param string $scheme The scheme to use with the new instance.
|
||||
* @return static A new instance with the specified scheme.
|
||||
* @throws \InvalidArgumentException for invalid or unsupported schemes.
|
||||
*/
|
||||
public function withScheme($scheme);
|
||||
|
||||
/**
|
||||
* Return an instance with the specified user information.
|
||||
*
|
||||
* This method MUST retain the state of the current instance, and return
|
||||
* an instance that contains the specified user information.
|
||||
*
|
||||
* Password is optional, but the user information MUST include the
|
||||
* user; an empty string for the user is equivalent to removing user
|
||||
* information.
|
||||
*
|
||||
* @param string $user The user name to use for authority.
|
||||
* @param null|string $password The password associated with $user.
|
||||
* @return static A new instance with the specified user information.
|
||||
*/
|
||||
public function withUserInfo($user, $password = null);
|
||||
|
||||
/**
|
||||
* Return an instance with the specified host.
|
||||
*
|
||||
* This method MUST retain the state of the current instance, and return
|
||||
* an instance that contains the specified host.
|
||||
*
|
||||
* An empty host value is equivalent to removing the host.
|
||||
*
|
||||
* @param string $host The hostname to use with the new instance.
|
||||
* @return static A new instance with the specified host.
|
||||
* @throws \InvalidArgumentException for invalid hostnames.
|
||||
*/
|
||||
public function withHost($host);
|
||||
|
||||
/**
|
||||
* Return an instance with the specified port.
|
||||
*
|
||||
* This method MUST retain the state of the current instance, and return
|
||||
* an instance that contains the specified port.
|
||||
*
|
||||
* Implementations MUST raise an exception for ports outside the
|
||||
* established TCP and UDP port ranges.
|
||||
*
|
||||
* A null value provided for the port is equivalent to removing the port
|
||||
* information.
|
||||
*
|
||||
* @param null|int $port The port to use with the new instance; a null value
|
||||
* removes the port information.
|
||||
* @return static A new instance with the specified port.
|
||||
* @throws \InvalidArgumentException for invalid ports.
|
||||
*/
|
||||
public function withPort($port);
|
||||
|
||||
/**
|
||||
* Return an instance with the specified path.
|
||||
*
|
||||
* This method MUST retain the state of the current instance, and return
|
||||
* an instance that contains the specified path.
|
||||
*
|
||||
* The path can either be empty or absolute (starting with a slash) or
|
||||
* rootless (not starting with a slash). Implementations MUST support all
|
||||
* three syntaxes.
|
||||
*
|
||||
* If the path is intended to be domain-relative rather than path relative then
|
||||
* it must begin with a slash ("/"). Paths not starting with a slash ("/")
|
||||
* are assumed to be relative to some base path known to the application or
|
||||
* consumer.
|
||||
*
|
||||
* Users can provide both encoded and decoded path characters.
|
||||
* Implementations ensure the correct encoding as outlined in getPath().
|
||||
*
|
||||
* @param string $path The path to use with the new instance.
|
||||
* @return static A new instance with the specified path.
|
||||
* @throws \InvalidArgumentException for invalid paths.
|
||||
*/
|
||||
public function withPath($path);
|
||||
|
||||
/**
|
||||
* Return an instance with the specified query string.
|
||||
*
|
||||
* This method MUST retain the state of the current instance, and return
|
||||
* an instance that contains the specified query string.
|
||||
*
|
||||
* Users can provide both encoded and decoded query characters.
|
||||
* Implementations ensure the correct encoding as outlined in getQuery().
|
||||
*
|
||||
* An empty query string value is equivalent to removing the query string.
|
||||
*
|
||||
* @param string $query The query string to use with the new instance.
|
||||
* @return static A new instance with the specified query string.
|
||||
* @throws \InvalidArgumentException for invalid query strings.
|
||||
*/
|
||||
public function withQuery($query);
|
||||
|
||||
/**
|
||||
* Return an instance with the specified URI fragment.
|
||||
*
|
||||
* This method MUST retain the state of the current instance, and return
|
||||
* an instance that contains the specified URI fragment.
|
||||
*
|
||||
* Users can provide both encoded and decoded fragment characters.
|
||||
* Implementations ensure the correct encoding as outlined in getFragment().
|
||||
*
|
||||
* An empty fragment value is equivalent to removing the fragment.
|
||||
*
|
||||
* @param string $fragment The fragment to use with the new instance.
|
||||
* @return static A new instance with the specified fragment.
|
||||
*/
|
||||
public function withFragment($fragment);
|
||||
|
||||
/**
|
||||
* Return the string representation as a URI reference.
|
||||
*
|
||||
* Depending on which components of the URI are present, the resulting
|
||||
* string is either a full URI or relative reference according to RFC 3986,
|
||||
* Section 4.1. The method concatenates the various components of the URI,
|
||||
* using the appropriate delimiters:
|
||||
*
|
||||
* - If a scheme is present, it MUST be suffixed by ":".
|
||||
* - If an authority is present, it MUST be prefixed by "//".
|
||||
* - The path can be concatenated without delimiters. But there are two
|
||||
* cases where the path has to be adjusted to make the URI reference
|
||||
* valid as PHP does not allow to throw an exception in __toString():
|
||||
* - If the path is rootless and an authority is present, the path MUST
|
||||
* be prefixed by "/".
|
||||
* - If the path is starting with more than one "/" and no authority is
|
||||
* present, the starting slashes MUST be reduced to one.
|
||||
* - If a query is present, it MUST be prefixed by "?".
|
||||
* - If a fragment is present, it MUST be prefixed by "#".
|
||||
*
|
||||
* @see http://tools.ietf.org/html/rfc3986#section-4.1
|
||||
* @return string
|
||||
*/
|
||||
public function __toString();
|
||||
}
|
@ -0,0 +1,21 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2016 PHP Framework Interoperability Group
|
||||
|
||||
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.
|
@ -0,0 +1,6 @@
|
||||
HTTP Server Handler
|
||||
===================
|
||||
|
||||
Provides the `RequestHandlerInterface` of [PSR-15][psr-15].
|
||||
|
||||
[psr-15]: https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-15-request-handlers.md
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in new issue