symfony/console 的接入和使用
基本
#创建目录 test-project
mkdir test-project
cd test-project
#composer 初始化,然后回车回车就行了
composer init
#创建app 目录
mkdir app
#然后在composer.json里的加入
"autoload": {
"psr-4": {
"App\\" : "./app"
}
}
#自动加载
composer dump-autoload
安装
composer require symfony/finder
composer require symfony/console
//console 文件
#!/usr/bin/env php
<?php
require_once 'vendor/autoload.php';
use App\Src\CommandLoader;
! defined('ROOT_PATH') && define('ROOT_PATH', __DIR__);
! defined('APP_PATH') && define('APP_PATH', ROOT_PATH."/app");
/**
* @var $application \Symfony\Component\Console\Application
*/
$application = (new CommandLoader())->application();
$application->run();
//app\Src\CommandLoader.php
<?php
namespace App\Src;
use Symfony\Component\Console\Application;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Finder\Finder;
use Symfony\Component\Finder\SplFileInfo;
use Symfony\Contracts\Service\ResetInterface;
class CommandLoader
{
protected string $path = APP_PATH.'/Command';
protected string $namespace = "\\App\\Command\\";
protected Application $application;
//默认有的
protected $default = [
];
public function __construct()
{
$this->application = new Application();
$this->load();
$this->loadDefault();
}
protected function loadDefault()
{
foreach($this->default as $class)
{
$this->application->add(new $class);
}
}
/**
* 遍历 加载 command 目录下的类
*/
protected function load()
{
$finder = new Finder();
$finder->files()
->in($this->path)
->name('*.php');
foreach ($finder as $file)
{
$className = $this->getClassName($file);
$reflectionClass = new \ReflectionClass($className);
if ($reflectionClass->isAbstract())
{
//echo "$className 是抽象类不加载\n";
continue;
}//end if isAbs
/**
* @var $instance Command
*/
$instance = $reflectionClass->newInstance();
if (! $instance instanceof Command)
{
//echo "$className 不继承 Command 不加载\n";
continue;
}//end if instanceof
$this->application->add($instance);
}//end foreach finder
}//end init()
/**
* @return Application
*/
public function application():Application
{
return $this->application;
}//end loader
/**获取命名空间+类名的形式
* @param SplFileInfo $file
* @return string 类名 \App\Command\Xxx
*/
protected function getClassName(SplFileInfo $file):string
{
if ($file->getRelativePath() != '')
{
$className = $this->namespace.$file->getRelativePath()."\\".$file->getFilenameWithoutExtension();
}else
{
$className = $this->namespace.$file->getFilenameWithoutExtension();
}
return $className;
}
}
//app\Command\BaseCommand.php
<?php
namespace App\Command;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
//如果有公共方法就写在这里
abstract class BaseCommand extends Command
{
protected OutputInterface $output;
protected InputInterface $input;
protected function initialize(InputInterface $input, OutputInterface $output)
{
parent::initialize($input, $output); // TODO: Change the autogenerated stub
$this->output = $output;
$this->input = $input;
}
//监听信号
public function listenForSignals($callback = null)
{
if ($callback == null)
{
$callback = [$this, 'sigalHandler'];
}
//绑定QUIT信号
pcntl_signal(SIGQUIT, $callback);
pcntl_signal(SIGTERM, $callback);
pcntl_signal(SIGHUP, $callback);
pcntl_signal(SIGINT, $callback);
}
//信号处理函数
protected function sigalHandler($signo)
{
$this->output->writeln([
"",
"----------------",
"收到信号:{$signo}",
"----------------",
]);
exit;
// switch ($signo) {
// case SIGTERM:
// case SIGHUP:
// case SIGINT:
// case SIGQUIT:
// $this->loop = false;
// echo "信号:{$signo}\n";
// break;
// default:
// // 处理所有其他信号
// }
}
}
//创建测试的 app\Command\Test.php
<?php
namespace App\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
class Test extends BaseCommand
{
protected function configure()
{
$this->setName('test')->setDescription('测试');
}
protected function execute(InputInterface $input, OutputInterface $output)
{
$this->output->writeln([
'HI',
'HI',
]);
return 1;
}
}
//执行
php console test