命令行内核

Testing Is Documentation

tests/Kernel/KernelConsoleTest.php命令行内核 - 图1

QueryPHP 命令行流程为入口接受输入,经过内核 kernel 传入输入,经过命令行应用程序调用命令执行业务,最后返回输出结果。

入口文件 leevel

  1. #!/usr/bin/env php
  2. <?php
  3. declare(strict_types=1);
  4. /*
  5. * This file is part of the forcodepoem package.
  6. *
  7. * The PHP Application Created By Code Poem. <Query Yet Simple>
  8. * (c) 2018-2099 http://forcodepoem.com All rights reserved.
  9. *
  10. * For the full copyright and license information, please view the LICENSE
  11. * file that was distributed with this source code.
  12. */
  13. use Common\App\ExceptionRuntime;
  14. use Common\App\Kernel;
  15. use Common\App\KernelConsole;
  16. use Leevel\Di\Container;
  17. use Leevel\Di\IContainer;
  18. use Leevel\Kernel\App;
  19. use Leevel\Kernel\IApp;
  20. use Leevel\Kernel\IExceptionRuntime;
  21. use Leevel\Kernel\IKernel;
  22. use Leevel\Kernel\IKernelConsole;
  23. /**
  24. * ---------------------------------------------------------------
  25. * Composer
  26. * ---------------------------------------------------------------.
  27. *
  28. * 用于管理 PHP 依赖包
  29. */
  30. require __DIR__.'/vendor/autoload.php';
  31. /**
  32. * ---------------------------------------------------------------
  33. * 创建应用
  34. * ---------------------------------------------------------------.
  35. *
  36. * 注册应用基础服务
  37. */
  38. $container = Container::singletons();
  39. $container->singleton(IContainer::class, $container);
  40. $container->singleton('app', new App($container, realpath(__DIR__)));
  41. $container->alias('app', [IApp::class, App::class]);
  42. $container->singleton(IKernel::class, Kernel::class);
  43. $container->singleton(IKernelConsole::class, KernelConsole::class);
  44. $container->singleton(IExceptionRuntime::class, ExceptionRuntime::class);
  45. /**
  46. * ---------------------------------------------------------------
  47. * 执行应用
  48. * ---------------------------------------------------------------.
  49. *
  50. * 根据内核调度请求返回响应
  51. */
  52. $kernel = $container->make(IKernelConsole::class);
  53. $status = $kernel->handle();
  54. $kernel->terminate($status);
  55. exit($status);

内核通过 \Leevel\Kernel\KernelConsole 的 handle 方法来实现请求。

handle 原型

  1. # Leevel\Kernel\KernelConsole::handle
  2. /**
  3. * 响应命令行请求.
  4. */
  5. public function handle(?InputInterface $input = null, ?OutputInterface $output = null): int;

Uses

  1. <?php
  2. use Leevel\Console\Application;
  3. use Leevel\Di\Container;
  4. use Leevel\Di\IContainer;
  5. use Leevel\Kernel\App as Apps;
  6. use Leevel\Kernel\IApp;
  7. use Leevel\Kernel\IKernelConsole;
  8. use Leevel\Kernel\KernelConsole;
  9. use Leevel\Option\IOption;
  10. use Symfony\Component\Console\Input\InputInterface;
  11. use Symfony\Component\Console\Output\OutputInterface;

基本使用

fixture 定义

Tests\Kernel\AppKernelConsole

  1. namespace Tests\Kernel;
  2. class AppKernelConsole extends Apps
  3. {
  4. public function namespacePath(string $specificClass, bool $throwException = true): string
  5. {
  6. return __DIR__.'/Commands/Console';
  7. }
  8. protected function registerBaseProvider(): void
  9. {
  10. }
  11. }

Tests\Kernel\Application1

  1. namespace Tests\Kernel;
  2. class Application1 extends Application
  3. {
  4. public function run(?InputInterface $input = null, ?OutputInterface $output = null)
  5. {
  6. return 0;
  7. }
  8. }

Tests\Kernel\KernelConsole1

  1. namespace Tests\Kernel;
  2. class KernelConsole1 extends KernelConsole
  3. {
  4. public function bootstrap(): void
  5. {
  6. }
  7. protected function getConsoleApplication(): Application
  8. {
  9. if ($this->consoleApplication) {
  10. return $this->consoleApplication;
  11. }
  12. return $this->consoleApplication = new Application1($this->app->container(), $this->app->version());
  13. }
  14. }

Tests\Kernel\Commands\Test

  1. namespace Tests\Kernel\Commands;
  2. use Leevel\Console\Command;
  3. class Test extends Command
  4. {
  5. protected string $name = 'test';
  6. protected string $description = 'This is a test command';
  7. protected string $help = <<<'EOF'
  8. The <info>%command.name%</info> command to show how to make a command:
  9. <info>php %command.full_name%</info>
  10. EOF;
  11. public function handle(): int
  12. {
  13. $this->info('Hello my test command.');
  14. return 0;
  15. }
  16. protected function getArguments(): array
  17. {
  18. return [];
  19. }
  20. protected function getOptions(): array
  21. {
  22. return [];
  23. }
  24. }

Tests\Kernel\Commands\Console\Foo

  1. namespace Tests\Kernel\Commands\Console;
  2. use Leevel\Console\Command;
  3. class Foo extends Command
  4. {
  5. protected string $name = 'console:foo';
  6. protected string $description = 'This is a foo command';
  7. protected string $help = <<<'EOF'
  8. The <info>%command.name%</info> command to show how to make a command:
  9. <info>php %command.full_name%</info>
  10. EOF;
  11. public function handle(): int
  12. {
  13. $this->info('Hello my foo command.');
  14. return 0;
  15. }
  16. protected function getArguments(): array
  17. {
  18. return [];
  19. }
  20. protected function getOptions(): array
  21. {
  22. return [];
  23. }
  24. }

Tests\Kernel\Commands\Console\Bar

  1. namespace Tests\Kernel\Commands\Console;
  2. use Leevel\Console\Command;
  3. class Bar extends Command
  4. {
  5. protected string $name = 'console:bar';
  6. protected string $description = 'This is a foo command';
  7. protected string $help = <<<'EOF'
  8. The <info>%command.name%</info> command to show how to make a command:
  9. <info>php %command.full_name%</info>
  10. EOF;
  11. public function handle(): int
  12. {
  13. $this->info('Hello my foo command.');
  14. return 0;
  15. }
  16. protected function getArguments(): array
  17. {
  18. return [];
  19. }
  20. protected function getOptions(): array
  21. {
  22. return [];
  23. }
  24. }
  1. public function testBaseUse(): void
  2. {
  3. $app = new AppKernelConsole($container = new Container(), '');
  4. $container->instance('app', $app);
  5. $this->createOption($container);
  6. $kernel = new KernelConsole1($app);
  7. $this->assertInstanceof(IKernelConsole::class, $kernel);
  8. $this->assertInstanceof(IApp::class, $kernel->getApp());
  9. $this->assertSame(0, $kernel->handle());
  10. }