Merge pull request #548 from flightphp/php8-named-arguments-support

PHP 8 named arguments support
master
n0nag0n 2 weeks ago committed by GitHub
commit 22570b9987
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -33,14 +33,17 @@
},
"autoload-dev": {
"classmap": [
"tests/classes/User.php",
"tests/classes/Hello.php",
"tests/classes/Factory.php",
"tests/classes/TesterClass.php"
]
"tests/classes/"
],
"psr-4": {
"Tests\\PHP8\\": [
"tests/named-arguments"
]
}
},
"require-dev": {
"ext-pdo_sqlite": "*",
"flightphp/container": "^1.0",
"flightphp/runway": "^0.2.3 || ^1.0",
"league/container": "^4.2",
"level-2/dice": "^4.0",

@ -16,6 +16,7 @@ use flight\net\Router;
use flight\template\View;
use Throwable;
use flight\net\Route;
use Psr\Container\ContainerInterface;
/**
* The Engine class contains the core functionality of the framework.
@ -265,9 +266,9 @@ class Engine
/**
* Registers the container handler
*
* @param callable|object $containerHandler Callback function or PSR-11 Container object that sets the container and how it will inject classes
* @template T of object
*
* @return void
* @param ContainerInterface|callable(class-string<T> $id, array<int|string, mixed> $params): ?T $containerHandler Callback function or PSR-11 Container object that sets the container and how it will inject classes
*/
public function registerContainerHandler($containerHandler): void
{

@ -9,6 +9,7 @@ use flight\net\Router;
use flight\template\View;
use flight\net\Route;
use flight\core\EventDispatcher;
use Psr\Container\ContainerInterface;
require_once __DIR__ . '/autoload.php';
@ -18,9 +19,11 @@ require_once __DIR__ . '/autoload.php';
* @license MIT, http://flightphp.com/license
* @copyright Copyright (c) 2011, Mike Cao <mike@mikecao.com>
*
* @template T of object
*
* # Core methods
* @method static void start() Starts the framework.
* @method static void path(string $path) Adds a path for autoloading classes.
* @method static void path(string $dir) Adds a path for autoloading classes.
* @method static void stop(?int $code = null) Stops the framework and sends a response.
* @method static void halt(int $code = 200, string $message = '', bool $actuallyExit = true)
* Stop the framework with an optional status code and message.
@ -28,7 +31,10 @@ require_once __DIR__ . '/autoload.php';
* Registers a class to a framework method.
* @method static void unregister(string $methodName)
* Unregisters a class to a framework method.
* @method static void registerContainerHandler(callable|object $containerHandler) Registers a container handler.
* @method static void registerContainerHandler(ContainerInterface|callable(class-string<T> $id, array<int|string, mixed> $params): ?T $containerHandler) Registers a container handler.
*
* # Class registration
* @method EventDispatcher eventDispatcher() Gets event dispatcher
*
* # Class registration
* @method EventDispatcher eventDispatcher() Gets event dispatcher
@ -104,6 +110,7 @@ class Flight
*/
private function __construct()
{
//
}
/**
@ -114,6 +121,7 @@ class Flight
*/
private function __clone()
{
//
}
/**

@ -106,7 +106,7 @@ class RouteCommand extends AbstractBaseCommand
if ($showAll === true) {
$boolval = true;
} else {
$methods = [ 'GET', 'POST', 'PUT', 'DELETE', 'PATCH' ];
$methods = ['GET', 'POST', 'PUT', 'DELETE', 'PATCH'];
foreach ($methods as $method) {
$lowercaseMethod = strtolower($method);
if (

@ -52,7 +52,9 @@ class Dispatcher
/**
* Sets the dependency injection container handler.
*
* @param ContainerInterface|(callable(string $classString, array<int, mixed> $params): (null|object)) $containerHandler
* @template T of object
*
* @param ContainerInterface|(callable(class-string<T> $classString, array<int, mixed> $params): ?T) $containerHandler
* Dependency injection container.
*
* @throws InvalidArgumentException If $containerHandler is not a `callable` or instance of `Psr\Container\ContainerInterface`.
@ -231,7 +233,7 @@ class Dispatcher
if ($parametersNumber === 1) {
/** @disregard &$params in after filters are deprecated. */
$callback = fn (array &$params, &$output) => $callback($output);
$callback = fn(array &$params, &$output) => $callback($output);
}
}
@ -437,11 +439,12 @@ class Dispatcher
public function resolveContainerClass(string $class, array &$params)
{
// PSR-11
if (
is_a($this->containerHandler, '\Psr\Container\ContainerInterface')
&& $this->containerHandler->has($class)
) {
return $this->containerHandler->get($class);
if (is_a($this->containerHandler, '\Psr\Container\ContainerInterface')) {
try {
return $this->containerHandler->get($class);
} catch (Throwable $exception) {
return null;
}
}
// Just a callable where you configure the behavior (Dice, PHP-DI, etc.)

@ -211,8 +211,8 @@ class Request
$this->data->setData($data);
}
}
// Check PUT, PATCH, DELETE for application/x-www-form-urlencoded data
} elseif (in_array($this->method, [ 'PUT', 'DELETE', 'PATCH' ], true) === true) {
// Check PUT, PATCH, DELETE for application/x-www-form-urlencoded data
} elseif (in_array($this->method, ['PUT', 'DELETE', 'PATCH'], true) === true) {
$body = $this->getBody();
if ($body !== '') {
$data = [];

@ -5,4 +5,5 @@ declare(strict_types=1);
// This file is only here so that the PHP8 attribute for doesn't throw an error in files
class ReturnTypeWillChange
{
//
}

@ -7,6 +7,7 @@ parameters:
excludePaths:
- vendor
- flight/util/ReturnTypeWillChange.php
- tests/named-arguments
paths:
- flight
- index.php

@ -22,6 +22,7 @@
<testsuites>
<testsuite name="default">
<directory>tests/</directory>
<exclude>tests/named-arguments/</exclude>
</testsuite>
</testsuites>
<logging />

@ -4,7 +4,6 @@ declare(strict_types=1);
namespace tests;
use ErrorException;
use Exception;
use flight\database\PdoWrapper;
use flight\Engine;

@ -389,7 +389,7 @@ class FlightTest extends TestCase
html;
// if windows replace \n with \r\n
$html = str_replace("\n", PHP_EOL, $html);
$html = str_replace(["\n", "\r\n"], PHP_EOL, $html);
$this->expectOutputString($html);

@ -233,8 +233,8 @@ class ViewTest extends TestCase
html;
$html1 = str_replace("\n", PHP_EOL, $html1);
$html2 = str_replace("\n", PHP_EOL, $html2);
$html1 = str_replace(["\n", "\r\n"], PHP_EOL, $html1);
$html2 = str_replace(["\n", "\r\n"], PHP_EOL, $html2);
return [
[

@ -105,15 +105,22 @@ PHP;
$app->handle(['runway', 'routes']);
$this->assertStringContainsString('Routes', file_get_contents(static::$ou));
$this->assertStringContainsString('+---------+-----------+-------+----------+----------------+
| Pattern | Methods | Alias | Streamed | Middleware |
+---------+-----------+-------+----------+----------------+
| / | GET, HEAD | | No | - |
| /post | POST | | No | Closure |
| /delete | DELETE | | No | - |
| /put | PUT | | No | - |
| /patch | PATCH | | No | Bad Middleware |
+---------+-----------+-------+----------+----------------+', $this->removeColors(file_get_contents(static::$ou)));
$expected = <<<'output'
+---------+-----------+-------+----------+----------------+
| Pattern | Methods | Alias | Streamed | Middleware |
+---------+-----------+-------+----------+----------------+
| / | GET, HEAD | | No | - |
| /post | POST | | No | Closure |
| /delete | DELETE | | No | - |
| /put | PUT | | No | - |
| /patch | PATCH | | No | Bad Middleware |
+---------+-----------+-------+----------+----------------+
output;
$this->assertStringContainsString(
$expected,
$this->removeColors(file_get_contents(static::$ou))
);
}
public function testGetPostRoute()

@ -0,0 +1,8 @@
<?php
declare(strict_types=1);
class ExampleClass
{
//
}

@ -0,0 +1,128 @@
<?php
declare(strict_types=1);
namespace Tests\PHP8;
use DateTimeImmutable;
use ExampleClass;
use Flight;
use flight\Container;
use flight\Engine;
use flight\net\Route;
use PHPUnit\Framework\TestCase;
use stdClass;
final class FlightTest extends TestCase
{
private Engine $engine;
protected function setUp(): void
{
$this->engine = new Engine;
Flight::init();
Flight::setEngine($this->engine);
}
//////////////////
// CORE METHODS //
//////////////////
public function test_path(): void
{
Flight::path(dir: __DIR__);
$exampleObject = new ExampleClass();
self::assertInstanceOf(ExampleClass::class, $exampleObject);
}
public function test_stop_with_code(): void
{
Flight::stop(code: 500);
self::expectOutputString('');
self::assertSame(500, Flight::response()->status());
}
public function test_halt(): void
{
Flight::halt(actuallyExit: false, code: 500, message: 'Test');
self::expectOutputString('Test');
self::assertSame(500, Flight::response()->status());
}
public function test_register(): void
{
Flight::register(
class: stdClass::class,
name: 'customClass',
callback: static function (stdClass $object): void {
$object->property = 'value';
},
params: []
);
$object = Flight::customClass();
self::assertInstanceOf(stdClass::class, $object);
self::assertObjectHasProperty('property', $object);
self::assertSame('value', $object->property);
Flight::unregister(methodName: 'customClass');
}
public function test_register_container(): void
{
$dateTime = new DateTimeImmutable();
$controller = new class($dateTime) {
public function __construct(private DateTimeImmutable $dateTime)
{
//
}
public function test(): void
{
echo $this->dateTime->format('Y-m-d');
}
};
Flight::registerContainerHandler(
containerHandler: new Container()
);
Flight::request()->url = '/test';
Flight::route(
pass_route: true,
alias: 'testRoute',
callback: [$controller::class, 'test'],
pattern: '/test'
);
self::expectOutputString($dateTime->format('Y-m-d'));
Flight::start();
}
/////////////////////
// ROUTING METHODS //
/////////////////////
public function test_static_route(): void
{
Flight::request()->url = '/test';
$route = Flight::route(
pass_route: true,
alias: 'testRoute',
callback: function () {
echo 'test';
},
pattern: '/test'
);
self::assertInstanceOf(Route::class, $route);
self::expectOutputString('test');
Flight::start();
}
}
Loading…
Cancel
Save