@@ -3,8 +3,7 @@ Soli PHP Console
33
44Soli Console Component.
55
6- Table of Contents
7- =================
6+ ## Table of Contents
87
98 * [ 安装] ( #安装 )
109 * [ 使用] ( #使用 )
@@ -20,7 +19,7 @@ Table of Contents
2019
2120## 使用
2221
23- 如下我们编写 ` test .php` 文件,内容为:
22+ 如下我们编写 ` task .php` 文件,内容为:
2423
2524``` php
2625<?php
@@ -37,14 +36,17 @@ class Task extends \Soli\Console\Command
3736 /**
3837 * 默认执行的方法:index
3938 */
40- public function index()
39+ public function index($name = 'wukong' )
4140 {
42- return ' task:index' ;
41+ return "hello $name, in task:index.\n" ;
4342 }
4443
45- public function handle()
44+ /**
45+ * 命令行输入的参数将按顺序作为 action 的参数传入
46+ */
47+ public function handle($name = 'wukong', $alias = '孙行者')
4648 {
47- return ' task:handle' ;
49+ return "hello $name <$alias>, in task:handle.\n" ;
4850 }
4951}
5052
@@ -64,95 +66,232 @@ $app = new \Soli\Console\App();
6466echo $app->handle();
6567```
6668
67- 执行 task 类中的 index 方法:
69+ 1 . 执行 Task 类中的 index 方法:
70+
71+ ```
72+ php task.php task
73+ // 或
74+ php task.php task:index
75+ ```
76+
77+ 2 . 执行 Task 类中的 handle 方法:
78+
79+ ```
80+ php task.php task:handle
81+ ```
82+
83+ 3 . 命令行输入的参数将按顺序作为 action 的参数传入,例如输入两个参数 ` hulk ` 和 ` 绿巨人 ` 执行:
6884
69- php test.php task
70- // 或
71- php test.php task:index
85+ ```
86+ php task.php task:handle hulk 绿巨人
87+ ```
7288
73- 执行 task 类中的 handle 方法 :
89+ 将输出 :
7490
75- php test.php task:handle
91+ ```
92+ hello hulk <绿巨人>, in task:handle.
93+ ```
7694
7795## 编写多进程终端命令程序
7896
79- 我们可以结合 [ Soli Process] 编写多进程终端命令程序 ,
97+ ` Soli Console ` 结合 [ Soli Process] 可以让我们以编写终端命令程序的方式编写多进程程序 ,
8098同时复用项目中的已有的 Model / Service 等代码。
8199
82- 文件位置 [ examples/app/Console/Proc.php] ( examples/app/Console/Proc.php ) ,内容为:
100+ 注意这里的多进程只支持在 ` Unix-like ` 系统下运行。
101+
102+ 文件位置 [ examples/app/Console/Proc2.php] ( examples/app/Console/Proc2.php ) ,内容为:
83103
84104``` php
85105<?php
86106
87107namespace App\Console;
88108
89- class Proc extends \Soli\Console\Command
109+ /**
110+ * 终端命令结合多进程
111+ */
112+ class Proc2 extends \Soli\Console\Command
90113{
91- /**
92- * @var \Soli\Process
93- */
94- protected $process;
114+ /** @var bool $runnable 这个属性决定了action是否以多进程方式运行 */
115+ protected $runnable = false;
116+
117+ /** @var string $name 进程名称,只在 Linux 系统下起作用 */
118+ protected $name = 'soli console proc2';
119+
120+ /** @var int $count 进程数 */
121+ protected $count = 4;
122+
123+ /** @var bool $daemonize 是否以守护进程方式运行 */
124+ protected $daemonize = false;
125+
126+ /** @var bool $refork 是否自动补充退出的进程 */
127+ protected $refork = false;
95128
96- public function __construct(\Soli\Process $process)
129+ /** @var string $logFile 记录进程的输出、终止等信息到此文件 */
130+ protected $logFile = '/tmp/soli-console-proc2.log';
131+
132+ public function __construct()
97133 {
98- $process->name = 'soli console';
99- $process->count = 4;
100- $process->daemonize = false;
101- $process->logFile = '/tmp/soli-console-proc.log';
134+ // 针对不同的 action 可以选择是否使用多进程,以及指定不同的进程属性
135+ $action = $this->dispatcher->getActionName();
136+ switch ($action) {
137+ case 'command':
138+ $this->runnable = false;
139+ break;
140+ case 'process':
141+ $this->runnable = true;
142+ $this->logFile = null;
143+ break;
144+ case 'daemonize':
145+ $this->runnable = true;
146+ $this->daemonize = true;
147+ echo "Process output info in {$this->logFile}\n";
148+ break;
149+ case 'refork':
150+ $this->runnable = true;
151+ $this->refork = true;
152+ break;
153+ }
154+ }
102155
103- $this->process = $process;
156+ public function command($name = 'wukong')
157+ {
158+ echo "hello $name. just a command.\n";
104159 }
105160
106161 /**
107- * 默认执行的方法:index
162+ * $worker 参数将成为 action 的第一个参数,$worker 参数之后是从命令行输入的参数
108163 */
109- public function index( )
164+ public function process(\Soli\Process $worker, $name = 'wukong' )
110165 {
111- $this->process->name .= ' proc:index';
112-
113- $this->process->setJob(function ($worker) {
114- $this->doIndex($worker);
115- });
116-
117- $this->process->start();
166+ echo "hello $name. dump message from [worker:{$worker->id} {$worker->workerPid}] process.\n";
167+ }
118168
119- return "return message from master process.\n";
169+ public function daemonize(\Soli\Process $worker)
170+ {
171+ echo "dump message from [worker:{$worker->id} {$worker->workerPid}] daemonize process.\n";
120172 }
121173
122- protected function doIndex( $worker)
174+ public function refork(\Soli\Process $worker)
123175 {
124- echo "dump message from worker[ {$worker->id} {$worker->workerPid}] process.\n";
176+ echo "dump message from [worker: {$worker->id} {$worker->workerPid}] process.\n";
125177 }
126178}
127179```
128180
129- 执行前在当前项目根目录使用 composer 安装 [ Soli Process] 多进程包,注意只支持 ` Unix-like ` 系统:
181+ 与多进程相关的属性:
182+
183+ 属性名称 | 类型 | 默认值 | 描述
184+ ----------|--------|----------|-----------------------------------------
185+ runnable | bool | false | 这个属性决定了action是否以多进程方式运行
186+ name | string | '' | 进程名称,只在 Linux 系统下起作用
187+ count | int | 1 | 进程数
188+ daemonize | bool | false | 是否以守护进程方式运行
189+ refork | bool | true | 是否自动补充退出的进程
190+ logFile | string | null | 记录进程的输出、终止等信息的文件路径
191+
192+ 设置 ` runnable ` 为 ` true ` 时,action 以多进程方式运行,` $worker 参数将成为 action 的第一个参数,$worker 参数之后是从命令行输入的参数 ` 。
193+
194+ 设置 ` daemonize ` 属性为 ` true ` 时,将以守护进程的方式运行,所有输出内容将被重定向到 ` logFile ` 属性所指定的文件,
195+ 未指定 ` logFile ` 属性时,输出内容将会被丢弃。
196+
197+ 设置 ` refork ` 属性为 ` true ` 时,可以在进程退出(如程序出现异常)后自动补充新的进程。
198+
199+ 下面执行 Proc2 类中的各个 action 方法,看看实际的执行效果:
200+
201+ 1 . 执行 Proc2 类中的 command 方法:
202+
203+ ```
204+ php examples/console proc2:command
205+ ```
206+
207+ 将输出:
208+
209+ ```
210+ hello wukong. just a command.
211+ ```
212+
213+ 2 . 执行 Proc2 类中的 process 方法:
214+
215+ ```
216+ php examples/console proc2:process bajie
217+ ```
218+
219+ 将输出类似以下内容(原始信息还会有进程启动、退出等相关信息,这里为了便于阅读,只贴出了 worker 进程中的输出信息):
220+
221+ ```
222+ hello bajie. dump message from [worker:2 64163] process.
223+ hello bajie. dump message from [worker:1 64162] process.
224+ hello bajie. dump message from [worker:3 64164] process.
225+ hello bajie. dump message from [worker:4 64165] process.
226+ ```
227+
228+ action 以多进程方式运行时:` $worker 参数将成为 action 的第一个参数,$worker 参数之后是从命令行输入的参数 ` ,
229+ 如这里的方法定义,从第二个参数开始才是从终端输入的参数:
230+
231+ public function process(\Soli\Process $worker, $name = 'wukong')
232+
233+ 3 . 执行 Proc2 类中的 daemonize 方法:
234+
235+ ```
236+ php examples/console proc2:daemonize
237+ ```
238+
239+ 将输出:
240+ ```
241+ Process output info in /tmp/soli-console-proc2.log
242+ ```
243+
244+ 程序以守护进程的方式运行时,所有输出内容将被重定向到 ` logFile ` 属性所指定的文件,
245+
246+ 查看 ` /tmp/soli-console-proc2.log ` 的文件内容为(原始信息还会有进程启动、退出等相关信息,这里为了便于阅读,只贴出了 worker 进程中的输出信息):
247+
248+ ```
249+ dump message from [worker:2 64612] daemonize process.
250+ dump message from [worker:3 64613] daemonize process.
251+ dump message from [worker:1 64611] daemonize process.
252+ dump message from [worker:4 64614] daemonize process.
253+ ```
254+
255+ 4 . 执行 Proc2 类中的 refork 方法:
130256
131- composer require soliphp/process
257+ ```
258+ php examples/console proc2:refork
259+ ```
260+
261+ 将输出类似以下内容(原始信息还会有其他进程启动、退出等相关信息,这里为了便于阅读,只贴出了 ` 1 号 worker 进程 ` 的相关信息):
132262
133- 执行 proc 类中的 index 方法:
263+ ```
264+ [2018-11-08 20:49:57] [master 73312] [worker:1 73332] process started
265+ dump message from [worker:1 73332] process.
266+ [2018-11-08 20:49:57] [master 73312] [worker:1 73332] process stopped with status 0
267+ [2018-11-08 20:49:57] [master 73312] [worker:1 73339] process started
268+ dump message from [worker:1 73339] process.
269+ [2018-11-08 20:49:57] [master 73312] [worker:1 73339] process stopped with status 0
270+ [2018-11-08 20:49:57] [master 73312] [worker:1 73343] process started
271+ dump message from [worker:1 73343] process.
272+ [2018-11-08 20:49:57] [master 73312] [worker:1 73343] process stopped with status 0
273+ [2018-11-08 20:49:57] [master 73312] [worker:1 73346] process started
274+ dump message from [worker:1 73346] process.
275+ [2018-11-08 20:49:57] [master 73312] [worker:1 73346] process stopped with status 0
276+ [2018-11-08 20:49:57] [master 73312] [worker:1 73350] process started
277+ dump message from [worker:1 73350] process.
278+ [2018-11-08 20:49:57] [master 73312] [worker:1 73350] process stopped with status 0
279+ ```
134280
135- php examples/console proc
136- // 或
137- php examples/console proc:index
138-
139- 将输出类似以下内容(原始信息还会有进程退出等相关信息,这里为阅读方便只贴出了 worker master 进程中的输出信息):
281+ 设置 ` refork ` 属性为 ` true ` 时,可以在进程退出后自动补充新的进程。当程序需要保持进程数,而由于异常进程被退出时,refork 将相当有用。
140282
141- dump message from worker[2 56649] process.
142- dump message from worker[1 56648] process.
143- dump message from worker[3 56650] process.
144- dump message from worker[4 56651] process.
145- return message from master process.
283+ 可以看到 ` worker:1 ` 每次在执行完毕退出进程后,就会有新的进程 fork 出来,进行补充,保持进程数。
146284
147285## 示例
148286
149- 在 [ examples] 文件夹下提供了一个带目录结构的终端命令例子,感兴趣的同学可以前去翻看 。
287+ 在 [ examples] 文件夹下提供了一个带目录结构的终端命令示例,感兴趣的同学可以直接翻看 。
150288
151289 examples
152290 ├── app
153291 │ └── Console
154- │ ├── Proc.php > proc 命令文件
155- │ └── Task.php > task 命令文件
292+ │ ├── Proc.php > proc 命令使用 \Soli\Process 多进程的原始类文件
293+ │ ├── Proc2.php > proc2 命令结合 \Soli\Process 使用多进程的类文件
294+ │ └── Task.php > task 命令类文件
156295 ├── bootstrap.php > 配置一些引导信息
157296 └── console > 入口文件
158297
0 commit comments