Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
42 commits
Select commit Hold shift + click to select a range
90e2014
Works without warnings in PHP 8.3
Ostico Oct 14, 2025
5e27d90
Save
Ostico Oct 15, 2025
c19661e
Tested for PHP 8.3
Ostico Oct 16, 2025
b775f07
Phpstan lvl 7
Ostico Oct 17, 2025
1ed1987
Removed TODO for deprecation
Ostico Oct 17, 2025
1a5449d
Updated ChangeLog
Ostico Oct 17, 2025
b47bc09
Updated ChangeLog
Ostico Oct 17, 2025
eea2527
Updated Ip validaiton tests
Ostico Oct 17, 2025
4244ce5
Updated travis.yml
Ostico Oct 17, 2025
52ddc94
Updated travis yml
Ostico Oct 17, 2025
4dde647
Updated travis.yml to support coverage
Ostico Oct 17, 2025
434cd87
Removed tests for php8.3 (bug)
Ostico Oct 17, 2025
5c5041d
Fix: PHP8.4
Ostico Oct 17, 2025
7a0747b
Fixed implicit nullable type hint definition
Ostico Oct 17, 2025
6822db6
Removed deprecations for implicit nullable method type hints
Ostico Oct 17, 2025
37c32a8
Merge pull request #1 from matecat/php8.3
Ostico Oct 17, 2025
462a91c
Update coding standards from PSR-2 to PSR-12
Ostico Oct 17, 2025
1730d52
Update README to remove PHP version specification
Ostico Oct 17, 2025
3ce129c
Updated Readme
Ostico Oct 17, 2025
8ffe198
Updated package name in composedr.json
Ostico Oct 17, 2025
933bc37
Faster: ~10x, searching for more optimizations
Ostico Oct 18, 2025
9bca3a9
Route regexp generation inside the route object
Ostico Oct 18, 2025
ecb7271
Implemented PSR-6 cache
Ostico Oct 18, 2025
27c5b5b
Removed is_callable redundant check
Ostico Oct 19, 2025
93927b4
Improved static routes check
Ostico Oct 19, 2025
336c4c7
Little more optimizations in Rote class and Klein
Ostico Oct 19, 2025
4e39892
Little refactory to remove method from Klein class
Ostico Oct 19, 2025
1493e6f
Implemented Radix Tree algorithm
Ostico Oct 19, 2025
f954112
Improvement:
Ostico Oct 20, 2025
6d2c9b8
Speed increase: +100x
Ostico Oct 20, 2025
52900bb
After benchmarks, removed PSR-6
Ostico Oct 20, 2025
984edc8
Little improvements
Ostico Oct 21, 2025
06c6ac2
Update Upgrading.md
Ostico Oct 21, 2025
a6fc9df
More micro optimizations
Ostico Oct 22, 2025
5f70e58
More optimizations
Ostico Oct 22, 2025
11c0155
Improvements for static routes
Ostico Oct 23, 2025
d2c7297
RC
Ostico Oct 23, 2025
456b252
Removed coverage from Travis CI
Ostico Oct 23, 2025
be67b50
Fixed bug in Header response
Ostico Oct 24, 2025
7961e43
Fixed dynamic detection on namespaces
Ostico Oct 27, 2025
d842754
Added test for dynamic namespace
Ostico Oct 27, 2025
30054d9
Renamed Request::method to Request::httpMethod to allow klein to be
Ostico Oct 28, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,8 @@ docs/

# Auto-generated code coverage report
report/
/.phpunit.cache/
/.phpunit.result.cache
/coverage.clover
/cache/
/Benchmarks/
17 changes: 6 additions & 11 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -1,19 +1,15 @@
sudo: false

env:
global:
- XDEBUG_MODE=coverage

language: php
php:
- 5.3
- 5.4
- 5.5
- 5.6
- 7.0
- nightly
- hhvm
- 8.3
- 8.4

matrix:
allow_failures:
- php: nightly
- php: hhvm
fast_finish: true

before_script:
Expand All @@ -22,4 +18,3 @@ before_script:
script:
- composer validate
- ./vendor/bin/phpunit
- ./vendor/bin/phpcs --standard=PSR2 --encoding=utf-8 -p src/ tests/
326 changes: 326 additions & 0 deletions BENCHMARKS.md

Large diffs are not rendered by default.

29 changes: 29 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,34 @@
# CHANGELOG

## 3.2.0

### Features

- Lightning fast routing! From **100x to 1000x** faster dispatch. Big performance improvements for large route collections with radix Tree routing. [Benchmarks](BENCHMARKS.md)
- 100% Code Coverage
- Breaking changes, see [UPGRADING.md](UPGRADING.md)

## 3.1.0

### Features

- Support for PHP 8.3
- Dropped support for previous PHP versions
- Updated PHPUnit to version 12

## 3.0.0

### Features

- Support for PHP >= 8.1
- Dropped support for previous PHP versions
- Removed the "magical" way of inputting mask in DataCollections in favor of PHP 8 named arguments.
- Removed use of 404/405 "routes" (deprecated in previous versions). Use `$klein->onHttpError()` instead.
- Removed "magical" callback behavior in favor of PHP 8.3 named arguments. Now the function accepts an optional string path as the first parameter and a NOT optional callback.
- Removed "magical" markdown behavior. Now the function accepts a string and an optional array of values.
- Removed "magical" markdown behavior. Now the function accepts a string and an optional array of values.
- Removed "magical" behavior of `ServiceProvider::flash()` method. Now the function accepts a string and an optional array of values.
- Updated PHPUnit to version 10

## 2.1.2

Expand Down
5 changes: 3 additions & 2 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ Contributing is absolutely encouraged, but a few things should be taken into acc

- Always test any bug-fixes or changes with [unit testing][unit-testing]
- When adding or changing a feature, make sure to write a **new** [unit test][unit-testing]
- This project adheres to the [PSR-2][psr-2] standards. Please make sure your contributions [comply][code-sniffer].
- This project adheres to the [PSR-12][psr-12] standards. Please make sure your contributions [comply][code-sniffer].
- Code and comment styles should be made as consistent as possible with the rest of the project
- Make sure to document your code with the [PHPDoc syntax][php-doc]
- Pull Requests and Issues should contain no more than **1** bug-fix, feature, or documentation change
Expand All @@ -18,6 +18,7 @@ Contributing is absolutely encouraged, but a few things should be taken into acc
Klein is an open library designed for a specific purpose. You may find that a certain requested feature or change may not be accepted. Please don't take those actions personally, as the controlling contributors are simply just trying to keep the project's purpose clear and designated.

[unit-testing]: README.md#unit-testing
[psr-2]: https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-2-coding-style-guide.md
[psr-12]: https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-12-extended-coding-style-guide.md
[code-sniffer]: https://github.com/squizlabs/PHP_CodeSniffer
[php-doc]: http://www.phpdoc.org/docs/latest/for-users/phpdoc-reference.html
[phpstan]: https://phpstan.org/user-guide/getting-started
38 changes: 23 additions & 15 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,16 +1,23 @@
# Klein.php

[![Build Status](https://travis-ci.org/klein/klein.php.png?branch=master)](https://travis-ci.org/klein/klein.php)
[![Build Status](https://app.travis-ci.com/matecat/klein.php.svg?token=qBazxkHwP18h3EWnHjjF&branch=master)](https://app.travis-ci.com/matecat/klein.php)

**klein.php** is a fast & flexible router for PHP 5.3+
**klein.php** is a fast & flexible router for PHP

* Flexible regular expression routing (inspired by [Sinatra](http://www.sinatrarb.com/))
* A set of [boilerplate methods](#api) for rapidly building web apps
* Almost no overhead => [2500+ requests/second](https://gist.github.com/878833)
* Almost no overhead => [Benchmarks](BENCHMARKS.md)
* Benchmark framework: https://github.com/follestad/php-router-benchmark

## Overview

This repository is a fork of the original project, created to restore active maintenance and modernize the codebase.
We use this library in production and have committed to keeping it up to date and compatible with current PHP versions.
The primary goal of this fork is to enable and support PHP 8.3 while preserving the original project's spirit and API where possible.

## Getting started

1. PHP 5.3.x is required
1. PHP >= 8.3 is required
2. Install Klein using [Composer](#composer-installation) (recommended) or manually
3. Setup [URL rewriting](https://gist.github.com/874000) so that all requests are handled by **index.php**
4. (Optional) Throw in some [APC](http://pecl.php.net/package/APC) for good measure
Expand Down Expand Up @@ -41,23 +48,23 @@ $klein->dispatch();
*Example 1* - Respond to all requests

```php
$klein->respond(function () {
$klein->respond(callback: function () {
return 'All the things';
});
```

*Example 2* - Named parameters

```php
$klein->respond('/[:name]', function ($request) {
$klein->respond(path: '/[:name]', callback: function ($request) {
return 'Hello ' . $request->name;
});
```

*Example 3* - [So RESTful](http://bit.ly/g93B1s)

```php
$klein->respond('GET', '/posts', $callback);
$klein->respond(method: 'GET', path: '/posts', callback: $callback);
$klein->respond('POST', '/posts', $callback);
$klein->respond('PUT', '/posts/[i:id]', $callback);
$klein->respond('DELETE', '/posts/[i:id]', $callback);
Expand All @@ -67,7 +74,7 @@ $klein->respond('OPTIONS', null, $callback);
$klein->respond(array('POST','GET'), $route, $callback);

// Or you might want to handle the requests in the same place
$klein->respond('/posts/[create|edit:action]?/[i:id]?', function ($request, $response) {
$klein->respond(path: '/posts/[create|edit:action]?/[i:id]?', callback: function ($request, $response) {
switch ($request->action) {
//
}
Expand All @@ -77,7 +84,7 @@ $klein->respond('/posts/[create|edit:action]?/[i:id]?', function ($request, $res
*Example 4* - Sending objects / files

```php
$klein->respond(function ($request, $response, $service) {
$klein->respond(callback: function ($request, $response, $service) {
$service->xml = function ($object) {
// Custom xml output function
}
Expand All @@ -86,7 +93,7 @@ $klein->respond(function ($request, $response, $service) {
}
});

$klein->respond('/report.[xml|csv|json:format]?', function ($request, $response, $service) {
$klein->respond(path: '/report.[xml|csv|json:format]?', callback: function ($request, $response, $service) {
// Get the format or fallback to JSON as the default
$send = $request->param('format', 'json');
$response->$send($report);
Expand All @@ -100,7 +107,7 @@ $klein->respond('/report/latest', function ($request, $response, $service) {
*Example 5* - All together

```php
$klein->respond(function ($request, $response, $service, $app) use ($klein) {
$klein->respond(callback: function ($request, $response, $service, $app) use ($klein) {
// Handle exceptions => flash the message and redirect to the referrer
$klein->onError(function ($klein, $err_msg) {
$klein->service()->flash($err_msg);
Expand Down Expand Up @@ -251,9 +258,9 @@ authentication or view layouts. e.g. as a basic example, the following
code will wrap other routes with a header and footer

```php
$klein->respond('*', function ($request, $response, $service) { $service->render('header.phtml'); });
$klein->respond(path: '*', callback: function ($request, $response, $service) { $service->render('header.phtml'); });
//other routes
$klein->respond('*', function ($request, $response, $service) { $service->render('footer.phtml'); });
$klein->respond(path: '*', callback: function ($request, $response, $service) { $service->render('footer.phtml'); });
```

Routes automatically match the entire request URI. If you need to match
Expand All @@ -262,10 +269,10 @@ negate a route, use the `!` operator

```php
// Match all requests that end with '.json' or '.csv'
$klein->respond('@\.(json|csv)$', ...
$klein->respond(path: '@\.(json|csv)$', ...

// Match all requests that _don't_ start with /admin
$klein->respond('!@^/admin/', ...
$klein->respond(path: '!@^/admin/', ...
```

## Views
Expand Down Expand Up @@ -424,6 +431,7 @@ See the [wiki](https://github.com/klein/klein.php/wiki) for more information

## Contributors

- [Domenico Lupinetti](https://github.com/Ostico)
- [Trevor N. Suarez](https://github.com/Rican7)

## License
Expand Down
33 changes: 33 additions & 0 deletions UPGRADING.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,38 @@
# Klein Upgrade Guide

## 3.1.0 to 3.2.0

### Behavior Changes

- The execution order of the route callbacks is no more guaranteed to be the same as the order in which they were registered when mixing catch all routes and routes with specified paths.
- The `HeaderDataCollection` class now uses `ucwords()` sanitization
Underscores are not allowed in the header field names since
nginx and Apache will silently drop HTTP headers with underscores
(which are perfectly valid, according to the HTTP standard).
This is done to prevent ambiguities when mapping headers to CGI variables,
as both dashes and underscores are mapped to underscores during that process.
- Fields are now case-sensitive.

Ex:
```shell
curl -H 'content-TOP: FooBar' -H 'content-type: application/json' https://localhost
[
'Host' => 'localhost',
'User-Agent' => 'curl/8.5.0',
'Accept' => '*/*',
'content-TOP' => 'Fake',
'content-type' => 'application/json',
] =>
HeaderDataCollection::get('content-TOP') => NULL
HeaderDataCollection::get('content-type') => NULL
HeaderDataCollection::get('Content-Top') => 'FooBar'
HeaderDataCollection::get('Content-Type') => 'application/json'
```

### Breaking Changes

- Renamed `Request::method` to `Request::httpMethod` to allow the Klein library to be mocked with PHPUnit >= 12
- Because of PHPUnit decision to not allow methods named "method" to be mocked (it throws an Exception), we must introduce a big breaking change: https://github.com/sebastianbergmann/phpunit/issues/5415

## 2.1.1 to 2.1.2

Expand Down
89 changes: 52 additions & 37 deletions composer.json
Original file line number Diff line number Diff line change
@@ -1,39 +1,54 @@
{
"name": "klein/klein",
"description": "A lightning fast router for PHP",
"keywords": ["router", "routing", "sinatra", "boilerplate"],
"homepage": "https://github.com/klein/klein.php",
"license": "MIT",
"authors": [
{
"name": "Chris O'Hara",
"email": "cohara87@gmail.com",
"homepage": "http://chris6f.com/",
"role": "Creator/Developer"
},
{
"name": "Trevor Suarez",
"email": "rican7@gmail.com",
"homepage": "https://trevorsuarez.com/",
"role": "Contributor/Developer"
}
],
"require": {
"php": ">=5.3.0"
},
"require-dev": {
"phpunit/phpunit": "^4.8",
"phpunit/php-code-coverage": "^2.2",
"squizlabs/php_codesniffer": "1.4.8"
},
"autoload": {
"psr-4": {
"Klein\\": "src/Klein/"
}
},
"autoload-dev": {
"psr-4": {
"Klein\\Tests\\": "tests/Klein/Tests"
}
}
"name": "matecat/klein",
"description": "A lightning fast router for PHP",
"keywords": [
"router",
"routing",
"sinatra",
"boilerplate"
],
"homepage": "https://github.com/matecat/klein.php",
"license": "MIT",
"authors": [
{
"name": "Chris O'Hara",
"email": "cohara87@gmail.com",
"homepage": "http://chris6f.com/",
"role": "Creator/Developer"
},
{
"name": "Trevor Suarez",
"email": "rican7@gmail.com",
"homepage": "https://trevorsuarez.com/",
"role": "Contributor/Developer"
},
{
"name": "Domenico Lupinetti",
"email": "ostico@gmail.com",
"role": "Contributor/Developer"
}
],
"require": {
"php": ">=8.3",
"ext-ctype": "*",
"ext-fileinfo": "*"
},
"require-dev": {
"phpunit/phpunit": "^12",
"phpunit/php-code-coverage": "^12",
"squizlabs/php_codesniffer": "^4",
"phpstan/phpstan": "@stable",
"ext-xdebug": "*"
},
"autoload": {
"psr-4": {
"Klein\\": "src/Klein/"
}
},
"autoload-dev": {
"psr-4": {
"Klein\\Tests\\": "tests/Klein/Tests",
"Benchmarks\\": "Benchmarks/"
}
}
}
Loading