diff --git a/.travis.yml b/.travis.yml index 2dda39e..7183b4b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,10 +1,10 @@ language: php php: - - 7.0 - - 7.1 - - 7.2 + - 8.0 + - 8.1 + - 8.2 install: - - pecl install swoole-1.10.3 + - pecl install swoole-4.8.13 - composer update script: - vendor/bin/phpunit diff --git a/composer.json b/composer.json index 4bdf5a7..7f72881 100644 --- a/composer.json +++ b/composer.json @@ -14,16 +14,16 @@ } ], "require": { - "php": ">=5.6.0", + "php": ">=7.4", "nikic/fast-route": "1.2.*", - "monolog/monolog": "~1.0", + "monolog/monolog": "^1.27", "psr/http-message": "^1.0", - "symfony/console": "^3.0 || ^4.0", - "psy/psysh": "^0.7.2 || ^0.8.0 || ^0.9.0", - "symfony/dotenv": "^3.3 || ^4.0" + "symfony/console": "^5.4", + "psy/psysh": "^0.11", + "symfony/dotenv": "^5.4" }, "require-dev": { - "phpunit/phpunit": "~6.0" + "phpunit/phpunit": "^9.6" }, "suggest": { "ext-swoole": "Run blink application under Swoole with visible performance improvements" diff --git a/phpunit.xml b/phpunit.xml index c0d7db1..0e278db 100644 --- a/phpunit.xml +++ b/phpunit.xml @@ -1,5 +1,6 @@ - + xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/9.3/phpunit.xsd"> + + + app/ + + ./tests/ - - - app/ - - diff --git a/src/core/ServiceLocator.php b/src/core/ServiceLocator.php index dfdef9e..edc75e6 100644 --- a/src/core/ServiceLocator.php +++ b/src/core/ServiceLocator.php @@ -3,6 +3,9 @@ namespace blink\core; use blink\di\Container; +use ReflectionClass; +use ReflectionNamedType; +use ReflectionParameter; /** * Class ServiceLocator @@ -57,17 +60,28 @@ public function get($id) /** * Call the given callback or class method with dependency injection. * - * @param $callback + * @param callable $callback * @param array $arguments * @return mixed */ - public function call($callback, $arguments = []) + public function call(callable $callback, array $arguments = []) { - $dependencies = $this->getMethodDependencies($callback, $arguments); + $dependencies = $this->getMethodDependencies($callback, array_values($arguments)); return call_user_func_array($callback, $dependencies); } + protected function getParameterClass(ReflectionParameter $parameter): ?ReflectionClass + { + $type = $parameter->getType(); + + if ($type instanceof ReflectionNamedType) { + return new ReflectionClass($type->getName()); + } else { + return null; + } + } + protected function getMethodDependencies($callback, array $arguments = []) { $dependencies = $arguments; @@ -76,7 +90,7 @@ protected function getMethodDependencies($callback, array $arguments = []) foreach ($parameters as $key => $parameter) { if ($parameter->isDefaultValueAvailable()) { $dependencies[] = $parameter->getDefaultValue(); - } elseif ($class = $parameter->getClass()) { + } elseif ($class = $this->getParameterClass($parameter)) { $dependencies[] = $this->get($class->getName()); } else { throw new InvalidParamException('Missing required argument: ' . $parameter->getName()); diff --git a/src/di/Container.php b/src/di/Container.php index fd13a19..aed406c 100644 --- a/src/di/Container.php +++ b/src/di/Container.php @@ -12,6 +12,7 @@ use ReflectionClass; use blink\core\BaseObject; use blink\core\InvalidConfigException; +use ReflectionNamedType; /** * Container implements a [dependency injection](http://en.wikipedia.org/wiki/Dependency_injection) container. @@ -482,8 +483,8 @@ protected function getDependencies($class) if ($param->isDefaultValueAvailable()) { $dependencies[] = $param->getDefaultValue(); } else { - $c = $param->getClass(); - $dependencies[] = Instance::of($c === null ? null : $c->getName()); + $c = $param->getType(); + $dependencies[] = Instance::of($c instanceof ReflectionNamedType ? $c->getName() : null); } } } diff --git a/src/http/CookieBag.php b/src/http/CookieBag.php index 13f7d4a..357532f 100644 --- a/src/http/CookieBag.php +++ b/src/http/CookieBag.php @@ -10,6 +10,7 @@ use ArrayIterator; use IteratorAggregate; use blink\core\BaseObject; +use Traversable; /** * Class CookieBag @@ -28,12 +29,12 @@ public function __construct(array $cookies = [], $config = []) parent::__construct($config); } - public function replace(array $cookies) + public function replace(array $cookies): void { $this->cookies = self::normalize($cookies); } - public static function normalize(array $cookies) + public static function normalize(array $cookies): array { foreach ($cookies as $name => $value) { if (!$value instanceof Cookie) { @@ -50,7 +51,7 @@ public static function normalize(array $cookies) * @return Cookie[] * @since 0.3.0 */ - public function all() + public function all(): array { return $this->cookies; } @@ -58,7 +59,7 @@ public function all() /** * Returns a cookie by name. * - * @param $name + * @param string $name * @return Cookie|null */ public function get($name) @@ -71,7 +72,7 @@ public function get($name) * * @param Cookie $cookie */ - public function add(Cookie $cookie) + public function add(Cookie $cookie): void { $this->cookies[$cookie->name] = $cookie; } @@ -79,10 +80,10 @@ public function add(Cookie $cookie) /** * Returns whether a cookie is exists. * - * @param $name + * @param string $name * @return bool */ - public function has($name) + public function has(string $name): bool { return isset($this->cookies[$name]); } @@ -90,19 +91,19 @@ public function has($name) /** * Remove a cookie by name. * - * @param $name + * @param string $name */ - public function remove($name) + public function remove(string $name) { unset($this->cookies[$name]); } - public function count() + public function count(): int { return count($this->cookies); } - public function getIterator() + public function getIterator(): Traversable { return new ArrayIterator($this->cookies); } diff --git a/src/http/FileBag.php b/src/http/FileBag.php index 98c5ec7..7eb0b2b 100644 --- a/src/http/FileBag.php +++ b/src/http/FileBag.php @@ -6,6 +6,7 @@ use ArrayIterator; use blink\core\BaseObject; use IteratorAggregate; +use Traversable; /** * FileBag represents a set of uploaded files. @@ -90,12 +91,12 @@ public function first($name) } } - public function count() + public function count(): int { return count($this->files); } - public function getIterator() + public function getIterator(): Traversable { return new ArrayIterator($this->files); } diff --git a/src/http/HeaderBag.php b/src/http/HeaderBag.php index 3b30844..26c970e 100644 --- a/src/http/HeaderBag.php +++ b/src/http/HeaderBag.php @@ -44,6 +44,7 @@ public function first($key, $default = null) return !empty($values) ? array_shift($values) : $default; } + #[\ReturnTypeWillChange] public function jsonSerialize() { return $this->all(); diff --git a/src/http/Request.php b/src/http/Request.php index b502828..50c72e8 100644 --- a/src/http/Request.php +++ b/src/http/Request.php @@ -337,6 +337,8 @@ private function parseBody($body) $parsedBody = $this->parseQueryString($body); } elseif ($contentType === 'multipart/form-data') { // noop + } elseif ($contentType === 'application/xml' || $contentType === 'text/xml') { + $parsedBody = (array)simplexml_load_string($body, null, LIBXML_NOCDATA); } else { throw new NotSupportedException("The content type: '$contentType' does not supported"); } diff --git a/src/support/BagTrait.php b/src/support/BagTrait.php index cb626d6..0e30890 100644 --- a/src/support/BagTrait.php +++ b/src/support/BagTrait.php @@ -3,6 +3,7 @@ namespace blink\support; use ArrayIterator; +use Traversable; trait BagTrait { @@ -88,12 +89,12 @@ public function remove($key) unset($this->data[$this->transformKey($key)]); } - public function count() + public function count(): int { return count($this->data); } - public function getIterator() + public function getIterator(): Traversable { return new ArrayIterator($this->data); } @@ -101,7 +102,8 @@ public function getIterator() /** * @inheritDoc */ - public function offsetExists($offset) + #[\ReturnTypeWillChange] + public function offsetExists($offset): bool { return $this->has($offset); } @@ -109,6 +111,7 @@ public function offsetExists($offset) /** * @inheritDoc */ + #[\ReturnTypeWillChange] public function offsetGet($offset) { return $this->get($offset); @@ -117,16 +120,17 @@ public function offsetGet($offset) /** * @inheritDoc */ - public function offsetSet($offset, $value) + #[\ReturnTypeWillChange] + public function offsetSet($offset, $value): void { - return $this->set($offset, $value); + $this->set($offset, $value); } /** * @inheritDoc */ - public function offsetUnset($offset) + public function offsetUnset($offset): void { - return $this->remove($offset); + $this->remove($offset); } } diff --git a/src/testing/TestCase.php b/src/testing/TestCase.php index 21b48aa..8836647 100644 --- a/src/testing/TestCase.php +++ b/src/testing/TestCase.php @@ -15,7 +15,7 @@ abstract class TestCase extends BaseTestCase abstract public function createApplication(); - public function setUp() + public function setUp(): void { if (!$this->app) { $this->app = $this->createApplication()->bootstrapIfNeeded(); @@ -33,7 +33,7 @@ public function actor() return new RequestActor($this, $this->createApplication()->bootstrapIfNeeded()); } - public function tearDown() + public function tearDown(): void { if ($this->app) { $this->app->shutdown(); diff --git a/tests/bootstrap.php b/tests/bootstrap.php index 9a6e7af..c6e361c 100644 --- a/tests/bootstrap.php +++ b/tests/bootstrap.php @@ -1,3 +1,5 @@ logFile = __DIR__ . '/test.log'; } - public function tearDown() + public function tearDown(): void { if (file_exists($this->logFile)) { unlink($this->logFile); @@ -47,7 +47,7 @@ protected function createLogger($logFile) ]); } - public function testLogBasic() + public function testLogBasic(): void { $log = $this->createLogger($this->logFile); @@ -58,11 +58,11 @@ public function testLogBasic() $content = file_get_contents($this->logFile); - $this->assertContains('alert message', $content); - $this->assertNotContains('info message', $content); + $this->assertStringContainsString('alert message', $content); + $this->assertStringNotContainsString('info message', $content); } - public function testLogException() + public function testLogException(): void { $log = $this->createLogger($this->logFile); diff --git a/tests/session/SessionTest.php b/tests/session/SessionTest.php index 3604995..a4dac87 100644 --- a/tests/session/SessionTest.php +++ b/tests/session/SessionTest.php @@ -11,7 +11,7 @@ class SessionTest extends TestCase { private $sessionPath; - public function setUp() + public function setUp(): void { $this->sessionPath = __DIR__ . '/sessions'; mkdir($this->sessionPath); @@ -19,7 +19,7 @@ public function setUp() parent::setUp(); } - public function tearDown() + public function tearDown(): void { foreach (new \DirectoryIterator($this->sessionPath) as $file) { if (!$file->isDot()) {