Browse Source

Spiral Framework v3.7 (#8157)

* Update Spiral Framework

* Call run outside of the cycle

* Fix queries default value
Maxim Smakouz 2 years ago
parent
commit
0e204cf8e2

+ 2 - 0
frameworks/PHP/spiral/.env

@@ -4,3 +4,5 @@ DB_DSN=mysql:host=tfb-database:3306;charset=utf8;dbname=hello_world;user=benchma
 
 
 # Set to application specific value, used to encrypt/decrypt cookies and etc.
 # Set to application specific value, used to encrypt/decrypt cookies and etc.
 ENCRYPTER_KEY=def00000f6f989c4ba99b5eec3dcd4f5b0fb7e5fbbf95d3cacb6b7ed049e22b4a931db7ad59085225b36d051fb06530c8a41b83d10761439326656536293473c2472d911
 ENCRYPTER_KEY=def00000f6f989c4ba99b5eec3dcd4f5b0fb7e5fbbf95d3cacb6b7ed049e22b4a931db7ad59085225b36d051fb06530c8a41b83d10761439326656536293473c2472d911
+
+TOKENIZER_CACHE_TARGETS=true

+ 1 - 1
frameworks/PHP/spiral/.rr.yaml

@@ -1,4 +1,4 @@
-version: '2.7'
+version: '3'
 
 
 rpc:
 rpc:
   listen: tcp://127.0.0.1:6001
   listen: tcp://127.0.0.1:6001

+ 3 - 3
frameworks/PHP/spiral/README.md

@@ -6,11 +6,11 @@ Benchmark code is located in `app/src/Controllers/BenchmarkController.php`.
 
 
 ## Infrastructure and Versions
 ## Infrastructure and Versions
 The tests were run with:
 The tests were run with:
-* [Spiral Framework Version 2](https://github.com/spiral/framework/)
+* [Spiral Framework Version 3.7](https://github.com/spiral/framework/)
 * [Spiral/Stempler](https://github.com/spiral/stempler) as template engine
 * [Spiral/Stempler](https://github.com/spiral/stempler) as template engine
 * [Cycle ORM 2.*](https://github.com/cycle/orm)
 * [Cycle ORM 2.*](https://github.com/cycle/orm)
-* [RoadRunner 2.*](https://roadrunner.dev/)
-* [PHP Version 8.0.*](http://www.php.net/) in CLI mode with OPCache
+* [RoadRunner 2023.*](https://roadrunner.dev/)
+* [PHP Version 8.2.*](http://www.php.net/) in CLI mode with OPCache
 
 
 ## Test URLs
 ## Test URLs
 Test                | URL 
 Test                | URL 

+ 14 - 15
frameworks/PHP/spiral/app.php

@@ -1,23 +1,22 @@
 <?php
 <?php
-/**
- * Spiral Framework.
- *
- * @license   MIT
- * @author    Anton Titov (Wolfy-J)
- */
+
 declare(strict_types=1);
 declare(strict_types=1);
 
 
-mb_internal_encoding('UTF-8');
-error_reporting(E_ALL | E_STRICT);
-ini_set('display_errors', 'stderr');
+use App\App;
+
+\mb_internal_encoding('UTF-8');
+\error_reporting(E_ALL | E_STRICT ^ E_DEPRECATED);
+\ini_set('display_errors', 'stderr');
 
 
-//Composer
+// Register Composer's auto loader.
 require __DIR__ . '/vendor/autoload.php';
 require __DIR__ . '/vendor/autoload.php';
 
 
-//Initiating shared container, bindings, directories and etc
-$app = \App\App::init(['root' => __DIR__]);
+// Initialize shared container, bindings, directories and etc.
+$app = App::create(directories: ['root' => __DIR__])->run();
 
 
-if ($app !== null) {
-    $code = (int)$app->serve();
-    exit($code);
+if ($app === null) {
+    exit(255);
 }
 }
+
+$code = (int)$app->serve();
+exit($code);

+ 10 - 18
frameworks/PHP/spiral/app/src/App.php

@@ -1,16 +1,11 @@
 <?php
 <?php
-/**
- * Spiral Framework.
- *
- * @license   MIT
- * @author    Anton Titov (Wolfy-J)
- */
+
 declare(strict_types=1);
 declare(strict_types=1);
 
 
 namespace App;
 namespace App;
 
 
-use App\Bootloader\DebugBootloader;
 use App\Bootloader\RoutesBootloader;
 use App\Bootloader\RoutesBootloader;
+use Spiral\Boot\Bootloader\CoreBootloader;
 use Spiral\Bootloader;
 use Spiral\Bootloader;
 use Spiral\DotEnv\Bootloader as DotEnv;
 use Spiral\DotEnv\Bootloader as DotEnv;
 use Spiral\Framework\Kernel;
 use Spiral\Framework\Kernel;
@@ -19,31 +14,33 @@ use Spiral\Cycle\Bootloader as CycleBridge;
 use Spiral\RoadRunnerBridge\Bootloader as RoadRunnerBridge;
 use Spiral\RoadRunnerBridge\Bootloader as RoadRunnerBridge;
 use Spiral\Stempler\Bootloader as Stempler;
 use Spiral\Stempler\Bootloader as Stempler;
 use Spiral\Scaffolder\Bootloader as Scaffolder;
 use Spiral\Scaffolder\Bootloader as Scaffolder;
+use Spiral\Tokenizer\Bootloader\TokenizerListenerBootloader;
 
 
 class App extends Kernel
 class App extends Kernel
 {
 {
+    protected const SYSTEM = [
+        CoreBootloader::class,
+        TokenizerListenerBootloader::class,
+        // Environment configuration
+        DotEnv\DotenvBootloader::class,
+    ];
+
     /*
     /*
      * List of components and extensions to be automatically registered
      * List of components and extensions to be automatically registered
      * within system container on application start.
      * within system container on application start.
      */
      */
     protected const LOAD = [
     protected const LOAD = [
-        // Environment configuration
-        DotEnv\DotenvBootloader::class,
-
         // Core Services
         // Core Services
         Bootloader\DebugBootloader::class,
         Bootloader\DebugBootloader::class,
         Bootloader\SnapshotsBootloader::class,
         Bootloader\SnapshotsBootloader::class,
 
 
         // Security and validation
         // Security and validation
         Bootloader\Security\EncrypterBootloader::class,
         Bootloader\Security\EncrypterBootloader::class,
-        Bootloader\Security\ValidationBootloader::class,
         Bootloader\Security\FiltersBootloader::class,
         Bootloader\Security\FiltersBootloader::class,
         Bootloader\Security\GuardBootloader::class,
         Bootloader\Security\GuardBootloader::class,
 
 
         RoadRunnerBridge\HttpBootloader::class,
         RoadRunnerBridge\HttpBootloader::class,
 
 
-        DebugBootloader::class,
-
         // HTTP extensions
         // HTTP extensions
         Nyholm\NyholmBootloader::class,
         Nyholm\NyholmBootloader::class,
         Bootloader\Http\RouterBootloader::class,
         Bootloader\Http\RouterBootloader::class,
@@ -67,12 +64,7 @@ class App extends Kernel
         // Framework commands
         // Framework commands
         Bootloader\CommandBootloader::class,
         Bootloader\CommandBootloader::class,
         RoadRunnerBridge\CommandBootloader::class,
         RoadRunnerBridge\CommandBootloader::class,
-    ];
 
 
-    /*
-     * Application specific services and extensions.
-     */
-    protected const APP = [
         RoutesBootloader::class,
         RoutesBootloader::class,
     ];
     ];
 }
 }

+ 0 - 37
frameworks/PHP/spiral/app/src/Bootloader/DebugBootloader.php

@@ -1,37 +0,0 @@
-<?php
-/**
- * Spiral Framework.
- *
- * @license   MIT
- * @author    Anton Titov (Wolfy-J)
- */
-declare(strict_types=1);
-
-namespace App\Bootloader;
-
-use Psr\Http\Message\ResponseInterface;
-use Psr\Http\Message\ServerRequestInterface;
-use Psr\Http\Server\MiddlewareInterface;
-use Psr\Http\Server\RequestHandlerInterface;
-use Spiral\Boot\Bootloader\Bootloader;
-use Spiral\Bootloader\Http\HttpBootloader;
-
-class DebugBootloader extends Bootloader implements MiddlewareInterface
-{
-    public function boot(HttpBootloader $http)
-    {
-        $http->addMiddleware(self::class);
-    }
-
-    public function process(
-        ServerRequestInterface $request,
-        RequestHandlerInterface $handler
-    ): ResponseInterface {
-        try {
-            return $handler->handle($request);
-        } catch (\Throwable $e) {
-            dumprr((string)$e);
-            throw $e;
-        }
-    }
-}

+ 19 - 20
frameworks/PHP/spiral/app/src/Bootloader/RoutesBootloader.php

@@ -1,30 +1,29 @@
 <?php
 <?php
-/**
- * Spiral Framework.
- *
- * @license   MIT
- * @author    Anton Titov (Wolfy-J)
- */
+
 declare(strict_types=1);
 declare(strict_types=1);
 
 
 namespace App\Bootloader;
 namespace App\Bootloader;
 
 
 use App\Controller\BenchmarkController;
 use App\Controller\BenchmarkController;
-use Spiral\Boot\Bootloader\Bootloader;
-use Spiral\Router\Route;
-use Spiral\Router\RouterInterface;
-use Spiral\Router\Target\Controller;
+use Spiral\Bootloader\Http\RoutesBootloader as BaseRoutesBootloader;
+use Spiral\Router\Loader\Configurator\RoutingConfigurator;
 
 
-class RoutesBootloader extends Bootloader
+final class RoutesBootloader extends BaseRoutesBootloader
 {
 {
-    /**
-     * @param RouterInterface $router
-     */
-    public function boot(RouterInterface $router)
+    protected function globalMiddleware(): array
+    {
+        return [];
+    }
+
+    protected function middlewareGroups(): array
+    {
+        return [];
+    }
+
+    protected function defineRoutes(RoutingConfigurator $routes): void
     {
     {
-        $router->addRoute(
-            'benchmark',
-            new Route('/<action>[/<queries>]', new Controller(BenchmarkController::class))
-        );
+        $routes
+            ->add('benchmark', '/<action>[/<queries>]')
+            ->controller(BenchmarkController::class);
     }
     }
-}
+}

+ 20 - 66
frameworks/PHP/spiral/app/src/Controller/BenchmarkController.php

@@ -1,10 +1,5 @@
 <?php
 <?php
-/**
- * Spiral Framework.
- *
- * @license   MIT
- * @author    Anton Titov (Wolfy-J)
- */
+
 declare(strict_types=1);
 declare(strict_types=1);
 
 
 namespace App\Controller;
 namespace App\Controller;
@@ -13,61 +8,32 @@ use App\Model\Fortune;
 use App\Model\Repository\FortuneRepository;
 use App\Model\Repository\FortuneRepository;
 use App\Model\Repository\WorldRepository;
 use App\Model\Repository\WorldRepository;
 use App\Model\World;
 use App\Model\World;
-use Cycle\ORM\Transaction;
+use Cycle\ORM\EntityManagerInterface;
 use Nyholm\Psr7\Response;
 use Nyholm\Psr7\Response;
+use Psr\Http\Message\ResponseInterface;
 use Spiral\Core\Container\SingletonInterface;
 use Spiral\Core\Container\SingletonInterface;
-use Spiral\Views\ViewInterface;
 use Spiral\Views\ViewsInterface;
 use Spiral\Views\ViewsInterface;
 
 
 final class BenchmarkController implements SingletonInterface
 final class BenchmarkController implements SingletonInterface
 {
 {
-    /** @var ViewInterface */
-    private $view;
-
-    /** @var Transaction */
-    private $transaction;
-
-    /** @var FortuneRepository */
-    private $fortunes;
-
-    /** @var WorldRepository */
-    private $worlds;
-
-    /** @var Response */
-    private $plain;
+    private ResponseInterface $plain;
 
 
-    /**
-     * @param ViewsInterface    $views
-     * @param Transaction       $transaction
-     * @param FortuneRepository $fortunes
-     * @param WorldRepository   $worlds
-     */
     public function __construct(
     public function __construct(
-        ViewsInterface $views,
-        Transaction $transaction,
-        FortuneRepository $fortunes,
-        WorldRepository $worlds
+        private readonly ViewsInterface $views,
+        private readonly EntityManagerInterface $entityManager,
+        private readonly FortuneRepository $fortunes,
+        private readonly WorldRepository $worlds
     ) {
     ) {
-        $this->view = $views->get('fortunes');
-
-        $this->transaction = $transaction;
-        $this->fortunes = $fortunes;
-        $this->worlds = $worlds;
-
         $this->plain = new Response(200, ['Content-Type' => 'text/plain', 'Server' => 'Spiral']);
         $this->plain = new Response(200, ['Content-Type' => 'text/plain', 'Server' => 'Spiral']);
         $this->plain->getBody()->write('Hello, World!');
         $this->plain->getBody()->write('Hello, World!');
     }
     }
 
 
-    /**
-     * @return array
-     */
-    public function json()
+    public function json(): array
     {
     {
         return ['message' => 'Hello, World!'];
         return ['message' => 'Hello, World!'];
     }
     }
 
 
     /**
     /**
-     * @return World|null
      * @throws \Exception
      * @throws \Exception
      */
      */
     public function db(): ?World
     public function db(): ?World
@@ -76,11 +42,9 @@ final class BenchmarkController implements SingletonInterface
     }
     }
 
 
     /**
     /**
-     * @param int $queries
-     * @return array
      * @throws \Exception
      * @throws \Exception
      */
      */
-    public function queries($queries = 1): array
+    public function queries(mixed $queries = null): array
     {
     {
         $queries = $this->clamp($queries);
         $queries = $this->clamp($queries);
 
 
@@ -105,51 +69,41 @@ final class BenchmarkController implements SingletonInterface
 
 
         $fortunes[] = $fortune;
         $fortunes[] = $fortune;
 
 
-        usort($fortunes, function ($left, $right) {
-            return strcmp($left->message, $right->message);
-        });
+        \usort($fortunes, static fn ($left, $right): int => \strcmp($left->message, $right->message));
 
 
-        return $this->view->render(compact('fortunes'));
+        return $this->views->render('fortunes', ['fortunes' => $fortunes]);
     }
     }
 
 
     /**
     /**
-     * @param int $queries
-     * @return array
      * @throws \Throwable
      * @throws \Throwable
      */
      */
-    public function updates($queries = 1): array
+    public function updates(mixed $queries = null): array
     {
     {
         $queries = $this->clamp($queries);
         $queries = $this->clamp($queries);
 
 
         $worlds = [];
         $worlds = [];
-
         while ($queries--) {
         while ($queries--) {
             $world = $this->worlds->findRandom();
             $world = $this->worlds->findRandom();
-            $world->randomNumber = random_int(1, 10000);
+            $world->randomNumber = \random_int(1, 10000);
 
 
-            $this->transaction->persist($world)->run();
+            $this->entityManager->persist($world);
 
 
             $worlds[] = $world;
             $worlds[] = $world;
         }
         }
 
 
+        $this->entityManager->run();
+
         return $worlds;
         return $worlds;
     }
     }
 
 
-    /**
-     * @return Response
-     */
-    public function plaintext(): Response
+    public function plaintext(): ResponseInterface
     {
     {
         return $this->plain;
         return $this->plain;
     }
     }
 
 
-    /**
-     * @param $value
-     * @return int
-     */
-    private function clamp($value): int
+    private function clamp(mixed $value): int
     {
     {
-        if (!is_numeric($value) || $value < 1) {
+        if (!\is_numeric($value) || $value < 1) {
             return 1;
             return 1;
         }
         }
 
 

+ 5 - 13
frameworks/PHP/spiral/app/src/Model/Fortune.php

@@ -1,10 +1,5 @@
 <?php
 <?php
-/**
- * Spiral Framework.
- *
- * @license   MIT
- * @author    Anton Titov (Wolfy-J)
- */
+
 declare(strict_types=1);
 declare(strict_types=1);
 
 
 namespace App\Model;
 namespace App\Model;
@@ -13,19 +8,16 @@ use App\Model\Repository;
 use Cycle\Annotated\Annotation\Column;
 use Cycle\Annotated\Annotation\Column;
 use Cycle\Annotated\Annotation\Entity;
 use Cycle\Annotated\Annotation\Entity;
 
 
-#[Entity(table: 'Fortune', repository: Repository\FortuneRepository::class)]
+#[Entity(table: 'fortune', repository: Repository\FortuneRepository::class)]
 class Fortune implements \JsonSerializable
 class Fortune implements \JsonSerializable
 {
 {
     #[Column(type: 'primary')]
     #[Column(type: 'primary')]
-    public $id;
+    public int $id;
 
 
     #[Column(type: 'text')]
     #[Column(type: 'text')]
-    public $message;
+    public string $message;
 
 
-    /**
-     * @return array
-     */
-    public function jsonSerialize(): mixed
+    public function jsonSerialize(): array
     {
     {
         return ['id' => $this->id, 'message' => $this->message];
         return ['id' => $this->id, 'message' => $this->message];
     }
     }

+ 3 - 9
frameworks/PHP/spiral/app/src/Model/Repository/FortuneRepository.php

@@ -1,17 +1,11 @@
 <?php
 <?php
-/**
- * Spiral Framework.
- *
- * @license   MIT
- * @author    Anton Titov (Wolfy-J)
- */
+
 declare(strict_types=1);
 declare(strict_types=1);
 
 
 namespace App\Model\Repository;
 namespace App\Model\Repository;
 
 
 use Cycle\ORM\Select\Repository;
 use Cycle\ORM\Select\Repository;
 
 
-class FortuneRepository extends Repository
+final class FortuneRepository extends Repository
 {
 {
-
-}
+}

+ 4 - 10
frameworks/PHP/spiral/app/src/Model/Repository/WorldRepository.php

@@ -1,10 +1,5 @@
 <?php
 <?php
-/**
- * Spiral Framework.
- *
- * @license   MIT
- * @author    Anton Titov (Wolfy-J)
- */
+
 declare(strict_types=1);
 declare(strict_types=1);
 
 
 namespace App\Model\Repository;
 namespace App\Model\Repository;
@@ -12,14 +7,13 @@ namespace App\Model\Repository;
 use App\Model\World;
 use App\Model\World;
 use Cycle\ORM\Select\Repository;
 use Cycle\ORM\Select\Repository;
 
 
-class WorldRepository extends Repository
+final class WorldRepository extends Repository
 {
 {
     /**
     /**
-     * @return World|null
      * @throws \Exception
      * @throws \Exception
      */
      */
     public function findRandom(): ?World
     public function findRandom(): ?World
     {
     {
-        return $this->findByPK(random_int(1, 10000));
+        return $this->findByPK(\random_int(1, 10000));
     }
     }
-}
+}

+ 5 - 13
frameworks/PHP/spiral/app/src/Model/World.php

@@ -1,10 +1,5 @@
 <?php
 <?php
-/**
- * Spiral Framework.
- *
- * @license   MIT
- * @author    Anton Titov (Wolfy-J)
- */
+
 declare(strict_types=1);
 declare(strict_types=1);
 
 
 namespace App\Model;
 namespace App\Model;
@@ -13,19 +8,16 @@ use App\Model\Repository;
 use Cycle\Annotated\Annotation\Column;
 use Cycle\Annotated\Annotation\Column;
 use Cycle\Annotated\Annotation\Entity;
 use Cycle\Annotated\Annotation\Entity;
 
 
-#[Entity(table: 'World', repository: Repository\WorldRepository::class)]
+#[Entity(table: 'world', repository: Repository\WorldRepository::class)]
 class World implements \JsonSerializable
 class World implements \JsonSerializable
 {
 {
     #[Column(type: 'primary')]
     #[Column(type: 'primary')]
-    public $id;
+    public int $id;
 
 
     #[Column(type: 'int', name: 'randomNumber')]
     #[Column(type: 'int', name: 'randomNumber')]
-    public $randomNumber;
+    public int $randomNumber;
 
 
-    /**
-     * @return array
-     */
-    public function jsonSerialize(): mixed
+    public function jsonSerialize(): array
     {
     {
         return ['id' => $this->id, 'randomNumber' => $this->randomNumber];
         return ['id' => $this->id, 'randomNumber' => $this->randomNumber];
     }
     }

+ 7 - 6
frameworks/PHP/spiral/composer.json

@@ -9,18 +9,19 @@
     }
     }
   ],
   ],
   "require": {
   "require": {
-    "php": ">=8.0",
-    "spiral/framework": "^2.9",
-    "spiral/nyholm-bridge": "^1.0",
-    "spiral/cycle-bridge": "^1.0",
-    "spiral/roadrunner-bridge": "^1.0"
+    "php": ">=8.1",
+    "spiral/framework": "^3.7",
+    "spiral/nyholm-bridge": "^1.3",
+    "spiral/cycle-bridge": "^2.4",
+    "spiral/roadrunner-bridge": "^3.0",
+    "spiral/roadrunner-cli": "^2.4"
   },
   },
   "scripts": {
   "scripts": {
     "post-create-project-cmd": [
     "post-create-project-cmd": [
       "php -r \"copy('.env.sample', '.env');\"",
       "php -r \"copy('.env.sample', '.env');\"",
       "php app.php encrypt:key -m .env",
       "php app.php encrypt:key -m .env",
       "php app.php configure -vv",
       "php app.php configure -vv",
-      "spiral get-binary"
+      "rr get-binary --quiet"
     ]
     ]
   },
   },
   "autoload": {
   "autoload": {

+ 1 - 1
frameworks/PHP/spiral/spiral.dockerfile

@@ -1,4 +1,4 @@
-FROM php:8.1.2
+FROM php:8.2.0-cli
 
 
 RUN docker-php-ext-install pdo_mysql > /dev/null
 RUN docker-php-ext-install pdo_mysql > /dev/null