1
0
mirror of https://github.com/dannyvankooten/AltoRouter.git synced 2025-08-22 16:12:50 +02:00

18 Commits

Author SHA1 Message Date
Danny van Kooten
c28df65f42 adhere to (mostly) PSR12, check codestyle in CI 2025-01-11 20:21:41 +01:00
Danny van Kooten
f440bb654d check php syntax with error_reporting=-1 2025-01-11 20:13:29 +01:00
Danny van Kooten
9931b97642 fix indentation 2025-01-05 21:33:28 +01:00
Danny van Kooten
41fcec6b8e Merge branch 'master' of github.com:dannyvankooten/AltoRouter 2025-01-05 21:30:50 +01:00
Danny van Kooten
9d62094f74 check php syntax on all supported versions 2025-01-05 21:30:35 +01:00
Danny van Kooten
bc6b911a6d Merge pull request #285 from xpetter/patch-1
Update AltoRouter.php for php 8.4
2024-12-16 14:27:40 +01:00
Petter
5159909a81 Update AltoRouter.php
fix for php 8.4 and keep php 7.3 support
2024-12-16 14:13:20 +01:00
Petter
71389237e5 Update AltoRouter.php for php 8.4
Fix for php8.4
AltoRouter::map(): Implicitly marking parameter $name as nullable is deprecated.
AltoRouter::match(): Implicitly marking parameter $requestUrl as nullable is deprecated.
AltoRouter::match(): Implicitly marking parameter $requestMethod as nullable is deprecated.
2024-12-16 10:00:57 +01:00
Danny van Kooten
36f67da100 bump required php version to 7.3 2023-11-30 10:10:31 +01:00
Danny van Kooten
4270bb5ca2 bump php version requirement to 7.0 and add types on all methods 2023-10-09 20:54:04 +02:00
Danny van Kooten
77a2e14681 fix phpcs issues 2023-10-09 20:49:37 +02:00
Danny van Kooten
f327fbb5bf test on php 8.2 and php 8.3 too 2023-10-09 20:46:07 +02:00
Danny van Kooten
63bb784d76 update links to point to docs 2023-10-09 20:23:45 +02:00
Danny van Kooten
bb7b009331 update phpunit to 9.6 & migrate config to latest schema 2023-10-09 19:46:04 +02:00
Danny van Kooten
20674b8953 address PHP8.x warnings about return type
this requires PHP 7.1 for the void return type, but only for running the
test suite.
2022-12-08 11:12:36 +01:00
Danny van Kooten
ac028a7f3f run tests only on php >= 7.3 2022-02-17 10:42:10 +01:00
Danny van Kooten
0a94ba4142 switch to GitHub actions for running test suite 2022-02-17 10:39:54 +01:00
Danny van Kooten
85c453b12c update phpunit to latest version 2022-02-17 10:31:41 +01:00
11 changed files with 163 additions and 125 deletions

20
.github/workflows/php-check-syntax.yml vendored Normal file
View File

@@ -0,0 +1,20 @@
name: Check PHP syntax
on: [ push, pull_request ]
jobs:
build:
runs-on: ubuntu-latest
strategy:
matrix:
php-versions: ['7.3', '7.4', '8.0', '8.1', '8.2', '8.3', 'highest']
steps:
- name: Setup PHP
uses: shivammathur/setup-php@v2
with:
php-version: ${{ matrix.php-versions }}
- name: checkout repo
uses: actions/checkout@v3
- run: composer run check-syntax

42
.github/workflows/php.yml vendored Normal file
View File

@@ -0,0 +1,42 @@
name: PHP
on: [ push, pull_request ]
jobs:
build:
runs-on: ubuntu-latest
strategy:
matrix:
php-versions: [ '7.3', 'highest' ]
steps:
- uses: actions/checkout@v2
- uses: shivammathur/setup-php@v2
with:
php-version: ${{ matrix.php-versions }}
tools: composer
- name: Validate composer.json and composer.lock
run: composer validate
- name: Get composer cache directory
id: composer-cache
run: echo "::set-output name=dir::$(composer config cache-files-dir)"
- name: Cache dependencies
uses: actions/cache@v2
with:
path: ${{ steps.composer-cache.outputs.dir }}
key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.lock') }}
restore-keys: ${{ runner.os }}-composer-
- name: Install dependencies
if: steps.composer-cache.outputs.cache-hit != 'true'
run: composer install --no-progress
- name: Check codestyle
run: composer run-script check-codestyle
- name: Run test suite
run: composer run-script test

1
.gitignore vendored
View File

@@ -6,3 +6,4 @@ build
vendor
composer.lock
phpunit.xml
.phpunit.result.cache

View File

@@ -1,21 +0,0 @@
language: php
php:
- 5.6
- 7.0
- 7.1
- 7.2
- 7.3
install:
- composer update --prefer-source
script:
- vendor/bin/phpunit
after_script:
- vendor/bin/test-reporter
env:
global:
secure: XnXSc7nxJMIrm/EJ1KuwlN4f+sj2R/sR0IFHdOdbOfMKyZ/u6WEgZ3vNrdeAsisiC/QUJJ00DGku1pAl3t3Hzvam0N/SiHtXjB1ZLVbX00S1PEZ6Z+h9zoaUBXWoN6+0OdKN0Xjmj2lwvTpvUxUZXNabilOw0F9WS/+JasofqBQ=
sudo: false
cache:
directories:
- vendor
- $HOME/.composer/cache

View File

@@ -1,4 +1,5 @@
<?php
/*
MIT License
@@ -13,7 +14,6 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
class AltoRouter
{
/**
* @var array Array of all routes (incl. named routes).
*/
@@ -49,7 +49,7 @@ class AltoRouter
* @param array $matchTypes
* @throws Exception
*/
public function __construct(array $routes = [], $basePath = '', array $matchTypes = [])
public function __construct(array $routes = [], string $basePath = '', array $matchTypes = [])
{
$this->addRoutes($routes);
$this->setBasePath($basePath);
@@ -61,7 +61,7 @@ class AltoRouter
* Useful if you want to process or display routes.
* @return array All routes.
*/
public function getRoutes()
public function getRoutes(): array
{
return $this->routes;
}
@@ -93,7 +93,7 @@ class AltoRouter
* Useful if you are running your application from a subdirectory.
* @param string $basePath
*/
public function setBasePath($basePath)
public function setBasePath(string $basePath)
{
$this->basePath = $basePath;
}
@@ -117,7 +117,7 @@ class AltoRouter
* @param string $name Optional name of this route. Supply if you want to reverse route this url in your application.
* @throws Exception
*/
public function map($method, $route, $target, $name = null)
public function map(string $method, string $route, $target, ?string $name = null)
{
$this->routes[] = [$method, $route, $target, $name];
@@ -128,8 +128,6 @@ class AltoRouter
}
$this->namedRoutes[$name] = $route;
}
return;
}
/**
@@ -138,11 +136,11 @@ class AltoRouter
* Generate the URL for a named route. Replace regexes with supplied parameters
*
* @param string $routeName The name of the route.
* @param array @params Associative array of parameters to replace placeholders with.
* @param array $params Associative array of parameters to replace placeholders with.
* @return string The URL of the route with named parameters in place.
* @throws Exception
*/
public function generate($routeName, array $params = [])
public function generate(string $routeName, array $params = []): string
{
// Check if named route exists
@@ -186,7 +184,7 @@ class AltoRouter
* @param string $requestMethod
* @return array|boolean Array with route information on success, false on failure (no match).
*/
public function match($requestUrl = null, $requestMethod = null)
public function match(?string $requestUrl = null, ?string $requestMethod = null)
{
$params = [];
@@ -204,7 +202,7 @@ class AltoRouter
$requestUrl = substr($requestUrl, 0, $strpos);
}
$lastRequestUrlChar = $requestUrl ? $requestUrl[strlen($requestUrl)-1] : '';
$lastRequestUrlChar = $requestUrl ? $requestUrl[strlen($requestUrl) - 1] : '';
// set Request Method if it isn't passed as a parameter
if ($requestMethod === null) {
@@ -233,8 +231,8 @@ class AltoRouter
$match = strcmp($requestUrl, $route) === 0;
} else {
// Compare longest non-param string with url before moving on to regex
// Check if last character before param is a slash, because it could be optional if param is optional too (see https://github.com/dannyvankooten/AltoRouter/issues/241)
if (strncmp($requestUrl, $route, $position) !== 0 && ($lastRequestUrlChar === '/' || $route[$position-1] !== '/')) {
// Check if last character before param is a slash, because it could be optional if param is optional too (see https://github.com/dannyvankooten/AltoRouter/issues/241)
if (strncmp($requestUrl, $route, $position) !== 0 && ($lastRequestUrlChar === '/' || $route[$position - 1] !== '/')) {
continue;
}
@@ -264,10 +262,10 @@ class AltoRouter
/**
* Compile the regex for a given route (EXPENSIVE)
* @param $route
* @param string $route
* @return string
*/
protected function compileRoute($route)
protected function compileRoute(string $route): string
{
if (preg_match_all('`(/|\.|)\[([^:\]]*+)(?::([^:\]]*+))?\](\?|)`', $route, $matches, PREG_SET_ORDER)) {
$matchTypes = $this->matchTypes;

View File

@@ -1,4 +1,5 @@
# AltoRouter [![Build Status](https://img.shields.io/travis/dannyvankooten/AltoRouter/master)](https://travis-ci.org/dannyvankooten/AltoRouter) [![Latest Stable Version](https://poser.pugx.org/altorouter/altorouter/v/stable.svg)](https://packagist.org/packages/altorouter/altorouter) [![License](https://poser.pugx.org/altorouter/altorouter/license.svg)](https://packagist.org/packages/altorouter/altorouter) [![Code Climate](https://codeclimate.com/github/dannyvankooten/AltoRouter/badges/gpa.svg)](https://codeclimate.com/github/dannyvankooten/AltoRouter) [![Test Coverage](https://codeclimate.com/github/dannyvankooten/AltoRouter/badges/coverage.svg)](https://codeclimate.com/github/dannyvankooten/AltoRouter)
# AltoRouter ![PHP status](https://github.com/dannyvankooten/AltoRouter/workflows/PHP/badge.svg) [![Latest Stable Version](https://poser.pugx.org/altorouter/altorouter/v/stable.svg)](https://packagist.org/packages/altorouter/altorouter) [![License](https://poser.pugx.org/altorouter/altorouter/license.svg)](https://packagist.org/packages/altorouter/altorouter)
AltoRouter is a small but powerful routing class, heavily inspired by [klein.php](https://github.com/chriso/klein.php/).
```php
@@ -29,13 +30,13 @@ echo $router->generate('user-details', ['id' => 5]); // Output: "/users/5"
## Getting started
You need PHP >= 5.6 to use AltoRouter, although we highly recommend you [use an officially supported PHP version](https://secure.php.net/supported-versions.php) that is not EOL.
You need PHP >= 7.3 to use AltoRouter, although we highly recommend you [use an officially supported PHP version](https://secure.php.net/supported-versions.php) that is not EOL.
- [Install AltoRouter](http://altorouter.com/usage/install.html)
- [Rewrite all requests to AltoRouter](http://altorouter.com/usage/rewrite-requests.html)
- [Map your routes](http://altorouter.com/usage/mapping-routes.html)
- [Match requests](http://altorouter.com/usage/matching-requests.html)
- [Process the request your preferred way](http://altorouter.com/usage/processing-requests.html)
- [Install AltoRouter](https://dannyvankooten.github.io/AltoRouter//usage/install.html)
- [Rewrite all requests to AltoRouter](https://dannyvankooten.github.io/AltoRouter//usage/rewrite-requests.html)
- [Map your routes](https://dannyvankooten.github.io/AltoRouter//usage/mapping-routes.html)
- [Match requests](https://dannyvankooten.github.io/AltoRouter//usage/matching-requests.html)
- [Process the request your preferred way](https://dannyvankooten.github.io/AltoRouter//usage/processing-requests.html)
## Contributors
- [Danny van Kooten](https://github.com/dannyvankooten)

View File

@@ -20,17 +20,18 @@
}
],
"require": {
"php": ">=5.6.0"
"php": ">=7.3"
},
"require-dev": {
"phpunit/phpunit": "5.7.*",
"codeclimate/php-test-reporter": "dev-master",
"squizlabs/php_codesniffer": "3.4.2"
"phpunit/phpunit": "9.6.*",
"squizlabs/php_codesniffer": "3.6.2"
},
"autoload": {
"classmap": ["AltoRouter.php"]
},
"scripts": {
"test": "vendor/bin/phpunit"
"test": "phpunit",
"check-syntax": "find . -name '*.php' -not -path './vendor/*' -print0 | xargs -0 -n1 php --define error_reporting=-1 -l",
"check-codestyle": "phpcs -ns"
}
}

View File

@@ -1,9 +1,10 @@
<?xml version="1.0"?>
<ruleset name="rules">
<description>rules</description>
<rule ref="PSR2"/>
<rule ref="PSR12">
<exclude name="PSR1.Classes.ClassDeclaration.MissingNamespace" />
</rule>
<rule ref="Generic.Arrays.DisallowLongArraySyntax"/>
<file>tests</file>
<file>AltoRouter.php</file>
<file>examples/</file>
<arg name="colors"/>

View File

@@ -1,17 +1,17 @@
<phpunit
colors="true"
verbose="true">
<testsuites>
<testsuite name="altorouter">
<directory>./tests/</directory>
</testsuite>
</testsuites>
<filter>
<whitelist>
<file>./AltoRouter.php</file>
</whitelist>
</filter>
<logging>
<log type="coverage-clover" target="build/logs/clover.xml"/>
</logging>
</phpunit>
<?xml version="1.0"?>
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" colors="true" verbose="true" xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/9.3/phpunit.xsd">
<coverage>
<include>
<file>./AltoRouter.php</file>
</include>
<report>
<clover outputFile="build/logs/clover.xml"/>
</report>
</coverage>
<testsuites>
<testsuite name="altorouter">
<directory>./tests/</directory>
</testsuite>
</testsuites>
<logging/>
</phpunit>

View File

@@ -25,23 +25,26 @@ class SimpleTraversable implements Iterator
['POST', '/bar', 'bar_action', 'second_route']
];
#[\ReturnTypeWillChange]
public function current()
{
return $this->_data[$this->_position];
}
#[\ReturnTypeWillChange]
public function key()
{
return $this->_position;
}
public function next()
public function next() : void
{
++$this->_position;
}
public function rewind()
public function rewind() : void
{
$this->_position = 0;
}
public function valid()
public function valid() : bool
{
return isset($this->_data[$this->_position]);
}
@@ -58,19 +61,11 @@ class AltoRouterTest extends PHPUnit\Framework\TestCase
* Sets up the fixture, for example, opens a network connection.
* This method is called before a test is executed.
*/
protected function setUp()
protected function setUp() : void
{
$this->router = new AltoRouterDebug;
}
/**
* Tears down the fixture, for example, closes a network connection.
* This method is called after a test is executed.
*/
protected function tearDown()
{
}
/**
* @covers AltoRouter::getRoutes
*/
@@ -81,7 +76,7 @@ class AltoRouterTest extends PHPUnit\Framework\TestCase
$target = static function () {
};
$this->assertInternalType('array', $this->router->getRoutes());
$this->assertIsArray($this->router->getRoutes());
// $this->assertIsArray($this->router->getRoutes()); // for phpunit 7.x
$this->router->map($method, $route, $target);
$this->assertEquals([[$method, $route, $target, null]], $this->router->getRoutes());
@@ -134,6 +129,7 @@ class AltoRouterTest extends PHPUnit\Framework\TestCase
*/
public function testAddRoutesThrowsExceptionOnInvalidArgument()
{
$this->expectException(RuntimeException::class);
$this->router->addRoutes(new stdClass);
}
@@ -142,7 +138,7 @@ class AltoRouterTest extends PHPUnit\Framework\TestCase
*/
public function testSetBasePath()
{
$this->router->setBasePath('/some/path');
$this->router->setBasePath('/some/path');
$this->assertEquals('/some/path', $this->router->getBasePath());
$this->router->setBasePath('/some/path');
@@ -518,18 +514,17 @@ class AltoRouterTest extends PHPUnit\Framework\TestCase
}
public function testMatchWithSlashBeforeOptionalPart()
{
$this->router->map('GET', '/archives/[lmin:category]?', 'Article#archives');
$expected = [
'target' => 'Article#archives',
'params' => [],
'name' => null
];
{
$this->router->map('GET', '/archives/[lmin:category]?', 'Article#archives');
$expected = [
'target' => 'Article#archives',
'params' => [],
'name' => null
];
$this->assertEquals($expected, $this->router->match('/archives/', 'GET'));
$this->assertEquals($expected, $this->router->match('/archives', 'GET'));
}
$this->assertEquals($expected, $this->router->match('/archives/', 'GET'));
$this->assertEquals($expected, $this->router->match('/archives', 'GET'));
}
/**
* @covers AltoRouter::addMatchTypes

View File

@@ -13,46 +13,46 @@
require __DIR__ . '/../vendor/autoload.php';
$routes = [
["POST", "/1/classes/[a:className]"],
["GET", "/1/classes/[a:className]/[i:objectId]"],
["PUT", "/1/classes/[a:className]/[i:objectId]"],
["GET", "/1/classes/[a:className]"],
["DELETE", "/1/classes/[a:className]/[i:objectId]"],
["POST", "/1/classes/[a:className]"],
["GET", "/1/classes/[a:className]/[i:objectId]"],
["PUT", "/1/classes/[a:className]/[i:objectId]"],
["GET", "/1/classes/[a:className]"],
["DELETE", "/1/classes/[a:className]/[i:objectId]"],
// Users
["POST", "/1/users"],
["GET", "/1/login"],
["GET", "/1/users/[i:objectId]"],
["PUT", "/1/users/[i:objectId]"],
["GET", "/1/users"],
["DELETE", "/1/users/[i:objectId]"],
["POST", "/1/requestPasswordReset"],
// Users
["POST", "/1/users"],
["GET", "/1/login"],
["GET", "/1/users/[i:objectId]"],
["PUT", "/1/users/[i:objectId]"],
["GET", "/1/users"],
["DELETE", "/1/users/[i:objectId]"],
["POST", "/1/requestPasswordReset"],
// Roles
["POST", "/1/roles"],
["GET", "/1/roles/[i:objectId]"],
["PUT", "/1/roles/[i:objectId]"],
["GET", "/1/roles"],
["DELETE", "/1/roles/[i:objectId]"],
// Roles
["POST", "/1/roles"],
["GET", "/1/roles/[i:objectId]"],
["PUT", "/1/roles/[i:objectId]"],
["GET", "/1/roles"],
["DELETE", "/1/roles/[i:objectId]"],
// Files
["POST", "/1/files/:fileName"],
// Files
["POST", "/1/files/:fileName"],
// Analytics
["POST", "/1/events/[a:eventName]"],
// Analytics
["POST", "/1/events/[a:eventName]"],
// Push Notifications
["POST", "/1/push"],
// Push Notifications
["POST", "/1/push"],
// Installations
["POST", "/1/installations"],
["GET", "/1/installations/[i:objectId]"],
["PUT", "/1/installations/[i:objectId]"],
["GET", "/1/installations"],
["DELETE", "/1/installations/[i:objectId]"],
// Installations
["POST", "/1/installations"],
["GET", "/1/installations/[i:objectId]"],
["PUT", "/1/installations/[i:objectId]"],
["GET", "/1/installations"],
["DELETE", "/1/installations/[i:objectId]"],
// Cloud Functions
["POST", "/1/functions"],
// Cloud Functions
["POST", "/1/functions"],
];
$total_time = 0;
$router = new AltoRouter();