Subversion Repositories php-qbpwcf

Rev

Rev 66 | Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
3 liveuser 1
<?php
2
 
3
/*
4
 
5
	QBPWCF, Quick Build PHP website Component base on Fedora Linux.
6
    Copyright (C) 2015~2024 Min-Jhin,Chen
7
 
8
    This file is part of QBPWCF.
9
 
10
    QBPWCF is free software: you can redistribute it and/or modify
11
    it under the terms of the GNU General Public License as published by
12
    the Free Software Foundation, either version 3 of the License, or
13
    (at your option) any later version.
14
 
15
    QBPWCF is distributed in the hope that it will be useful,
16
    but WITHOUT ANY WARRANTY; without even the implied warranty of
17
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18
    GNU General Public License for more details.
19
 
20
    You should have received a copy of the GNU General Public License
21
    along with QBPWCF.  If not, see <http://www.gnu.org/licenses/>.
22
 
23
*/
24
namespace qbpwcf;
25
 
26
/*
27
類別說明:
28
提供多執行序應用的類別.
29
參考資料:
30
https://www.php.net/manual/en/book.parallel.php
31
備註:
32
建構中
33
*/
34
class threads{
35
 
36
	/*
37
	#函式說明:
38
	#當前類別被呼叫的靜態方法不存在時,將會執行該函數,回報該方法不存在.
39
	#回傳結果:
40
	#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
41
	#$reuslt["error"],執行不正常結束的錯訊息陣列.
42
	#$result["function"],當前執行的函式名稱.
43
	#必填參數:
44
	#$method,物件,為物件實體或類別名稱,會自動置入該參數.
45
	#$arguments,陣列,為呼叫方法時所用的參數.
46
	#可省略參數:
47
	#無.
48
	#參考資料:
49
	#__call=>http://php.net/manual/en/language.oop5.overloading.php#object.callstatic
50
	#備註:
51
	#無.
52
	*/
53
	public function __call($method,$arguments){
54
 
55
		#取得當前執行的函式
56
		$result["function"]=__FUNCTION__;
57
 
58
		#設置執行不正常
59
		$result["status"]="false";
60
 
61
		#設置執行錯誤
62
		$result["error"][]=__NAMESPACE__ ."/".$method."() 不存在!";
63
 
64
		#設置所丟入的參數
65
		$result["error"][]=$arguments;
66
 
67
		#回傳結果
68
		return $result;
69
 
70
		}#function __call end
71
 
72
	/*
73
	#函式說明:
74
	#當前類別被呼叫的靜態方法不存在時,將會執行該函數,回報該方法不存在.
75
	#回傳結果:
76
	#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
77
	#$reuslt["error"],執行不正常結束的錯訊息陣列.
78
	#$result["function"],當前執行的函式名稱.
79
	#必填參數:
80
	#$method,物件,為物件實體或類別名稱,會自動置入該參數.
81
	#$arguments,陣列,為呼叫方法時所用的參數.
82
	#可省略參數:
83
	#無.
84
	#參考資料:
85
	#__call=>http://php.net/manual/en/language.oop5.overloading.php#object.callstatic
86
	#備註:
87
	#無.
88
	*/
89
	public static function __callStatic($method,$arguments){
90
 
91
		#取得當前執行的函式
92
		$result["function"]=__FUNCTION__;
93
 
94
		#設置執行不正常
95
		$result["status"]="false";
96
 
97
		#設置執行錯誤
98
		$result["error"][]="欲呼叫的". __NAMESPACE__ ."/".$method."() 不存在!";
99
 
100
		#設置所丟入的參數
101
		$result["error"][]=$arguments;
102
 
103
		#回傳結果
104
		return $result;
105
 
106
		}#function __callStatic end
107
 
108
	/*
109
	#函式說明:
110
	#展示多執行序運作.
111
	#回傳結果:
112
	#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
113
	#$reuslt["error"],執行不正常結束的錯訊息陣列.
114
	#$result["function"],當前執行的函式名稱.
115
	#必填參數:
116
	#無.
117
	#可省略參數:
118
	#無.
119
	#參考資料:
120
	#無.
121
	#備註:
122
	#無.
123
	改用 proc 試試 https://www.php.net/manual/en/function.proc-open.php
124
	*/
125
	public static function demo(){
126
 
127
		#執行demo
128
		var_dump(self::proc_demo());
129
 
130
		}#function demo end
131
 
132
	/*
133
	#函式說明:
134
	#透過proc展示多執行序運作.
135
	#回傳結果:
136
	#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
137
	#$reuslt["error"],執行不正常結束的錯訊息陣列.
138
	#$result["function"],當前執行的函式名稱.
139
	#必填參數:
140
	#無.
141
	#可省略參數:
142
	#無.
143
	#參考資料:
144
	#https://www.php.net/manual/en/function.proc-open.php
145
	#備註:
146
	#無.
147
	*/
148
	public static function proc_demo(){
149
 
150
		#初始化 descriptorspec
151
		$descriptorspec = array();
152
 
153
		#stdin is a pipe that the child will read from
154
		$descriptorspec[]=array("pipe", "r");
155
 
156
		#stdout is a pipe that the child will write to
157
		$descriptorspec[]=array("pipe", "w");
158
 
159
		#stderr is a pipe that the child will write to
160
		$descriptorspec[]=array("pipe", "w");
161
 
162
		#The initial working dir for the command. This must be an absolute directory path, or null if you want to use the default value (the working dir of the current PHP process) 
163
		$cwd = null;
164
 
165
		#An array with the environment variables for the command that will be run, or null to use the same environment as the current PHP process 
166
		$env = array("QBPWCF" => "Quick Build PHP Website Componment base on Fedora Linux");
167
 
168
		#初始化儲存要多執行序執行的程式
169
		$codes=array();
170
 
171
		#初始化要demo用的url
172
		$demoUrl="https://qbpwc.sourceforge.io/";
173
 
174
		#要多執行序執行的程式1
175
		$codes[]=array("bash","curl -v -L --ssl-reqd ".$demoUrl);
176
 
177
		#要多執行序執行的程式2
178
		$codes[]=array("bash","curl -v -L --ssl-reqd ".$demoUrl);
179
 
180
		#要多執行序執行的程式3
181
		$codes[]=array("bash","curl -v -L --ssl-reqd ".$demoUrl);
182
 
183
		#debug
184
		#var_dump(__LINE__,$codes);
185
 
186
		#儲存每個要執行的程式資訊
187
		$process=array();
188
 
189
		#針對每個要執行的程式內容
190
		foreach($codes as $index=>$code){
191
 
192
			#取得要用什麼程式執行
193
			$executeBy=$code[0];
194
 
195
			#取得要執行的程式內容
196
			$code=$code[1];
197
 
198
			#運行 php 程式,並儲存 resource
199
			$process[$index]["resource"] = proc_open($executeBy, $descriptorspec, $pipes, $cwd, $env);
200
 
201
			#儲存對應的 pipes
202
			$process[$index]["pipes"]=$pipes;
203
 
204
			#debug
205
			#var_dump(__LINE__,$process[$index]);
206
 
207
			#如果有成功執行
208
			if(is_resource($process[$index]["resource"])){
209
 
210
				#$pipes now looks like this:
211
				#0 => writeable handle connected to child stdin
212
				#1 => readable handle connected to child stdout
213
				#2 => readable handle connected to child stdin
214
 
215
				#寫入內容作為 $executeBy 的輸入
216
				$bytes2write=fwrite($process[$index]["pipes"][0], $code);
217
 
218
				#debug
219
				#var_dump(__LINE__,$bytes2write);
220
 
221
				#結束輸入
222
				fclose($process[$index]["pipes"][0]);
223
 
224
				}#if end
225
 
226
			#反之,代表運行 php 失敗
227
			else{
228
 
229
				#初始化暫存執行結果的變數
230
				$cmdRes=array();
231
 
232
				#設置執行失敗
233
				$cmdRes["status"]="false";
234
 
235
				#設置執行錯誤訊息
236
				$cmdRes["error"]="execute program by \"".$executeBy."\" failed!";
237
 
238
				#設置執行結果
239
				$result["content"][]=$cmdRes;
240
 
241
				}#else end
242
 
243
			}#foreach end
244
 
245
		#debug
246
		#var_dump(__LINE__,$process);
247
 
248
		#針對每個回饋
249
		foreach($process as $index => $ps){
250
 
251
			#取得 proc resource
252
			$resource=$ps["resource"];
253
 
254
			#取得標準輸出
255
			$stdout=stream_get_contents($process[$index]["pipes"][1]);
256
 
257
			#取得錯誤輸出
258
			$stderr=stream_get_contents($process[$index]["pipes"][2]);
259
 
260
			#debug
261
			#var_dump($stdout);
262
 
263
			#初始化暫存執行狀況的變數
264
			$cmdRes=array();
265
 
266
			#設置執行失敗訊息
267
			$cmdRes["error"]=$stderr;
268
 
269
			#設置執行結果
270
			$cmdRes["content"]=$stdout;
271
 
272
			#debug
273
			#var_dump($cmdRes);
274
 
275
			#結束讀取標準輸出
276
			fclose($process[$index]["pipes"][1]);
277
 
278
			#結束讀取錯誤輸出
279
			fclose($process[$index]["pipes"][2]);
280
 
281
			#It is important that you close any pipes before calling proc_close in order to avoid a deadlock
282
			$cmdRes["statusCode"] = proc_close($resource);
283
 
284
			#debug
285
			#var_dump($cmdRes["statusCode"]);
286
 
287
			#預設執行不正常
288
			$cmdRes["status"]="false";
289
 
290
			#如果執行正常
291
			if($cmdRes["statusCode"]===0){
292
 
293
				#設置執行正常
294
				$cmdRes["status"]="true";
295
 
296
				}#if end
297
 
298
			#保存結果
299
			$result["content"][]=$cmdRes;
300
 
301
			#debug
302
			#var_dump($result);
303
 
304
			}#foreach end
305
 
306
		#設置執行正常
307
		$result["status"]="true";
308
 
309
		#debug
310
		#var_dump($result);
311
 
312
		#回傳結果
313
		return $result;
314
 
315
		}#function proc_demo end
316
 
317
	/*
318
	#函式說明:
319
	#透過proc來多執行序運作.
320
	#回傳結果:
321
	#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
322
	#$reuslt["error"],執行不正常結束的錯訊息陣列.
323
	#$result["function"],當前執行的函式名稱.
324
	#$result["argu"],使用的參數.
325
	#$result["content"],陣列,每個元素為其指令執行的結果訊息陣列,key為"status"代表執行是否正常的識別;key為"statusCode"代表程式結束後回傳給對應executeBy程式的數值;key為"output"代表標準輸出,若為resource,則代表為pipe;key為"error"代表非標準輸出,若為resource,則代表為pipe;key為"input"代表成功輸入的指令;key為"process"代表該程序經proc_open後的process source;key為"proc_get_status"代表程序的資訊.
326
	#必填參數:
327
	#$conf["cmds"],字串陣列,每個元素代表要執行的指令與參數.
328
	#$conf["cmds"]=array();
329
	#可省略參數:
330
	#$conf["wait"],字串,是否需要等待所有程序結束,預設為"true"要等待;反之為"false"不要等待.
331
	#$conf["wait"]="false";
332
	#$conf["workingDir"],字串陣列,個別程式執行時的家目錄,預設不指定.
333
	#$conf["workingDir"]=array("path");
334
	#$conf["envs"],2維字串陣列,每個元素代表個別程式執行時的指定環境變數,key變數名稱;value為變數內容.預設為array("QBPWCF" => "Quick Build PHP Website Componment base on Fedora Linux");
335
	#$conf["envs"]=array(array("key"=>"value"));
336
	#$conf["executeBy"],字串陣列,每個元素代表個別指令要用什麼程式執行,預設為"bash".
337
	#$conf["executeBy"]=array("bash");
338
	#參考資料:
339
	#https://www.php.net/manual/en/function.proc-open.php
340
	#https://www.php.net/manual/en/function.proc-get-status.php
341
	#備註:
342
	#若需要取得當下的執行狀況,請使用 self::proc_update 來更新.
343
	*/
344
	public static function proc(&$conf){
345
 
346
		#初始化要回傳的變數
347
		$result=array();
348
 
349
		#初始化當前執行的函數名稱
350
		$result["function"]=__FUNCTION__;
351
 
352
		#如果 $conf 不為陣列
353
		if(gettype($conf)!="array"){
354
 
355
			#設置執行失敗
356
			$result["status"]="false";
357
 
358
			#設置執行錯誤訊息
359
			$result["error"][]="\$conf變數須為陣列形態";
360
 
361
			#如果傳入的參數為 null
362
			if($conf==null){
363
 
364
				#設置執行錯誤訊息
365
				$result["error"][]="\$conf變數不得為null,請檢查函數「".$result["function"]."」的參數設置有無正確!";
366
 
367
				}#if end
368
 
369
			#回傳結果
370
			return $result;
371
 
372
			}#if end
373
 
374
		#取得使用的參數
375
		$result["argu"]=$conf;
376
 
377
		#函式說明:
378
		#檢查必填與可省略的參數,可省略參數可指定預設要給與什麼數值內容.
379
		#回傳結果:
380
		#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
381
		#$result["error"],執行不正常結束的錯訊息陣列.
382
		#$result["simpleError"],簡單表示的錯誤訊息.
383
		#$result["function"],當前執行的函式名稱.
384
		#$result["argu"],設置給予的參數.
385
		#$result["passed"],識別要檢查的全體變數是否存在以及型態是否正確的變數,"true"代表檢查全部通過;"false"代表檢查不通過
386
		#$result[$shouldBeCheckedVarName]["varExist"],所檢查的變數是否存在,"false"代表不存在;"true"代表存在
387
		#$result[$shouldBeCheckedVarName]["varType"],所檢查的變數型態是否正確,"false"代表錯誤;"true"代表正確
388
		#$result[$shouldBeCheckedVarName]["error"],每個參數設定的錯誤訊息
389
		#$result["shouldNotBeEmpty"],不應該為空字串或控陣列的變數.
390
		#$result["argu"],字串陣列,目前輸入的參數名稱陣列.
391
		#$result["legalVarName"],字串陣列,合法可用的參數名稱陣列.
392
		#$result["notNeedVar"],字串陣列,多餘的參數名稱.
393
		#必填參數:
394
		#$conf["varInput"],陣列變數,要檢查的陣列變數,請在要檢查的參數前面加上&,這樣變動的結果才能被套用。
395
		$conf["variableCheck::checkArguments"]["varInput"]=&$conf;
396
		#$conf["referenceVarKey"],字串,$conf參數後面的key值,用於移除不要的參考陣列.
397
		$conf["variableCheck::checkArguments"]["referenceVarKey"]="variableCheck::checkArguments";
398
		#可省略參數:
399
		#$conf["mustBeFilledVariableName"],爲必填參數的變數名稱陣列,形態爲陣列變數,元素數量需要跟"mustBeFilledVariableType"參數的元素數量一致,例如: $conf["mustBeFilledVariableName"] = array("id","account","password");
400
		$conf["variableCheck::checkArguments"]["mustBeFilledVariableName"]=array("cmds");
401
		#$conf["mustBeFilledVariableType"],爲必填參數的變數陣列應該爲何種變數形態,形態爲陣列,元素數量需要跟"mustBeFilledVariableName"參數的元素數量一致,例如: $conf["mustBeFilledVariableType"] = array("string",integer,"double","resource","object"); , null代表不指定變數形態.
402
		$conf["variableCheck::checkArguments"]["mustBeFilledVariableType"]=array("array");
403
		#$conf["canBeEmptyString"],字串,必填變數內容如果是空字串就不能算是有設置的話,請設為"false",預設爲"true",可以為空字串.
404
		#$conf["variableCheck::checkArguments"]["canBeEmptyString"]="false";
405
		#$conf["canNotBeEmpty"],字串陣列,哪些必填參數的內容不得為空字串或空陣列,僅當$conf["canBeEmptyString"]為"true"時會生效.
406
		#$conf["canNotBeEmpty"]=array();
407
		#$conf["canBeEmpty"],字串陣列,哪些必填參數的內容可為空字串或空陣列,僅當$conf["canBeEmptyString"]為"false"時會生效.
408
		#$conf["canBeEmpty"]=array();
409
		#$conf["skipableVariableCanNotBeEmpty"],字串陣列,哪些可省略參數不可以為空字串或空陣列.
410
		$conf["variableCheck::checkArguments"]["skipableVariableCanNotBeEmpty"]=array("wait","workingDir","envs","executeBy");
411
		#$conf["skipableVariableName"],陣列字串,爲可省略參數的變數名稱陣列,形態爲陣列變數,例如: $conf["skipableVariableName"] = array("id","account","password");
412
		$conf["variableCheck::checkArguments"]["skipableVariableName"]=array("wait","workingDir","envs","executeBy");
413
		#$conf["skipableVariableType"],陣列字串,爲可省略參數的變數名稱陣列,形態爲陣列變數,例如: $conf["skipableVariableType"] = array("string",integer,"double");
414
		$conf["variableCheck::checkArguments"]["skipableVariableType"]=array("string","array","array","array");
415
		#$conf["skipableVarDefaultValue"],字串陣列,每個不存在的可省略變數要初始化為什麼,null與代表不指定,若預設值是參數之一,請將$conf["mustBeFilledVar"]改成"\$conf["\mustBeFilledVar\"]".
416
		$conf["variableCheck::checkArguments"]["skipableVarDefaultValue"]=array("true",null,null,null);
417
		#$conf["disallowAllSkipableVarIsEmpty"],字串,是否允許每個可省略參數都為空字串,預設為"true"允許,反之為"false".
418
		#$conf["disallowAllSkipableVarIsEmpty"]="";
419
		#$conf["disallowAllSkipableVarIsEmptyArray"],字串,是否允許每個可省略參數都為空陣列,預設為"true"允許,反之為"false".
420
		#$conf["disallowAllSkipableVarIsEmptyArray"]="";
421
		#$conf["disallowAllSkipableVarNotExist"],字串,是否不允許每個可省略參數都不存在,預設為"false"代表允許,反之為"true".
422
		#$conf["disallowAllSkipableVarNotExist"]="";
423
		#$conf["arrayCountEqualCheck"],字串陣列,為檢查哪些陣列參數的元素數量要一樣,$conf["arrayCountEqualCheck"][$i]=array()為第$i組key為哪些的變數其元素數量要相等.
424
		#$conf["variableCheck::checkArguments"]["arrayCountEqualCheck"][]=array("");
425
		#參考資料:
426
		#array_keys=>http://php.net/manual/en/function.array-keys.php
427
		#備註:
428
		#無.
429
		$checkArguments=variableCheck::checkArguments($conf["variableCheck::checkArguments"]);
430
		unset($conf["variableCheck::checkArguments"]);
431
 
432
		#如果 $checkArguments["status"] 等於 "false"
433
		if($checkArguments["status"]==="false"){
434
 
435
			#設置錯誤識別
436
			$result["status"]="false";
437
 
438
			#設置錯誤訊息
439
			$result["error"]=$checkArguments;
440
 
441
			#回傳結果
442
			return $result;
443
 
444
			}#if end
445
 
446
		#如果 $checkArguments["passed"] 等於 "false"
447
		if($checkArguments["passed"]==="false"){
448
 
449
			#設置錯誤識別
450
			$result["status"]="false";
451
 
452
			#設置錯誤訊息
453
			$result["error"]=$checkArguments;
454
 
455
			#回傳結果
456
			return $result;
457
 
458
			}#if end
459
 
460
		#初始化 descriptorspec
461
		$descriptorspec = array();
462
 
463
		#stdin is a pipe that the child will read from
464
		$descriptorspec[]=array("pipe", "r");
465
 
466
		#stdout is a pipe that the child will write to
467
		$descriptorspec[]=array("pipe", "w");
468
 
469
		#stderr is a pipe that the child will write to
470
		$descriptorspec[]=array("pipe", "w");
471
 
472
		#The initial working dir for the command. This must be an absolute directory path, or null if you want to use the default value (the working dir of the current PHP process) 
473
		$defaultCWD = null;
474
 
475
		#初始化儲存每個指令的working dir.
476
		$cwds=array();
477
 
478
		#有幾個指令就執行幾次
479
		for($i=0;$i<count($conf["cmds"]);$i++){
480
 
481
			#設置預設working dir
482
			$cwds[]=$defaultCWD;
483
 
484
			}#for end
485
 
486
		#如果有設置 workingDir
487
		if(isset($conf["workingDir"])){
488
 
489
			#如果數量符合
490
			if(count($conf["cmds"])===count($conf["workingDir"])){
491
 
492
				#有幾個指令就執行幾次
493
				for($i=0;$i<count($conf["cmds"]);$i++){
494
 
495
					#預設為指定數值
496
					$cwds[]=$conf["workingDir"][$i];
497
 
498
					}#for end
499
 
500
				}#if end
501
 
502
			}#if end
503
 
504
		#An array with the environment variables for the command that will be run, or null to use the same environment as the current PHP process 
505
		$defaultENV = array("QBPWCF" => "Quick Build PHP Website Componment base on Fedora Linux");
506
 
507
		#初始化儲存每個指令的環境變數.
508
		$envs=array();
509
 
510
		#有幾個指令就執行幾次
511
		for($i=0;$i<count($conf["cmds"]);$i++){
512
 
513
			#設置預設環境變數
514
			$envs[]=$defaultENV;
515
 
516
			}#for end
517
 
518
		#如果有設置 envs
519
		if(isset($conf["envs"])){
520
 
521
			#如果數量符合
522
			if(count($conf["cmds"])===count($conf["envs"])){
523
 
524
				#有幾個指令就執行幾次
525
				for($i=0;$i<count($conf["cmds"]);$i++){
526
 
527
					#預設為指定數值
528
					$envs[]=$conf["envs"][$i];
529
 
530
					}#for end
531
 
532
				}#if end
533
 
534
			}#if end
535
 
536
		#預設程式都透過 bash 來執行
537
		$defaultExecBy="bash";
538
 
539
		#初始化儲存每個指令要透過什麼程式執行
540
		$executeBys=array();
541
 
542
		#有幾個指令就執行幾次
543
		for($i=0;$i<count($conf["cmds"]);$i++){
544
 
545
			#設置預設環境變數
546
			$executeBys[]=$defaultExecBy;
547
 
548
			}#for end
549
 
550
		#如果有設置 executeBy
551
		if(isset($conf["executeBy"])){
552
 
553
			#如果數量符合
554
			if(count($conf["cmds"])===count($conf["executeBy"])){
555
 
556
				#初始化儲存每個指令要透過什麼程式執行
557
				$executeBys=array();
558
 
559
				#有幾個指令就執行幾次
560
				for($i=0;$i<count($conf["cmds"]);$i++){
561
 
562
					#預設為指定數值
563
					$executeBys[]=$conf["executeBy"][$i];
564
 
565
					}#for end
566
 
567
				}#if end
568
 
569
			}#if end
570
 
571
		#儲存每個要執行的程式資訊
572
		$process=array();
573
 
574
		#debug
575
		#var_dump(__LINE__,$executeBys);
576
 
577
		#針對每個指令與參數字串
578
		foreach($conf["cmds"] as $index=>$cmdAndArguStr){
579
 
580
			#debug
581
			#var_dump(__LINE__,$executeBys[$index]);
582
 
583
			#運行 php 程式,並儲存 resource
584
			$process[$index]["resource"] = proc_open($executeBys[$index], $descriptorspec, $pipes, $cwds[$index], $envs[$index]);
585
 
586
			#儲存對應的 pipes
587
			$process[$index]["pipes"]=$pipes;
588
 
589
			#如果有成功執行
590
			if(is_resource($process[$index]["resource"])){
591
 
592
				#$pipes now looks like this:
593
				#0 => writeable handle connected to child stdin
594
				#1 => readable handle connected to child stdout
595
				#2 => readable handle connected to child stdin
596
 
597
				#寫入內容作為 $executeBy 的輸入
598
				$bytes2write=fwrite($process[$index]["pipes"][0], $cmdAndArguStr);
599
 
600
				#結束輸入
601
				fclose($process[$index]["pipes"][0]);
602
 
603
				#如果有完整寫入指令
604
				if($bytes2write===strlen($cmdAndArguStr)){
605
 
606
					#記錄輸入的指令
607
					$process[$index]["input"]=$cmdAndArguStr;
608
 
609
					}#if end
610
 
611
				#反之
612
				else{
613
 
614
					#設置錯誤識別
615
					$result["status"]="false";
616
 
617
					#設置錯誤訊息
618
					$result["error"][]="將指令(".$cmdAndArguStr.")輸入(".$executeBys[$index].")失敗";
619
 
620
					#回傳結果
621
					return $result;
622
 
623
					}#else end
624
 
625
				}#if end
626
 
627
			#反之,代表運行 $executeBys[$index] 失敗
628
			else{
629
 
630
				#初始化暫存執行結果的變數
631
				$cmdRes=array();
632
 
633
				#設置執行失敗
634
				$cmdRes["status"]="false";
635
 
636
				#設置執行錯誤訊息
637
				$cmdRes["error"]="execute program by \"".$executeBys[$index]."\" failed!";
638
 
639
				#設置執行結果
640
				$result["content"][]=$cmdRes;
641
 
642
				}#else end
643
 
644
			}#foreach end
645
 
646
		#針對每個回饋
647
		foreach($process as $index => $ps){
648
 
649
			#取得 proc resource
650
			$resource=&$ps["resource"];
651
 
652
			#取得標準輸出的pipe
653
			$stdout=$process[$index]["pipes"][1];
654
 
655
			#取得非標準輸出的pipe
656
			$stderr=$process[$index]["pipes"][2];
657
 
658
			#如果需要等待程序執行完
659
			if($conf["wait"]==="true"){
660
 
661
				#取得標準輸出
662
				$stdout=stream_get_contents($process[$index]["pipes"][1]);
663
 
664
				#取得錯誤輸出
665
				$stderr=stream_get_contents($process[$index]["pipes"][2]);
666
 
667
				}#if end
668
 
669
			#反之
670
			else{
671
 
672
				#不讓標準輸出會阻擋程式執行
673
				stream_set_blocking($stdout,false);
674
 
675
				#不讓錯誤輸出會阻擋程式執行
676
				stream_set_blocking($stderr,false);
677
 
678
				}#else end
679
 
680
			#初始化暫存執行狀況的變數
681
			$cmdRes=array();
682
 
683
			#取得 proc_open 後的 process resource
684
			$cmdRes["process"]=$resource;
685
 
686
			#取得 process 的狀態,包含 pid 等資訊,若程式已經結束,則會自動將pipes關閉,再proc_close.
687
			$cmdRes["proc_get_status"]=proc_get_status($resource);
688
 
689
			#預設 statusCode 為 "?" 代表尚未 proc_close
690
			$cmdRes["statusCode"]="?";
691
 
692
			#如果執行已經結束,有回傳exitcode
693
			if($cmdRes["proc_get_status"]["exitcode"]!==-1){
694
 
695
				#設置 statusCode
696
				$cmdRes["statusCode"]=&$cmdRes["proc_get_status"]["exitcode"];
697
 
698
				}#if end
699
 
700
			#反之未執行完畢,且需要等待程序執行完
701
			else if($conf["wait"]==="true"){
702
 
703
				#無窮迴圈
704
				while(true){
705
 
706
					#取得 process 的狀態,包含 pid 等資訊,若程式已經結束,則會自動將pipes關閉,再proc_close.
707
					$cmdRes["proc_get_status"]=proc_get_status($resource);
708
 
709
					#如果執行已經結束,有回傳exitcode
710
					if($cmdRes["proc_get_status"]["exitcode"]!==-1){
711
 
712
						#設置 statusCode
713
						$cmdRes["statusCode"]=&$cmdRes["proc_get_status"]["exitcode"];
714
 
715
						#結束#無窮迴圈
716
						break;
717
 
718
						}#if end
719
 
720
					#等待1秒鐘
721
					sleep(1);
722
 
723
					}#while end
724
 
725
				}#if end
726
 
727
			#設置執行失敗訊息
728
			$cmdRes["error"]=$stderr;
729
 
730
			#設置執行結果
731
			$cmdRes["content"]=$stdout;
732
 
733
			#如果有成功輸入指令
734
			if(isset($process[$index]["input"])){
735
 
736
				#設置有輸入的指令
737
				$cmdRes["input"]=$process[$index]["input"];
738
 
739
				}#if end
740
 
741
			#預設執行不正常
742
			$cmdRes["status"]="false";
743
 
744
			#如果執行正常 或 等於"?"(代表尚未 proc_close)
745
			if($cmdRes["statusCode"]===0 || $cmdRes["statusCode"]==="?"){
746
 
747
				#設置執行正常
748
				$cmdRes["status"]="true";
749
 
750
				}#if end
751
 
752
			#保存結果
753
			$result["content"][]=$cmdRes;
754
 
755
			}#foreach end
756
 
757
		#設置執行正常
758
		$result["status"]="true";
759
 
760
		#回傳結果
761
		return $result;
762
 
763
		}#function proc end
764
 
765
	/*
766
	#函式說明:
767
	#更新透過proc執行的多程序資訊.
768
	#回傳結果:
769
	#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
770
	#$reuslt["error"],執行不正常結束的錯訊息陣列.
771
	#$result["function"],當前執行的函式名稱.
772
	#$result["argu"],使用的參數.
773
	#$result["content"],陣列,每個元素為其指令執行的結果訊息陣列,key為"status"代表執行是否正常的識別;key為"statusCode"代表程式結束後回傳給對應executeBy程式的數值;key為"output"代表標準輸出,若為resource,則代表為pipe;key為"error"代表非標準輸出,若為resource,則代表為pipe;key為"input"代表成功輸入的指令;key為"process"代表該程序經proc_open後的process source;key為"proc_get_status"代表程序的資訊.
774
	#必填參數:
775
	#$conf["procs"],陣列,運行self::proc後回傳的content.
776
	$conf["procs"]=$procs;
777
	#可省略參數:
778
	#無.
779
	#參考資料:
780
	#無.
781
	#備註:
782
	#無.
783
	*/
784
	public static function proc_update(&$conf){
785
 
786
		#初始化要回傳的變數
787
		$result=array();
788
 
789
		#初始化當前執行的函數名稱
790
		$result["function"]=__FUNCTION__;
791
 
792
		#如果 $conf 不為陣列
793
		if(gettype($conf)!="array"){
794
 
795
			#設置執行失敗
796
			$result["status"]="false";
797
 
798
			#設置執行錯誤訊息
799
			$result["error"][]="\$conf變數須為陣列形態";
800
 
801
			#如果傳入的參數為 null
802
			if($conf==null){
803
 
804
				#設置執行錯誤訊息
805
				$result["error"][]="\$conf變數不得為null,請檢查函數「".$result["function"]."」的參數設置有無正確!";
806
 
807
				}#if end
808
 
809
			#回傳結果
810
			return $result;
811
 
812
			}#if end
813
 
814
		#取得使用的參數
815
		$result["argu"]=$conf;
816
 
817
		#函式說明:
818
		#檢查必填與可省略的參數,可省略參數可指定預設要給與什麼數值內容.
819
		#回傳結果:
820
		#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
821
		#$result["error"],執行不正常結束的錯訊息陣列.
822
		#$result["simpleError"],簡單表示的錯誤訊息.
823
		#$result["function"],當前執行的函式名稱.
824
		#$result["argu"],設置給予的參數.
825
		#$result["passed"],識別要檢查的全體變數是否存在以及型態是否正確的變數,"true"代表檢查全部通過;"false"代表檢查不通過
826
		#$result[$shouldBeCheckedVarName]["varExist"],所檢查的變數是否存在,"false"代表不存在;"true"代表存在
827
		#$result[$shouldBeCheckedVarName]["varType"],所檢查的變數型態是否正確,"false"代表錯誤;"true"代表正確
828
		#$result[$shouldBeCheckedVarName]["error"],每個參數設定的錯誤訊息
829
		#$result["shouldNotBeEmpty"],不應該為空字串或控陣列的變數.
830
		#$result["argu"],字串陣列,目前輸入的參數名稱陣列.
831
		#$result["legalVarName"],字串陣列,合法可用的參數名稱陣列.
832
		#$result["notNeedVar"],字串陣列,多餘的參數名稱.
833
		#必填參數:
834
		#$conf["varInput"],陣列變數,要檢查的陣列變數,請在要檢查的參數前面加上&,這樣變動的結果才能被套用。
835
		$conf["variableCheck::checkArguments"]["varInput"]=&$conf;
836
		#$conf["referenceVarKey"],字串,$conf參數後面的key值,用於移除不要的參考陣列.
837
		$conf["variableCheck::checkArguments"]["referenceVarKey"]="variableCheck::checkArguments";
838
		#可省略參數:
839
		#$conf["mustBeFilledVariableName"],爲必填參數的變數名稱陣列,形態爲陣列變數,元素數量需要跟"mustBeFilledVariableType"參數的元素數量一致,例如: $conf["mustBeFilledVariableName"] = array("id","account","password");
840
		$conf["variableCheck::checkArguments"]["mustBeFilledVariableName"]=array("procs");
841
		#$conf["mustBeFilledVariableType"],爲必填參數的變數陣列應該爲何種變數形態,形態爲陣列,元素數量需要跟"mustBeFilledVariableName"參數的元素數量一致,例如: $conf["mustBeFilledVariableType"] = array("string",integer,"double","resource","object"); , null代表不指定變數形態.
842
		$conf["variableCheck::checkArguments"]["mustBeFilledVariableType"]=array("array");
843
		#$conf["canBeEmptyString"],字串,必填變數內容如果是空字串就不能算是有設置的話,請設為"false",預設爲"true",可以為空字串.
844
		#$conf["variableCheck::checkArguments"]["canBeEmptyString"]="false";
845
		#$conf["canNotBeEmpty"],字串陣列,哪些必填參數的內容不得為空字串或空陣列,僅當$conf["canBeEmptyString"]為"true"時會生效.
846
		$conf["variableCheck::checkArguments"]["canNotBeEmpty"]=array("procs");
847
		#$conf["canBeEmpty"],字串陣列,哪些必填參數的內容可為空字串或空陣列,僅當$conf["canBeEmptyString"]為"false"時會生效.
848
		#$conf["canBeEmpty"]=array();
849
		#$conf["skipableVariableCanNotBeEmpty"],字串陣列,哪些可省略參數不可以為空字串或空陣列.
850
		#$conf["variableCheck::checkArguments"]["skipableVariableCanNotBeEmpty"]=array("wait","workingDir","envs","executeBy");
851
		#$conf["skipableVariableName"],陣列字串,爲可省略參數的變數名稱陣列,形態爲陣列變數,例如: $conf["skipableVariableName"] = array("id","account","password");
852
		#$conf["variableCheck::checkArguments"]["skipableVariableName"]=array("wait","workingDir","envs","executeBy");
853
		#$conf["skipableVariableType"],陣列字串,爲可省略參數的變數名稱陣列,形態爲陣列變數,例如: $conf["skipableVariableType"] = array("string",integer,"double");
854
		#$conf["variableCheck::checkArguments"]["skipableVariableType"]=array("string","array","array","array");
855
		#$conf["skipableVarDefaultValue"],字串陣列,每個不存在的可省略變數要初始化為什麼,null與代表不指定,若預設值是參數之一,請將$conf["mustBeFilledVar"]改成"\$conf["\mustBeFilledVar\"]".
856
		#$conf["variableCheck::checkArguments"]["skipableVarDefaultValue"]=array("true",null,null,null);
857
		#$conf["disallowAllSkipableVarIsEmpty"],字串,是否允許每個可省略參數都為空字串,預設為"true"允許,反之為"false".
858
		#$conf["disallowAllSkipableVarIsEmpty"]="";
859
		#$conf["disallowAllSkipableVarIsEmptyArray"],字串,是否允許每個可省略參數都為空陣列,預設為"true"允許,反之為"false".
860
		#$conf["disallowAllSkipableVarIsEmptyArray"]="";
861
		#$conf["disallowAllSkipableVarNotExist"],字串,是否不允許每個可省略參數都不存在,預設為"false"代表允許,反之為"true".
862
		#$conf["disallowAllSkipableVarNotExist"]="";
863
		#$conf["arrayCountEqualCheck"],字串陣列,為檢查哪些陣列參數的元素數量要一樣,$conf["arrayCountEqualCheck"][$i]=array()為第$i組key為哪些的變數其元素數量要相等.
864
		#$conf["variableCheck::checkArguments"]["arrayCountEqualCheck"][]=array("");
865
		#參考資料:
866
		#array_keys=>http://php.net/manual/en/function.array-keys.php
867
		#備註:
868
		#無.
869
		$checkArguments=variableCheck::checkArguments($conf["variableCheck::checkArguments"]);
870
		unset($conf["variableCheck::checkArguments"]);
871
 
872
		#如果 $checkArguments["status"] 等於 "false"
873
		if($checkArguments["status"]==="false"){
874
 
875
			#設置錯誤識別
876
			$result["status"]="false";
877
 
878
			#設置錯誤訊息
879
			$result["error"]=$checkArguments;
880
 
881
			#回傳結果
882
			return $result;
883
 
884
			}#if end
885
 
886
		#如果 $checkArguments["passed"] 等於 "false"
887
		if($checkArguments["passed"]==="false"){
888
 
889
			#設置錯誤識別
890
			$result["status"]="false";
891
 
892
			#設置錯誤訊息
893
			$result["error"]=$checkArguments;
894
 
895
			#回傳結果
896
			return $result;
897
 
898
			}#if end
899
 
900
		#檢查 content
901
		/*
902
		#$result["content"],陣列,每個元素為其指令執行的結果訊息陣列,key為"status"代表執行是否正常的識別;key為"statusCode"代表程式結束後回傳給對應executeBy程式的數值;key為"output"代表標準輸出,若為resource,則代表為pipe;key為"error"代表非標準輸出,若為resource,則代表為pipe;key為"input"代表成功輸入的指令;key為"process"代表該程序經proc_open後的process source;key為"proc_get_status"代表程序的資訊.
903
		*/
904
 
905
		#針對每個程序
906
		foreach($conf["procs"] as $index => $proc){
907
 
908
			#函式說明:
909
			#檢查必填與可省略的參數,可省略參數可指定預設要給與什麼數值內容.
910
			#回傳結果:
911
			#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
912
			#$result["error"],執行不正常結束的錯訊息陣列.
913
			#$result["simpleError"],簡單表示的錯誤訊息.
914
			#$result["function"],當前執行的函式名稱.
915
			#$result["argu"],設置給予的參數.
916
			#$result["passed"],識別要檢查的全體變數是否存在以及型態是否正確的變數,"true"代表檢查全部通過;"false"代表檢查不通過
917
			#$result[$shouldBeCheckedVarName]["varExist"],所檢查的變數是否存在,"false"代表不存在;"true"代表存在
918
			#$result[$shouldBeCheckedVarName]["varType"],所檢查的變數型態是否正確,"false"代表錯誤;"true"代表正確
919
			#$result[$shouldBeCheckedVarName]["error"],每個參數設定的錯誤訊息
920
			#$result["shouldNotBeEmpty"],不應該為空字串或控陣列的變數.
921
			#$result["argu"],字串陣列,目前輸入的參數名稱陣列.
922
			#$result["legalVarName"],字串陣列,合法可用的參數名稱陣列.
923
			#$result["notNeedVar"],字串陣列,多餘的參數名稱.
924
			#必填參數:
925
			#$conf["varInput"],陣列變數,要檢查的陣列變數,請在要檢查的參數前面加上&,這樣變動的結果才能被套用。
926
			$conf["variableCheck::checkArguments"]["varInput"]=&$proc;
927
			#$conf["referenceVarKey"],字串,$conf參數後面的key值,用於移除不要的參考陣列.
928
			$conf["variableCheck::checkArguments"]["referenceVarKey"]="variableCheck::checkArguments";
929
			#可省略參數:
930
			#$conf["mustBeFilledVariableName"],爲必填參數的變數名稱陣列,形態爲陣列變數,元素數量需要跟"mustBeFilledVariableType"參數的元素數量一致,例如: $conf["mustBeFilledVariableName"] = array("id","account","password");
931
			$conf["variableCheck::checkArguments"]["mustBeFilledVariableName"]=array("status","statusCode","content","error","input","process","proc_get_status");
932
			#$conf["mustBeFilledVariableType"],爲必填參數的變數陣列應該爲何種變數形態,形態爲陣列,元素數量需要跟"mustBeFilledVariableName"參數的元素數量一致,例如: $conf["mustBeFilledVariableType"] = array("string",integer,"double","resource","object"); , null代表不指定變數形態.
933
			$conf["variableCheck::checkArguments"]["mustBeFilledVariableType"]=array("string",null,null,null,"string","resource","array");
934
			#$conf["canBeEmptyString"],字串,必填變數內容如果是空字串就不能算是有設置的話,請設為"false",預設爲"true",可以為空字串.
935
			#$conf["variableCheck::checkArguments"]["canBeEmptyString"]="false";
936
			#$conf["canNotBeEmpty"],字串陣列,哪些必填參數的內容不得為空字串或空陣列,僅當$conf["canBeEmptyString"]為"true"時會生效.
937
			#$conf["variableCheck::checkArguments"]["canNotBeEmpty"]=array("procs");
938
			#$conf["canBeEmpty"],字串陣列,哪些必填參數的內容可為空字串或空陣列,僅當$conf["canBeEmptyString"]為"false"時會生效.
939
			#$conf["variableCheck::checkArguments"]["canBeEmpty"]=array();
940
			#$conf["skipableVariableCanNotBeEmpty"],字串陣列,哪些可省略參數不可以為空字串或空陣列.
941
			#$conf["variableCheck::checkArguments"]["skipableVariableCanNotBeEmpty"]=array("wait","workingDir","envs","executeBy");
942
			#$conf["skipableVariableName"],陣列字串,爲可省略參數的變數名稱陣列,形態爲陣列變數,例如: $conf["skipableVariableName"] = array("id","account","password");
943
			#$conf["variableCheck::checkArguments"]["skipableVariableName"]=array("error");
944
			#$conf["skipableVariableType"],陣列字串,爲可省略參數的變數名稱陣列,形態爲陣列變數,例如: $conf["skipableVariableType"] = array("string",integer,"double");
945
			#$conf["variableCheck::checkArguments"]["skipableVariableType"]=array("array");
946
			#$conf["skipableVarDefaultValue"],字串陣列,每個不存在的可省略變數要初始化為什麼,null與代表不指定,若預設值是參數之一,請將$conf["mustBeFilledVar"]改成"\$conf["\mustBeFilledVar\"]".
947
			#$conf["variableCheck::checkArguments"]["skipableVarDefaultValue"]=array("true",null,null,null);
948
			#$conf["disallowAllSkipableVarIsEmpty"],字串,是否允許每個可省略參數都為空字串,預設為"true"允許,反之為"false".
949
			#$conf["disallowAllSkipableVarIsEmpty"]="";
950
			#$conf["disallowAllSkipableVarIsEmptyArray"],字串,是否允許每個可省略參數都為空陣列,預設為"true"允許,反之為"false".
951
			#$conf["disallowAllSkipableVarIsEmptyArray"]="";
952
			#$conf["disallowAllSkipableVarNotExist"],字串,是否不允許每個可省略參數都不存在,預設為"false"代表允許,反之為"true".
953
			#$conf["disallowAllSkipableVarNotExist"]="";
954
			#$conf["arrayCountEqualCheck"],字串陣列,為檢查哪些陣列參數的元素數量要一樣,$conf["arrayCountEqualCheck"][$i]=array()為第$i組key為哪些的變數其元素數量要相等.
955
			#$conf["variableCheck::checkArguments"]["arrayCountEqualCheck"][]=array("");
956
			#參考資料:
957
			#array_keys=>http://php.net/manual/en/function.array-keys.php
958
			#備註:
959
			#無.
960
			$checkArguments=variableCheck::checkArguments($conf["variableCheck::checkArguments"]);
961
			unset($conf["variableCheck::checkArguments"]);
962
 
963
			#如果 $checkArguments["status"] 等於 "false"
964
			if($checkArguments["status"]==="false"){
965
 
966
				#設置錯誤識別
967
				$result["status"]="false";
968
 
969
				#設置錯誤訊息
970
				$result["error"]=$checkArguments;
971
 
972
				#回傳結果
973
				return $result;
974
 
975
				}#if end
976
 
977
			#如果 $checkArguments["passed"] 等於 "false"
978
			if($checkArguments["passed"]==="false"){
979
 
980
				#設置錯誤識別
981
				$result["status"]="false";
982
 
983
				#設置錯誤訊息
984
				$result["error"]=$checkArguments;
985
 
986
				#回傳結果
987
				return $result;
988
 
989
				}#if end
990
 
991
			#如果可能尚在執行中
992
			if($proc["statusCode"]==="?"){
993
 
994
				#取得當下的狀態
995
				$proc_get_status=proc_get_status($proc["process"]);
996
 
997
				#如果執行已經結束,有回傳exitcode
998
				if($proc_get_status["exitcode"]!==-1){
999
 
1000
					#設置 statusCode
1001
					$conf["procs"][$index]["statusCode"]=$proc_get_status["exitcode"];
1002
 
1003
					#取得標準輸出
1004
					$stdout=stream_get_contents($proc["content"]);
1005
 
1006
					#取得錯誤輸出
1007
					$stderr=stream_get_contents($proc["error"]);
1008
 
1009
					#設置執行失敗訊息
1010
					$conf["procs"][$index]["error"]=$stderr;
1011
 
1012
					#設置執行結果
1013
					$conf["procs"][$index]["content"]=$stdout;
1014
 
1015
					}#if end
1016
 
1017
				}#if end
1018
 
1019
			}#foreach end
1020
 
1021
		#設置要回傳的結果
1022
		$result["content"]=$conf["procs"];
1023
 
1024
		#設置執行正常
1025
		$result["status"]="true";
1026
 
1027
		#回傳結果
1028
		return $result;
1029
 
1030
		}#function proc_update end
1031
 
1032
	/*
1033
	#函式說明:
1034
	#透過parallel展示多執行序運作.
1035
	#回傳結果:
1036
	#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
1037
	#$reuslt["error"],執行不正常結束的錯訊息陣列.
1038
	#$result["function"],當前執行的函式名稱.
1039
	#必填參數:
1040
	#無.
1041
	#可省略參數:
1042
	#無.
1043
	#參考資料:
1044
	#https://www.php.net/manual/en/class.parallel-runtime.php
1045
	#備註:
1046
	#需要於編譯PHP時啟用該套件	
1047
	*/
1048
	public static function parallel_demo(){
1049
 
1050
		#初始化要回傳的結果
1051
		$result=array();
1052
 
1053
		#取得當前執行的函數名稱
1054
		$result["function"]=__FUNCTION__;
1055
 
1056
		#新增程序r1
1057
		$r1=new \parallel\Runtime();
1058
 
1059
		#r1要執行的函式
1060
		$thread_r1_function=function($conf){
1061
 
1062
			#提示開始
1063
			echo $conf["id"]." start".PHP_EOL;
1064
 
1065
			#跑 $conf["i"] 次
1066
			for($i=0;$i<$conf["i"];$i++){
1067
 
1068
				#題書$i數值
1069
				echo "\$i=".$i.PHP_EOL;
1070
 
1071
				}#for end
1072
 
1073
			#提示結束
1074
			echo $conf["id"]." end".PHP_EOL;
1075
 
1076
			};#function end
1077
 
1078
		#r1的參數
1079
		$args_r1=array();
1080
		$args_r1["id"]="r1";
1081
		$args_r1["i"]=10;
1082
 
1083
		#運行程序r1
1084
		#程序函式為 $thread_r1_function
1085
		#參數陣列為 $args_r1
1086
		$future_r1=$r1->run($thread_r1_function, $args_r1);
1087
 
1088
		#新增程序r2
1089
		$r2=new \parallel\Runtime();
1090
 
1091
		#r2要執行的函式
1092
		$thread_r2_function=function($conf){
1093
 
1094
			#提示開始
1095
			echo $conf["id"]." start".PHP_EOL;
1096
 
1097
			#跑 $conf["i"] 次
1098
			for($i=$conf["i"];$i>0;$i--){
1099
 
1100
				#題書$i數值
1101
				echo "\$i=".$i.PHP_EOL;
1102
 
1103
				}#for end
1104
 
1105
			#提示結束
1106
			echo $conf["id"]." end".PHP_EOL;
1107
 
1108
			};#function end
1109
 
1110
		#r2的參數
1111
		$args_r2=array();
1112
		$args_r2["id"]="r2";
1113
		$args_r2["i"]=10;
1114
 
1115
		#運行程序r2
1116
		#程序函式為 $thread__r2_function
1117
		#參數陣列為 $args_r2
1118
		$future_r2=$r2->run($thread_r2_function, $args_r2);
1119
 
1120
		#存放有多少在執行的程序
1121
		$futureArray=array();
1122
		$futureArray[]=$future_r1;
1123
		$futureArray[]=$future_r2;
1124
 
1125
		#當有程序尚未結束時
1126
		while(!empty($futureArray)){
1127
 
1128
			#針對每個 Future
1129
			foreach($futureArray as $index => $Future){
1130
 
1131
				#如果執行完成了
1132
				if($Future->done()){
1133
 
1134
					#移除之
1135
					unset($futureArray[$index]);
1136
 
1137
					}#if end
1138
 
1139
				}#foreach end
1140
 
1141
			}#while end
1142
 
1143
		#提示所有程序都執行結束了
1144
		echo "all done!".PHP_EOL;
1145
 
1146
		#設置執行正常
1147
		$result["status"]="true";
1148
 
1149
		#回傳結果
1150
		return $result;
1151
 
1152
		}#function parallel_demo end
1153
 
1154
	/*
1155
	#函式說明:
1156
	#透過 unix socket 來多執行序運作.
1157
	#回傳結果:
1158
	#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
1159
	#$reuslt["error"],執行不正常結束的錯訊息陣列.
1160
	#$result["function"],當前執行的函式名稱.
1161
	#$result["argu"],使用的參數.
1162
	#$result["content"],陣列,每個元素為cmds參數中個別元素其指令傳送後得到的uuid,可透過sock::getProcInfo來查詢結果.
1163
	#必填參數:
1164
	#$conf["cmds"],字串陣列,每個元素代表要執行的指令與參數.
1165
	#$conf["cmds"]=array();
1166
	#可省略參數:
1167
	#$conf["sock"],字串,要連線的 usr/bin/qbpwcf-sock.php 所產生的 unix domain socket 路徑與名稱,預設為 qbpwcf_usock_path.
1168
	#$conf["sock"]=qbpwcf_usock_path;
1169
	#參考資料:
1170
	#無
1171
	#備註:
1172
	#需要透過sock::unixDomainSockServer來運行.
1173
	*/
1174
	public static function socket(&$conf){
1175
 
1176
		#初始化要回傳的變數
1177
		$result=array();
1178
 
1179
		#初始化當前執行的函數名稱
1180
		$result["function"]=__FUNCTION__;
1181
 
1182
		#如果 $conf 不為陣列
1183
		if(gettype($conf)!="array"){
1184
 
1185
			#設置執行失敗
1186
			$result["status"]="false";
1187
 
1188
			#設置執行錯誤訊息
1189
			$result["error"][]="\$conf變數須為陣列形態";
1190
 
1191
			#如果傳入的參數為 null
1192
			if($conf==null){
1193
 
1194
				#設置執行錯誤訊息
1195
				$result["error"][]="\$conf變數不得為null,請檢查函數「".$result["function"]."」的參數設置有無正確!";
1196
 
1197
				}#if end
1198
 
1199
			#回傳結果
1200
			return $result;
1201
 
1202
			}#if end
1203
 
1204
		#取得使用的參數
1205
		$result["argu"]=$conf;
1206
 
1207
		#函式說明:
1208
		#檢查必填與可省略的參數,可省略參數可指定預設要給與什麼數值內容.
1209
		#回傳結果:
1210
		#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
1211
		#$result["error"],執行不正常結束的錯訊息陣列.
1212
		#$result["simpleError"],簡單表示的錯誤訊息.
1213
		#$result["function"],當前執行的函式名稱.
1214
		#$result["argu"],設置給予的參數.
1215
		#$result["passed"],識別要檢查的全體變數是否存在以及型態是否正確的變數,"true"代表檢查全部通過;"false"代表檢查不通過
1216
		#$result[$shouldBeCheckedVarName]["varExist"],所檢查的變數是否存在,"false"代表不存在;"true"代表存在
1217
		#$result[$shouldBeCheckedVarName]["varType"],所檢查的變數型態是否正確,"false"代表錯誤;"true"代表正確
1218
		#$result[$shouldBeCheckedVarName]["error"],每個參數設定的錯誤訊息
1219
		#$result["shouldNotBeEmpty"],不應該為空字串或控陣列的變數.
1220
		#$result["argu"],字串陣列,目前輸入的參數名稱陣列.
1221
		#$result["legalVarName"],字串陣列,合法可用的參數名稱陣列.
1222
		#$result["notNeedVar"],字串陣列,多餘的參數名稱.
1223
		#必填參數:
1224
		#$conf["varInput"],陣列變數,要檢查的陣列變數,請在要檢查的參數前面加上&,這樣變動的結果才能被套用。
1225
		$conf["variableCheck::checkArguments"]["varInput"]=&$conf;
1226
		#$conf["referenceVarKey"],字串,$conf參數後面的key值,用於移除不要的參考陣列.
1227
		$conf["variableCheck::checkArguments"]["referenceVarKey"]="variableCheck::checkArguments";
1228
		#可省略參數:
1229
		#$conf["mustBeFilledVariableName"],爲必填參數的變數名稱陣列,形態爲陣列變數,元素數量需要跟"mustBeFilledVariableType"參數的元素數量一致,例如: $conf["mustBeFilledVariableName"] = array("id","account","password");
1230
		$conf["variableCheck::checkArguments"]["mustBeFilledVariableName"]=array("cmds");
1231
		#$conf["mustBeFilledVariableType"],爲必填參數的變數陣列應該爲何種變數形態,形態爲陣列,元素數量需要跟"mustBeFilledVariableName"參數的元素數量一致,例如: $conf["mustBeFilledVariableType"] = array("string",integer,"double","resource","object"); , null代表不指定變數形態.
1232
		$conf["variableCheck::checkArguments"]["mustBeFilledVariableType"]=array("array");
1233
		#$conf["canBeEmptyString"],字串,必填變數內容如果是空字串就不能算是有設置的話,請設為"false",預設爲"true",可以為空字串.
1234
		$conf["variableCheck::checkArguments"]["canBeEmptyString"]="false";
1235
		#$conf["canNotBeEmpty"],字串陣列,哪些必填參數的內容不得為空字串或空陣列,僅當$conf["canBeEmptyString"]為"true"時會生效.
1236
		#$conf["canNotBeEmpty"]=array();
1237
		#$conf["canBeEmpty"],字串陣列,哪些必填參數的內容可為空字串或空陣列,僅當$conf["canBeEmptyString"]為"false"時會生效.
1238
		#$conf["canBeEmpty"]=array();
1239
		#$conf["skipableVariableCanNotBeEmpty"],字串陣列,哪些可省略參數不可以為空字串或空陣列.
1240
		$conf["variableCheck::checkArguments"]["skipableVariableCanNotBeEmpty"]=array("sock");
1241
		#$conf["skipableVariableName"],陣列字串,爲可省略參數的變數名稱陣列,形態爲陣列變數,例如: $conf["skipableVariableName"] = array("id","account","password");
1242
		$conf["variableCheck::checkArguments"]["skipableVariableName"]=array("sock");
1243
		#$conf["skipableVariableType"],陣列字串,爲可省略參數的變數名稱陣列,形態爲陣列變數,例如: $conf["skipableVariableType"] = array("string",integer,"double");
1244
		$conf["variableCheck::checkArguments"]["skipableVariableType"]=array("string");
1245
		#$conf["skipableVarDefaultValue"],字串陣列,每個不存在的可省略變數要初始化為什麼,null與代表不指定,若預設值是參數之一,請將$conf["mustBeFilledVar"]改成"\$conf["\mustBeFilledVar\"]".
1246
		$conf["variableCheck::checkArguments"]["skipableVarDefaultValue"]=array(null);
1247
		#$conf["disallowAllSkipableVarIsEmpty"],字串,是否允許每個可省略參數都為空字串,預設為"true"允許,反之為"false".
1248
		#$conf["disallowAllSkipableVarIsEmpty"]="";
1249
		#$conf["disallowAllSkipableVarIsEmptyArray"],字串,是否允許每個可省略參數都為空陣列,預設為"true"允許,反之為"false".
1250
		#$conf["disallowAllSkipableVarIsEmptyArray"]="";
1251
		#$conf["disallowAllSkipableVarNotExist"],字串,是否不允許每個可省略參數都不存在,預設為"false"代表允許,反之為"true".
1252
		#$conf["disallowAllSkipableVarNotExist"]="";
1253
		#$conf["arrayCountEqualCheck"],字串陣列,為檢查哪些陣列參數的元素數量要一樣,$conf["arrayCountEqualCheck"][$i]=array()為第$i組key為哪些的變數其元素數量要相等.
1254
		#$conf["variableCheck::checkArguments"]["arrayCountEqualCheck"][]=array("");
1255
		#參考資料:
1256
		#array_keys=>http://php.net/manual/en/function.array-keys.php
1257
		#備註:
1258
		#無.
1259
		$checkArguments=variableCheck::checkArguments($conf["variableCheck::checkArguments"]);
1260
		unset($conf["variableCheck::checkArguments"]);
1261
 
1262
		#如果 $checkArguments["status"] 等於 "false"
1263
		if($checkArguments["status"]==="false"){
1264
 
1265
			#設置錯誤識別
1266
			$result["status"]="false";
1267
 
1268
			#設置錯誤訊息
1269
			$result["error"]=$checkArguments;
1270
 
1271
			#回傳結果
1272
			return $result;
1273
 
1274
			}#if end
1275
 
1276
		#如果 $checkArguments["passed"] 等於 "false"
1277
		if($checkArguments["passed"]==="false"){
1278
 
1279
			#設置錯誤識別
1280
			$result["status"]="false";
1281
 
1282
			#設置錯誤訊息
1283
			$result["error"]=$checkArguments;
1284
 
1285
			#回傳結果
1286
			return $result;
1287
 
1288
			}#if end
1289
 
1290
		#針對每個指令
1291
		foreach($conf["cmds"] as $cmd){
1292
 
1293
			#連線到 usr/bin/qbpwcf-usock.php 產生的  unix domain socket,運行指定的指令.
1294
			#回傳結果:
1295
			#$result["status"],"true"代表執行正常;"false"代表執行不正常.
1296
			#$result["error"],錯誤訊息陣列.
1297
			#$result["function"],當前執行的函式名稱.
1298
			#$result["argu"],使用的參數.
1299
			#$result["content"],執行完指令的結果.
1300
			#必填參數:
1301
			#$conf["fileArgu"],字串,變數__FILE__的內容.
1302
			$conf["sock::execAnyCmdByQBPWCFunixSocket"]["fileArgu"]=__FILE__;
1303
			#$conf["command"],字串,要執行的指令名稱.
1304
			$conf["sock::execAnyCmdByQBPWCFunixSocket"]["command"]=$cmd;
1305
			#可省略參數:
1306
 
1307
			#如果有設置 sock 參數
1308
			if(isset($conf["sock"])){
1309
 
1310
				#$conf["sock"],字串,要連線的 usr/bin/qbpwcf-sock.php 所產生的 unix domain socket 路徑與名稱,預設為 qbpwcf_usock_path.
1311
				$conf["sock::execAnyCmdByQBPWCFunixSocket"]["sock"]=$conf["sock"];
1312
 
1313
				}#if end
1314
 
1315
			#$conf["argu"],陣列字串,指令搭配的參數,預設為空陣列.
1316
			#$conf["sock::execAnyCmdByQBPWCFunixSocket"]["argu"]=$conf["argu"];
1317
			#$conf["commandIncludeArgu"],字串,是否command含有參數,預設為"false"代表沒有;反之為"true".
1318
			$conf["sock::execAnyCmdByQBPWCFunixSocket"]["commandIncludeArgu"]="true";
1319
			#$conf["commandInBg"],字串,是否要將程序放在背景執行,再取得相關資訊,預設為"false"代表不要;反之為"true".
1320
			$conf["sock::execAnyCmdByQBPWCFunixSocket"]["commandInBg"]="true";
1321
			#參考資料:
1322
			#無.
1323
			#備註:
1324
			#無.
1325
			$execAnyCmdByQBPWCFunixSocket=sock::execAnyCmdByQBPWCFunixSocket($conf["sock::execAnyCmdByQBPWCFunixSocket"]);
1326
			unset($conf["sock::execAnyCmdByQBPWCFunixSocket"]);
1327
 
1328
			#如果執行失敗
1329
			if($execAnyCmdByQBPWCFunixSocket["status"]==="false"){
1330
 
1331
				#設置錯誤識別
1332
				$result["status"]="false";
1333
 
1334
				#設置錯誤訊息
1335
				$result["error"]=$execAnyCmdByQBPWCFunixSocket;
1336
 
1337
				#回傳結果
1338
				return $result;
1339
 
1340
				}#if end
1341
 
1342
			#debug
1343
			#var_dump(__LINE__,$execAnyCmdByQBPWCFunixSocket);
1344
 
1345
			#儲存收到的回應
1346
			$result["content"][]=$execAnyCmdByQBPWCFunixSocket["content"];
1347
 
1348
			}#foreach end
1349
 
1350
		#設置執行正常
1351
		$result["status"]="true";
1352
 
1353
		#回傳結果
1354
		return $result;
1355
 
1356
		}#function socket end
1357
 
1358
	}#class threads end