Subversion Repositories php-qbpwcf

Rev

Rev 66 | Rev 159 | Go to most recent revision | Details | Compare with Previous | 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"],使用的參數.
66 liveuser 325
	#$result["content"],陣列,每個元素為其指令執行的結果訊息陣列,key為"status"代表執行是否正常的識別;key為"statusCode"代表程式結束後回傳給對應executeBy程式的數值,若為"?"則代表程序尚未結束,可透過proc_update函式進行資訊的更新與取得;key為"output"代表標準輸出,若為resource,則代表為pipe;key為"error"代表非標準輸出,若為resource,則代表為pipe;key為"input"代表成功輸入的指令;key為"process"代表該程序經proc_open後的process source;key為"proc_get_status"代表程序的資訊.
3 liveuser 326
	#必填參數:
66 liveuser 327
	#$conf["cmds"],字串陣列,每個元素代表單一程序要執行的指令與參數.
3 liveuser 328
	#$conf["cmds"]=array();
329
	#可省略參數:
330
	#$conf["wait"],字串,是否需要等待所有程序結束,預設為"true"要等待;反之為"false"不要等待.
331
	#$conf["wait"]="false";
140 liveuser 332
	#$conf["timeout"],字串陣列,每個元素代表單一程序執行的最大等待秒數,超過後將會強迫停止執行,僅當wait參數為"true"時生效.
333
	#$conf["timeout"]=array("10");
3 liveuser 334
	#$conf["workingDir"],字串陣列,個別程式執行時的家目錄,預設不指定.
335
	#$conf["workingDir"]=array("path");
336
	#$conf["envs"],2維字串陣列,每個元素代表個別程式執行時的指定環境變數,key變數名稱;value為變數內容.預設為array("QBPWCF" => "Quick Build PHP Website Componment base on Fedora Linux");
337
	#$conf["envs"]=array(array("key"=>"value"));
338
	#$conf["executeBy"],字串陣列,每個元素代表個別指令要用什麼程式執行,預設為"bash".
339
	#$conf["executeBy"]=array("bash");
340
	#參考資料:
341
	#https://www.php.net/manual/en/function.proc-open.php
342
	#https://www.php.net/manual/en/function.proc-get-status.php
140 liveuser 343
	#https://www.php.net/manual/en/function.proc-terminate.php
3 liveuser 344
	#備註:
345
	#若需要取得當下的執行狀況,請使用 self::proc_update 來更新.
346
	*/
347
	public static function proc(&$conf){
348
 
349
		#初始化要回傳的變數
350
		$result=array();
351
 
352
		#初始化當前執行的函數名稱
353
		$result["function"]=__FUNCTION__;
354
 
355
		#如果 $conf 不為陣列
66 liveuser 356
		if(gettype($conf)!=="array"){
3 liveuser 357
 
358
			#設置執行失敗
359
			$result["status"]="false";
360
 
361
			#設置執行錯誤訊息
362
			$result["error"][]="\$conf變數須為陣列形態";
363
 
364
			#如果傳入的參數為 null
66 liveuser 365
			if($conf===null){
3 liveuser 366
 
367
				#設置執行錯誤訊息
368
				$result["error"][]="\$conf變數不得為null,請檢查函數「".$result["function"]."」的參數設置有無正確!";
369
 
370
				}#if end
371
 
372
			#回傳結果
373
			return $result;
374
 
375
			}#if end
376
 
377
		#取得使用的參數
378
		$result["argu"]=$conf;
379
 
380
		#函式說明:
381
		#檢查必填與可省略的參數,可省略參數可指定預設要給與什麼數值內容.
382
		#回傳結果:
383
		#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
384
		#$result["error"],執行不正常結束的錯訊息陣列.
385
		#$result["simpleError"],簡單表示的錯誤訊息.
386
		#$result["function"],當前執行的函式名稱.
387
		#$result["argu"],設置給予的參數.
388
		#$result["passed"],識別要檢查的全體變數是否存在以及型態是否正確的變數,"true"代表檢查全部通過;"false"代表檢查不通過
389
		#$result[$shouldBeCheckedVarName]["varExist"],所檢查的變數是否存在,"false"代表不存在;"true"代表存在
390
		#$result[$shouldBeCheckedVarName]["varType"],所檢查的變數型態是否正確,"false"代表錯誤;"true"代表正確
391
		#$result[$shouldBeCheckedVarName]["error"],每個參數設定的錯誤訊息
392
		#$result["shouldNotBeEmpty"],不應該為空字串或控陣列的變數.
393
		#$result["argu"],字串陣列,目前輸入的參數名稱陣列.
394
		#$result["legalVarName"],字串陣列,合法可用的參數名稱陣列.
395
		#$result["notNeedVar"],字串陣列,多餘的參數名稱.
396
		#必填參數:
397
		#$conf["varInput"],陣列變數,要檢查的陣列變數,請在要檢查的參數前面加上&,這樣變動的結果才能被套用。
398
		$conf["variableCheck::checkArguments"]["varInput"]=&$conf;
399
		#$conf["referenceVarKey"],字串,$conf參數後面的key值,用於移除不要的參考陣列.
400
		$conf["variableCheck::checkArguments"]["referenceVarKey"]="variableCheck::checkArguments";
401
		#可省略參數:
402
		#$conf["mustBeFilledVariableName"],爲必填參數的變數名稱陣列,形態爲陣列變數,元素數量需要跟"mustBeFilledVariableType"參數的元素數量一致,例如: $conf["mustBeFilledVariableName"] = array("id","account","password");
403
		$conf["variableCheck::checkArguments"]["mustBeFilledVariableName"]=array("cmds");
404
		#$conf["mustBeFilledVariableType"],爲必填參數的變數陣列應該爲何種變數形態,形態爲陣列,元素數量需要跟"mustBeFilledVariableName"參數的元素數量一致,例如: $conf["mustBeFilledVariableType"] = array("string",integer,"double","resource","object"); , null代表不指定變數形態.
405
		$conf["variableCheck::checkArguments"]["mustBeFilledVariableType"]=array("array");
406
		#$conf["canBeEmptyString"],字串,必填變數內容如果是空字串就不能算是有設置的話,請設為"false",預設爲"true",可以為空字串.
407
		#$conf["variableCheck::checkArguments"]["canBeEmptyString"]="false";
408
		#$conf["canNotBeEmpty"],字串陣列,哪些必填參數的內容不得為空字串或空陣列,僅當$conf["canBeEmptyString"]為"true"時會生效.
409
		#$conf["canNotBeEmpty"]=array();
410
		#$conf["canBeEmpty"],字串陣列,哪些必填參數的內容可為空字串或空陣列,僅當$conf["canBeEmptyString"]為"false"時會生效.
411
		#$conf["canBeEmpty"]=array();
412
		#$conf["skipableVariableCanNotBeEmpty"],字串陣列,哪些可省略參數不可以為空字串或空陣列.
140 liveuser 413
		$conf["variableCheck::checkArguments"]["skipableVariableCanNotBeEmpty"]=array("wait","workingDir","envs","executeBy","timeout");
3 liveuser 414
		#$conf["skipableVariableName"],陣列字串,爲可省略參數的變數名稱陣列,形態爲陣列變數,例如: $conf["skipableVariableName"] = array("id","account","password");
140 liveuser 415
		$conf["variableCheck::checkArguments"]["skipableVariableName"]=array("wait","workingDir","envs","executeBy","timeout");
3 liveuser 416
		#$conf["skipableVariableType"],陣列字串,爲可省略參數的變數名稱陣列,形態爲陣列變數,例如: $conf["skipableVariableType"] = array("string",integer,"double");
140 liveuser 417
		$conf["variableCheck::checkArguments"]["skipableVariableType"]=array("string","array","array","array","array");
3 liveuser 418
		#$conf["skipableVarDefaultValue"],字串陣列,每個不存在的可省略變數要初始化為什麼,null與代表不指定,若預設值是參數之一,請將$conf["mustBeFilledVar"]改成"\$conf["\mustBeFilledVar\"]".
140 liveuser 419
		$conf["variableCheck::checkArguments"]["skipableVarDefaultValue"]=array("true",null,null,null,null);
3 liveuser 420
		#$conf["disallowAllSkipableVarIsEmpty"],字串,是否允許每個可省略參數都為空字串,預設為"true"允許,反之為"false".
421
		#$conf["disallowAllSkipableVarIsEmpty"]="";
422
		#$conf["disallowAllSkipableVarIsEmptyArray"],字串,是否允許每個可省略參數都為空陣列,預設為"true"允許,反之為"false".
423
		#$conf["disallowAllSkipableVarIsEmptyArray"]="";
424
		#$conf["disallowAllSkipableVarNotExist"],字串,是否不允許每個可省略參數都不存在,預設為"false"代表允許,反之為"true".
425
		#$conf["disallowAllSkipableVarNotExist"]="";
426
		#$conf["arrayCountEqualCheck"],字串陣列,為檢查哪些陣列參數的元素數量要一樣,$conf["arrayCountEqualCheck"][$i]=array()為第$i組key為哪些的變數其元素數量要相等.
427
		#$conf["variableCheck::checkArguments"]["arrayCountEqualCheck"][]=array("");
428
		#參考資料:
429
		#array_keys=>http://php.net/manual/en/function.array-keys.php
430
		#備註:
431
		#無.
432
		$checkArguments=variableCheck::checkArguments($conf["variableCheck::checkArguments"]);
433
		unset($conf["variableCheck::checkArguments"]);
434
 
435
		#如果 $checkArguments["status"] 等於 "false"
436
		if($checkArguments["status"]==="false"){
437
 
438
			#設置錯誤識別
439
			$result["status"]="false";
440
 
441
			#設置錯誤訊息
442
			$result["error"]=$checkArguments;
443
 
444
			#回傳結果
445
			return $result;
446
 
447
			}#if end
448
 
449
		#如果 $checkArguments["passed"] 等於 "false"
450
		if($checkArguments["passed"]==="false"){
451
 
452
			#設置錯誤識別
453
			$result["status"]="false";
454
 
455
			#設置錯誤訊息
456
			$result["error"]=$checkArguments;
457
 
458
			#回傳結果
459
			return $result;
460
 
461
			}#if end
140 liveuser 462
 
3 liveuser 463
		#初始化 descriptorspec
464
		$descriptorspec = array();
465
 
466
		#stdin is a pipe that the child will read from
467
		$descriptorspec[]=array("pipe", "r");
468
 
469
		#stdout is a pipe that the child will write to
470
		$descriptorspec[]=array("pipe", "w");
471
 
472
		#stderr is a pipe that the child will write to
473
		$descriptorspec[]=array("pipe", "w");
140 liveuser 474
 
3 liveuser 475
		#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) 
476
		$defaultCWD = null;
477
 
478
		#初始化儲存每個指令的working dir.
479
		$cwds=array();
480
 
481
		#有幾個指令就執行幾次
482
		for($i=0;$i<count($conf["cmds"]);$i++){
483
 
484
			#設置預設working dir
485
			$cwds[]=$defaultCWD;
486
 
487
			}#for end
488
 
489
		#如果有設置 workingDir
490
		if(isset($conf["workingDir"])){
491
 
492
			#如果數量符合
493
			if(count($conf["cmds"])===count($conf["workingDir"])){
494
 
495
				#有幾個指令就執行幾次
496
				for($i=0;$i<count($conf["cmds"]);$i++){
497
 
498
					#預設為指定數值
499
					$cwds[]=$conf["workingDir"][$i];
500
 
501
					}#for end
502
 
503
				}#if end
504
 
505
			}#if end
506
 
507
		#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 
508
		$defaultENV = array("QBPWCF" => "Quick Build PHP Website Componment base on Fedora Linux");
509
 
510
		#初始化儲存每個指令的環境變數.
511
		$envs=array();
512
 
513
		#有幾個指令就執行幾次
514
		for($i=0;$i<count($conf["cmds"]);$i++){
515
 
516
			#設置預設環境變數
517
			$envs[]=$defaultENV;
518
 
519
			}#for end
520
 
521
		#如果有設置 envs
522
		if(isset($conf["envs"])){
523
 
524
			#如果數量符合
525
			if(count($conf["cmds"])===count($conf["envs"])){
526
 
527
				#有幾個指令就執行幾次
528
				for($i=0;$i<count($conf["cmds"]);$i++){
529
 
530
					#預設為指定數值
531
					$envs[]=$conf["envs"][$i];
532
 
533
					}#for end
534
 
535
				}#if end
536
 
537
			}#if end
538
 
539
		#預設程式都透過 bash 來執行
540
		$defaultExecBy="bash";
541
 
542
		#初始化儲存每個指令要透過什麼程式執行
543
		$executeBys=array();
544
 
545
		#有幾個指令就執行幾次
546
		for($i=0;$i<count($conf["cmds"]);$i++){
547
 
548
			#設置預設環境變數
549
			$executeBys[]=$defaultExecBy;
550
 
551
			}#for end
552
 
553
		#如果有設置 executeBy
554
		if(isset($conf["executeBy"])){
555
 
556
			#如果數量符合
557
			if(count($conf["cmds"])===count($conf["executeBy"])){
558
 
559
				#初始化儲存每個指令要透過什麼程式執行
560
				$executeBys=array();
561
 
562
				#有幾個指令就執行幾次
563
				for($i=0;$i<count($conf["cmds"]);$i++){
564
 
565
					#預設為指定數值
566
					$executeBys[]=$conf["executeBy"][$i];
567
 
568
					}#for end
569
 
570
				}#if end
571
 
572
			}#if end
573
 
574
		#儲存每個要執行的程式資訊
575
		$process=array();
576
 
577
		#debug
578
		#var_dump(__LINE__,$executeBys);
579
 
580
		#針對每個指令與參數字串
581
		foreach($conf["cmds"] as $index=>$cmdAndArguStr){
582
 
583
			#debug
584
			#var_dump(__LINE__,$executeBys[$index]);
585
 
586
			#運行 php 程式,並儲存 resource
587
			$process[$index]["resource"] = proc_open($executeBys[$index], $descriptorspec, $pipes, $cwds[$index], $envs[$index]);
66 liveuser 588
 
3 liveuser 589
			#儲存對應的 pipes
590
			$process[$index]["pipes"]=$pipes;
66 liveuser 591
 
3 liveuser 592
			#如果有成功執行
593
			if(is_resource($process[$index]["resource"])){
594
 
595
				#$pipes now looks like this:
596
				#0 => writeable handle connected to child stdin
597
				#1 => readable handle connected to child stdout
598
				#2 => readable handle connected to child stdin
599
 
600
				#寫入內容作為 $executeBy 的輸入
601
				$bytes2write=fwrite($process[$index]["pipes"][0], $cmdAndArguStr);
602
 
603
				#結束輸入
604
				fclose($process[$index]["pipes"][0]);
605
 
606
				#如果有完整寫入指令
607
				if($bytes2write===strlen($cmdAndArguStr)){
608
 
609
					#記錄輸入的指令
610
					$process[$index]["input"]=$cmdAndArguStr;
611
 
612
					}#if end
613
 
614
				#反之
615
				else{
616
 
617
					#設置錯誤識別
618
					$result["status"]="false";
619
 
620
					#設置錯誤訊息
621
					$result["error"][]="將指令(".$cmdAndArguStr.")輸入(".$executeBys[$index].")失敗";
622
 
623
					#回傳結果
624
					return $result;
625
 
626
					}#else end
627
 
628
				}#if end
629
 
630
			#反之,代表運行 $executeBys[$index] 失敗
631
			else{
632
 
633
				#初始化暫存執行結果的變數
634
				$cmdRes=array();
635
 
636
				#設置執行失敗
637
				$cmdRes["status"]="false";
638
 
639
				#設置執行錯誤訊息
640
				$cmdRes["error"]="execute program by \"".$executeBys[$index]."\" failed!";
641
 
642
				#設置執行結果
643
				$result["content"][]=$cmdRes;
644
 
645
				}#else end
646
 
647
			}#foreach end
648
 
649
		#針對每個回饋
650
		foreach($process as $index => $ps){
651
 
652
			#取得 proc resource
653
			$resource=&$ps["resource"];
654
 
655
			#取得標準輸出的pipe
656
			$stdout=$process[$index]["pipes"][1];
657
 
658
			#取得非標準輸出的pipe
659
			$stderr=$process[$index]["pipes"][2];
660
 
661
			#如果需要等待程序執行完
662
			if($conf["wait"]==="true"){
663
 
140 liveuser 664
				#如果有設置  timeout
665
				if(isset($conf["timeout"])){
666
 
667
					#如果有設置該程序的 timeout
668
					if(isset($conf["timeout"][$index])){
669
 
670
						#避免 timeout 仍然會等待程序結束 - start
671
 
672
						#不讓標準輸出會阻擋程式執行
673
						stream_set_blocking($stdout,false);
674
 
675
						#不讓錯誤輸出會阻擋程式執行
676
						stream_set_blocking($stderr,false);
677
 
678
						#避免 timeout 仍然會等待程序結束 - end
679
 
680
						}#if end
681
 
682
					}#if end
683
 
3 liveuser 684
				}#if end
685
 
686
			#反之
687
			else{
688
 
689
				#不讓標準輸出會阻擋程式執行
690
				stream_set_blocking($stdout,false);
691
 
692
				#不讓錯誤輸出會阻擋程式執行
693
				stream_set_blocking($stderr,false);
694
 
695
				}#else end
696
 
697
			#初始化暫存執行狀況的變數
698
			$cmdRes=array();
699
 
700
			#取得 proc_open 後的 process resource
701
			$cmdRes["process"]=$resource;
702
 
703
			#取得 process 的狀態,包含 pid 等資訊,若程式已經結束,則會自動將pipes關閉,再proc_close.
704
			$cmdRes["proc_get_status"]=proc_get_status($resource);
705
 
706
			#預設 statusCode 為 "?" 代表尚未 proc_close
707
			$cmdRes["statusCode"]="?";
708
 
709
			#如果執行已經結束,有回傳exitcode
710
			if($cmdRes["proc_get_status"]["exitcode"]!==-1){
711
 
712
				#設置 statusCode
713
				$cmdRes["statusCode"]=&$cmdRes["proc_get_status"]["exitcode"];
714
 
715
				}#if end
716
 
717
			#反之未執行完畢,且需要等待程序執行完
718
			else if($conf["wait"]==="true"){
719
 
140 liveuser 720
				#預設已經執行0秒
721
				$runtime=0;
722
 
3 liveuser 723
				#無窮迴圈
724
				while(true){
725
 
140 liveuser 726
					#debug
727
					#var_dump(__LINE__,$runtime,$conf["timeout"]);
728
 
729
					#如果有設置  timeout
730
					if(isset($conf["timeout"])){
731
 
732
						#如果有設置該程序的 timeout
733
						if(isset($conf["timeout"][$index])){
734
 
735
							#如果執行秒數逾時了
736
							if( $runtime > (int)($conf["timeout"][$index]) ){
737
 
738
								#debug
739
								#var_dump(__LINE__,"timeout!");
740
 
741
								#關閉標準輸出的pipe
742
								fclose($stdout);
743
 
744
								#關閉標準錯誤的pipe
745
								fclose($stderr);
746
 
747
								#強制結束程序
748
								proc_terminate($resource);
749
 
750
								#結束proc.
751
								proc_close($resource);
752
 
753
								#設置執行異常
754
								$result["status"]="false";
755
 
756
								#設置error
757
								$result["error"][]="timeout(".$conf["timeout"][$index].")";
758
 
759
								#回傳結果
760
								return $result;
761
 
762
								}#if end
763
 
764
							}#if end
765
 
766
						}#if end
767
 
3 liveuser 768
					#取得 process 的狀態,包含 pid 等資訊,若程式已經結束,則會自動將pipes關閉,再proc_close.
769
					$cmdRes["proc_get_status"]=proc_get_status($resource);
770
 
771
					#如果執行已經結束,有回傳exitcode
772
					if($cmdRes["proc_get_status"]["exitcode"]!==-1){
773
 
774
						#設置 statusCode
775
						$cmdRes["statusCode"]=&$cmdRes["proc_get_status"]["exitcode"];
776
 
777
						#結束#無窮迴圈
778
						break;
779
 
780
						}#if end
781
 
782
					#等待1秒鐘
783
					sleep(1);
140 liveuser 784
 
785
					#執行秒數+1
786
					$runtime++;
3 liveuser 787
 
788
					}#while end
789
 
790
				}#if end
791
 
792
			#設置執行失敗訊息
793
			$cmdRes["error"]=$stderr;
794
 
795
			#設置執行結果
796
			$cmdRes["content"]=$stdout;
797
 
798
			#如果有成功輸入指令
799
			if(isset($process[$index]["input"])){
800
 
801
				#設置有輸入的指令
802
				$cmdRes["input"]=$process[$index]["input"];
803
 
804
				}#if end
805
 
806
			#預設執行不正常
807
			$cmdRes["status"]="false";
808
 
809
			#如果執行正常 或 等於"?"(代表尚未 proc_close)
810
			if($cmdRes["statusCode"]===0 || $cmdRes["statusCode"]==="?"){
811
 
812
				#設置執行正常
813
				$cmdRes["status"]="true";
814
 
815
				}#if end
816
 
817
			#保存結果
818
			$result["content"][]=$cmdRes;
819
 
820
			}#foreach end
821
 
822
		#設置執行正常
823
		$result["status"]="true";
824
 
825
		#回傳結果
826
		return $result;
827
 
828
		}#function proc end
829
 
830
	/*
831
	#函式說明:
832
	#更新透過proc執行的多程序資訊.
833
	#回傳結果:
834
	#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
835
	#$reuslt["error"],執行不正常結束的錯訊息陣列.
836
	#$result["function"],當前執行的函式名稱.
837
	#$result["argu"],使用的參數.
66 liveuser 838
	#$result["content"],陣列,每個元素為其指令執行的結果訊息陣列,key為"status"代表執行是否正常的識別;key為"statusCode"代表程式結束後回傳給對應executeBy程式的數值,若為"?"則代表程序尚未結束,可透過proc_update函式進行資訊的更新與取得;key為"output"代表標準輸出,若為resource,則代表為pipe;key為"error"代表非標準輸出,若為resource,則代表為pipe;key為"input"代表成功輸入的指令;key為"process"代表該程序經proc_open後的process source;key為"proc_get_status"代表程序的資訊.
3 liveuser 839
	#必填參數:
840
	#$conf["procs"],陣列,運行self::proc後回傳的content.
841
	$conf["procs"]=$procs;
842
	#可省略參數:
843
	#無.
844
	#參考資料:
845
	#無.
846
	#備註:
847
	#無.
848
	*/
849
	public static function proc_update(&$conf){
850
 
851
		#初始化要回傳的變數
852
		$result=array();
853
 
854
		#初始化當前執行的函數名稱
855
		$result["function"]=__FUNCTION__;
856
 
857
		#如果 $conf 不為陣列
858
		if(gettype($conf)!="array"){
859
 
860
			#設置執行失敗
861
			$result["status"]="false";
862
 
863
			#設置執行錯誤訊息
864
			$result["error"][]="\$conf變數須為陣列形態";
865
 
866
			#如果傳入的參數為 null
867
			if($conf==null){
868
 
869
				#設置執行錯誤訊息
870
				$result["error"][]="\$conf變數不得為null,請檢查函數「".$result["function"]."」的參數設置有無正確!";
871
 
872
				}#if end
873
 
874
			#回傳結果
875
			return $result;
876
 
877
			}#if end
878
 
879
		#取得使用的參數
880
		$result["argu"]=$conf;
881
 
882
		#函式說明:
883
		#檢查必填與可省略的參數,可省略參數可指定預設要給與什麼數值內容.
884
		#回傳結果:
885
		#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
886
		#$result["error"],執行不正常結束的錯訊息陣列.
887
		#$result["simpleError"],簡單表示的錯誤訊息.
888
		#$result["function"],當前執行的函式名稱.
889
		#$result["argu"],設置給予的參數.
890
		#$result["passed"],識別要檢查的全體變數是否存在以及型態是否正確的變數,"true"代表檢查全部通過;"false"代表檢查不通過
891
		#$result[$shouldBeCheckedVarName]["varExist"],所檢查的變數是否存在,"false"代表不存在;"true"代表存在
892
		#$result[$shouldBeCheckedVarName]["varType"],所檢查的變數型態是否正確,"false"代表錯誤;"true"代表正確
893
		#$result[$shouldBeCheckedVarName]["error"],每個參數設定的錯誤訊息
894
		#$result["shouldNotBeEmpty"],不應該為空字串或控陣列的變數.
895
		#$result["argu"],字串陣列,目前輸入的參數名稱陣列.
896
		#$result["legalVarName"],字串陣列,合法可用的參數名稱陣列.
897
		#$result["notNeedVar"],字串陣列,多餘的參數名稱.
898
		#必填參數:
899
		#$conf["varInput"],陣列變數,要檢查的陣列變數,請在要檢查的參數前面加上&,這樣變動的結果才能被套用。
900
		$conf["variableCheck::checkArguments"]["varInput"]=&$conf;
901
		#$conf["referenceVarKey"],字串,$conf參數後面的key值,用於移除不要的參考陣列.
902
		$conf["variableCheck::checkArguments"]["referenceVarKey"]="variableCheck::checkArguments";
903
		#可省略參數:
904
		#$conf["mustBeFilledVariableName"],爲必填參數的變數名稱陣列,形態爲陣列變數,元素數量需要跟"mustBeFilledVariableType"參數的元素數量一致,例如: $conf["mustBeFilledVariableName"] = array("id","account","password");
905
		$conf["variableCheck::checkArguments"]["mustBeFilledVariableName"]=array("procs");
906
		#$conf["mustBeFilledVariableType"],爲必填參數的變數陣列應該爲何種變數形態,形態爲陣列,元素數量需要跟"mustBeFilledVariableName"參數的元素數量一致,例如: $conf["mustBeFilledVariableType"] = array("string",integer,"double","resource","object"); , null代表不指定變數形態.
907
		$conf["variableCheck::checkArguments"]["mustBeFilledVariableType"]=array("array");
908
		#$conf["canBeEmptyString"],字串,必填變數內容如果是空字串就不能算是有設置的話,請設為"false",預設爲"true",可以為空字串.
909
		#$conf["variableCheck::checkArguments"]["canBeEmptyString"]="false";
910
		#$conf["canNotBeEmpty"],字串陣列,哪些必填參數的內容不得為空字串或空陣列,僅當$conf["canBeEmptyString"]為"true"時會生效.
911
		$conf["variableCheck::checkArguments"]["canNotBeEmpty"]=array("procs");
912
		#$conf["canBeEmpty"],字串陣列,哪些必填參數的內容可為空字串或空陣列,僅當$conf["canBeEmptyString"]為"false"時會生效.
913
		#$conf["canBeEmpty"]=array();
914
		#$conf["skipableVariableCanNotBeEmpty"],字串陣列,哪些可省略參數不可以為空字串或空陣列.
915
		#$conf["variableCheck::checkArguments"]["skipableVariableCanNotBeEmpty"]=array("wait","workingDir","envs","executeBy");
916
		#$conf["skipableVariableName"],陣列字串,爲可省略參數的變數名稱陣列,形態爲陣列變數,例如: $conf["skipableVariableName"] = array("id","account","password");
917
		#$conf["variableCheck::checkArguments"]["skipableVariableName"]=array("wait","workingDir","envs","executeBy");
918
		#$conf["skipableVariableType"],陣列字串,爲可省略參數的變數名稱陣列,形態爲陣列變數,例如: $conf["skipableVariableType"] = array("string",integer,"double");
919
		#$conf["variableCheck::checkArguments"]["skipableVariableType"]=array("string","array","array","array");
920
		#$conf["skipableVarDefaultValue"],字串陣列,每個不存在的可省略變數要初始化為什麼,null與代表不指定,若預設值是參數之一,請將$conf["mustBeFilledVar"]改成"\$conf["\mustBeFilledVar\"]".
921
		#$conf["variableCheck::checkArguments"]["skipableVarDefaultValue"]=array("true",null,null,null);
922
		#$conf["disallowAllSkipableVarIsEmpty"],字串,是否允許每個可省略參數都為空字串,預設為"true"允許,反之為"false".
923
		#$conf["disallowAllSkipableVarIsEmpty"]="";
924
		#$conf["disallowAllSkipableVarIsEmptyArray"],字串,是否允許每個可省略參數都為空陣列,預設為"true"允許,反之為"false".
925
		#$conf["disallowAllSkipableVarIsEmptyArray"]="";
926
		#$conf["disallowAllSkipableVarNotExist"],字串,是否不允許每個可省略參數都不存在,預設為"false"代表允許,反之為"true".
927
		#$conf["disallowAllSkipableVarNotExist"]="";
928
		#$conf["arrayCountEqualCheck"],字串陣列,為檢查哪些陣列參數的元素數量要一樣,$conf["arrayCountEqualCheck"][$i]=array()為第$i組key為哪些的變數其元素數量要相等.
929
		#$conf["variableCheck::checkArguments"]["arrayCountEqualCheck"][]=array("");
930
		#參考資料:
931
		#array_keys=>http://php.net/manual/en/function.array-keys.php
932
		#備註:
933
		#無.
934
		$checkArguments=variableCheck::checkArguments($conf["variableCheck::checkArguments"]);
935
		unset($conf["variableCheck::checkArguments"]);
936
 
937
		#如果 $checkArguments["status"] 等於 "false"
938
		if($checkArguments["status"]==="false"){
939
 
940
			#設置錯誤識別
941
			$result["status"]="false";
942
 
943
			#設置錯誤訊息
944
			$result["error"]=$checkArguments;
945
 
946
			#回傳結果
947
			return $result;
948
 
949
			}#if end
950
 
951
		#如果 $checkArguments["passed"] 等於 "false"
952
		if($checkArguments["passed"]==="false"){
953
 
954
			#設置錯誤識別
955
			$result["status"]="false";
956
 
957
			#設置錯誤訊息
958
			$result["error"]=$checkArguments;
959
 
960
			#回傳結果
961
			return $result;
962
 
963
			}#if end
964
 
965
		#檢查 content
966
		/*
967
		#$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"代表程序的資訊.
968
		*/
969
 
970
		#針對每個程序
971
		foreach($conf["procs"] as $index => $proc){
972
 
973
			#函式說明:
974
			#檢查必填與可省略的參數,可省略參數可指定預設要給與什麼數值內容.
975
			#回傳結果:
976
			#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
977
			#$result["error"],執行不正常結束的錯訊息陣列.
978
			#$result["simpleError"],簡單表示的錯誤訊息.
979
			#$result["function"],當前執行的函式名稱.
980
			#$result["argu"],設置給予的參數.
981
			#$result["passed"],識別要檢查的全體變數是否存在以及型態是否正確的變數,"true"代表檢查全部通過;"false"代表檢查不通過
982
			#$result[$shouldBeCheckedVarName]["varExist"],所檢查的變數是否存在,"false"代表不存在;"true"代表存在
983
			#$result[$shouldBeCheckedVarName]["varType"],所檢查的變數型態是否正確,"false"代表錯誤;"true"代表正確
984
			#$result[$shouldBeCheckedVarName]["error"],每個參數設定的錯誤訊息
985
			#$result["shouldNotBeEmpty"],不應該為空字串或控陣列的變數.
986
			#$result["argu"],字串陣列,目前輸入的參數名稱陣列.
987
			#$result["legalVarName"],字串陣列,合法可用的參數名稱陣列.
988
			#$result["notNeedVar"],字串陣列,多餘的參數名稱.
989
			#必填參數:
990
			#$conf["varInput"],陣列變數,要檢查的陣列變數,請在要檢查的參數前面加上&,這樣變動的結果才能被套用。
991
			$conf["variableCheck::checkArguments"]["varInput"]=&$proc;
992
			#$conf["referenceVarKey"],字串,$conf參數後面的key值,用於移除不要的參考陣列.
993
			$conf["variableCheck::checkArguments"]["referenceVarKey"]="variableCheck::checkArguments";
994
			#可省略參數:
995
			#$conf["mustBeFilledVariableName"],爲必填參數的變數名稱陣列,形態爲陣列變數,元素數量需要跟"mustBeFilledVariableType"參數的元素數量一致,例如: $conf["mustBeFilledVariableName"] = array("id","account","password");
996
			$conf["variableCheck::checkArguments"]["mustBeFilledVariableName"]=array("status","statusCode","content","error","input","process","proc_get_status");
997
			#$conf["mustBeFilledVariableType"],爲必填參數的變數陣列應該爲何種變數形態,形態爲陣列,元素數量需要跟"mustBeFilledVariableName"參數的元素數量一致,例如: $conf["mustBeFilledVariableType"] = array("string",integer,"double","resource","object"); , null代表不指定變數形態.
998
			$conf["variableCheck::checkArguments"]["mustBeFilledVariableType"]=array("string",null,null,null,"string","resource","array");
999
			#$conf["canBeEmptyString"],字串,必填變數內容如果是空字串就不能算是有設置的話,請設為"false",預設爲"true",可以為空字串.
1000
			#$conf["variableCheck::checkArguments"]["canBeEmptyString"]="false";
1001
			#$conf["canNotBeEmpty"],字串陣列,哪些必填參數的內容不得為空字串或空陣列,僅當$conf["canBeEmptyString"]為"true"時會生效.
1002
			#$conf["variableCheck::checkArguments"]["canNotBeEmpty"]=array("procs");
1003
			#$conf["canBeEmpty"],字串陣列,哪些必填參數的內容可為空字串或空陣列,僅當$conf["canBeEmptyString"]為"false"時會生效.
1004
			#$conf["variableCheck::checkArguments"]["canBeEmpty"]=array();
1005
			#$conf["skipableVariableCanNotBeEmpty"],字串陣列,哪些可省略參數不可以為空字串或空陣列.
1006
			#$conf["variableCheck::checkArguments"]["skipableVariableCanNotBeEmpty"]=array("wait","workingDir","envs","executeBy");
1007
			#$conf["skipableVariableName"],陣列字串,爲可省略參數的變數名稱陣列,形態爲陣列變數,例如: $conf["skipableVariableName"] = array("id","account","password");
1008
			#$conf["variableCheck::checkArguments"]["skipableVariableName"]=array("error");
1009
			#$conf["skipableVariableType"],陣列字串,爲可省略參數的變數名稱陣列,形態爲陣列變數,例如: $conf["skipableVariableType"] = array("string",integer,"double");
1010
			#$conf["variableCheck::checkArguments"]["skipableVariableType"]=array("array");
1011
			#$conf["skipableVarDefaultValue"],字串陣列,每個不存在的可省略變數要初始化為什麼,null與代表不指定,若預設值是參數之一,請將$conf["mustBeFilledVar"]改成"\$conf["\mustBeFilledVar\"]".
1012
			#$conf["variableCheck::checkArguments"]["skipableVarDefaultValue"]=array("true",null,null,null);
1013
			#$conf["disallowAllSkipableVarIsEmpty"],字串,是否允許每個可省略參數都為空字串,預設為"true"允許,反之為"false".
1014
			#$conf["disallowAllSkipableVarIsEmpty"]="";
1015
			#$conf["disallowAllSkipableVarIsEmptyArray"],字串,是否允許每個可省略參數都為空陣列,預設為"true"允許,反之為"false".
1016
			#$conf["disallowAllSkipableVarIsEmptyArray"]="";
1017
			#$conf["disallowAllSkipableVarNotExist"],字串,是否不允許每個可省略參數都不存在,預設為"false"代表允許,反之為"true".
1018
			#$conf["disallowAllSkipableVarNotExist"]="";
1019
			#$conf["arrayCountEqualCheck"],字串陣列,為檢查哪些陣列參數的元素數量要一樣,$conf["arrayCountEqualCheck"][$i]=array()為第$i組key為哪些的變數其元素數量要相等.
1020
			#$conf["variableCheck::checkArguments"]["arrayCountEqualCheck"][]=array("");
1021
			#參考資料:
1022
			#array_keys=>http://php.net/manual/en/function.array-keys.php
1023
			#備註:
1024
			#無.
1025
			$checkArguments=variableCheck::checkArguments($conf["variableCheck::checkArguments"]);
1026
			unset($conf["variableCheck::checkArguments"]);
1027
 
1028
			#如果 $checkArguments["status"] 等於 "false"
1029
			if($checkArguments["status"]==="false"){
1030
 
1031
				#設置錯誤識別
1032
				$result["status"]="false";
1033
 
1034
				#設置錯誤訊息
1035
				$result["error"]=$checkArguments;
1036
 
1037
				#回傳結果
1038
				return $result;
1039
 
1040
				}#if end
1041
 
1042
			#如果 $checkArguments["passed"] 等於 "false"
1043
			if($checkArguments["passed"]==="false"){
1044
 
1045
				#設置錯誤識別
1046
				$result["status"]="false";
1047
 
1048
				#設置錯誤訊息
1049
				$result["error"]=$checkArguments;
1050
 
1051
				#回傳結果
1052
				return $result;
1053
 
1054
				}#if end
1055
 
1056
			#如果可能尚在執行中
1057
			if($proc["statusCode"]==="?"){
1058
 
1059
				#取得當下的狀態
1060
				$proc_get_status=proc_get_status($proc["process"]);
1061
 
1062
				#如果執行已經結束,有回傳exitcode
1063
				if($proc_get_status["exitcode"]!==-1){
1064
 
1065
					#設置 statusCode
1066
					$conf["procs"][$index]["statusCode"]=$proc_get_status["exitcode"];
1067
 
1068
					#取得標準輸出
1069
					$stdout=stream_get_contents($proc["content"]);
1070
 
1071
					#取得錯誤輸出
1072
					$stderr=stream_get_contents($proc["error"]);
1073
 
1074
					#設置執行失敗訊息
1075
					$conf["procs"][$index]["error"]=$stderr;
1076
 
1077
					#設置執行結果
1078
					$conf["procs"][$index]["content"]=$stdout;
1079
 
1080
					}#if end
1081
 
1082
				}#if end
1083
 
1084
			}#foreach end
1085
 
1086
		#設置要回傳的結果
1087
		$result["content"]=$conf["procs"];
1088
 
1089
		#設置執行正常
1090
		$result["status"]="true";
1091
 
1092
		#回傳結果
1093
		return $result;
1094
 
1095
		}#function proc_update end
1096
 
1097
	/*
1098
	#函式說明:
1099
	#透過parallel展示多執行序運作.
1100
	#回傳結果:
1101
	#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
1102
	#$reuslt["error"],執行不正常結束的錯訊息陣列.
1103
	#$result["function"],當前執行的函式名稱.
1104
	#必填參數:
1105
	#無.
1106
	#可省略參數:
1107
	#無.
1108
	#參考資料:
1109
	#https://www.php.net/manual/en/class.parallel-runtime.php
1110
	#備註:
1111
	#需要於編譯PHP時啟用該套件	
1112
	*/
1113
	public static function parallel_demo(){
1114
 
1115
		#初始化要回傳的結果
1116
		$result=array();
1117
 
1118
		#取得當前執行的函數名稱
1119
		$result["function"]=__FUNCTION__;
1120
 
1121
		#新增程序r1
1122
		$r1=new \parallel\Runtime();
1123
 
1124
		#r1要執行的函式
1125
		$thread_r1_function=function($conf){
1126
 
1127
			#提示開始
1128
			echo $conf["id"]." start".PHP_EOL;
1129
 
1130
			#跑 $conf["i"] 次
1131
			for($i=0;$i<$conf["i"];$i++){
1132
 
1133
				#題書$i數值
1134
				echo "\$i=".$i.PHP_EOL;
1135
 
1136
				}#for end
1137
 
1138
			#提示結束
1139
			echo $conf["id"]." end".PHP_EOL;
1140
 
1141
			};#function end
1142
 
1143
		#r1的參數
1144
		$args_r1=array();
1145
		$args_r1["id"]="r1";
1146
		$args_r1["i"]=10;
1147
 
1148
		#運行程序r1
1149
		#程序函式為 $thread_r1_function
1150
		#參數陣列為 $args_r1
1151
		$future_r1=$r1->run($thread_r1_function, $args_r1);
1152
 
1153
		#新增程序r2
1154
		$r2=new \parallel\Runtime();
1155
 
1156
		#r2要執行的函式
1157
		$thread_r2_function=function($conf){
1158
 
1159
			#提示開始
1160
			echo $conf["id"]." start".PHP_EOL;
1161
 
1162
			#跑 $conf["i"] 次
1163
			for($i=$conf["i"];$i>0;$i--){
1164
 
1165
				#題書$i數值
1166
				echo "\$i=".$i.PHP_EOL;
1167
 
1168
				}#for end
1169
 
1170
			#提示結束
1171
			echo $conf["id"]." end".PHP_EOL;
1172
 
1173
			};#function end
1174
 
1175
		#r2的參數
1176
		$args_r2=array();
1177
		$args_r2["id"]="r2";
1178
		$args_r2["i"]=10;
1179
 
1180
		#運行程序r2
1181
		#程序函式為 $thread__r2_function
1182
		#參數陣列為 $args_r2
1183
		$future_r2=$r2->run($thread_r2_function, $args_r2);
1184
 
1185
		#存放有多少在執行的程序
1186
		$futureArray=array();
1187
		$futureArray[]=$future_r1;
1188
		$futureArray[]=$future_r2;
1189
 
1190
		#當有程序尚未結束時
1191
		while(!empty($futureArray)){
1192
 
1193
			#針對每個 Future
1194
			foreach($futureArray as $index => $Future){
1195
 
1196
				#如果執行完成了
1197
				if($Future->done()){
1198
 
1199
					#移除之
1200
					unset($futureArray[$index]);
1201
 
1202
					}#if end
1203
 
1204
				}#foreach end
1205
 
1206
			}#while end
1207
 
1208
		#提示所有程序都執行結束了
1209
		echo "all done!".PHP_EOL;
1210
 
1211
		#設置執行正常
1212
		$result["status"]="true";
1213
 
1214
		#回傳結果
1215
		return $result;
1216
 
1217
		}#function parallel_demo end
1218
 
1219
	/*
1220
	#函式說明:
1221
	#透過 unix socket 來多執行序運作.
1222
	#回傳結果:
1223
	#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
1224
	#$reuslt["error"],執行不正常結束的錯訊息陣列.
1225
	#$result["function"],當前執行的函式名稱.
1226
	#$result["argu"],使用的參數.
1227
	#$result["content"],陣列,每個元素為cmds參數中個別元素其指令傳送後得到的uuid,可透過sock::getProcInfo來查詢結果.
1228
	#必填參數:
1229
	#$conf["cmds"],字串陣列,每個元素代表要執行的指令與參數.
1230
	#$conf["cmds"]=array();
1231
	#可省略參數:
1232
	#$conf["sock"],字串,要連線的 usr/bin/qbpwcf-sock.php 所產生的 unix domain socket 路徑與名稱,預設為 qbpwcf_usock_path.
1233
	#$conf["sock"]=qbpwcf_usock_path;
1234
	#參考資料:
1235
	#無
1236
	#備註:
1237
	#需要透過sock::unixDomainSockServer來運行.
1238
	*/
1239
	public static function socket(&$conf){
1240
 
1241
		#初始化要回傳的變數
1242
		$result=array();
1243
 
1244
		#初始化當前執行的函數名稱
1245
		$result["function"]=__FUNCTION__;
1246
 
1247
		#如果 $conf 不為陣列
1248
		if(gettype($conf)!="array"){
1249
 
1250
			#設置執行失敗
1251
			$result["status"]="false";
1252
 
1253
			#設置執行錯誤訊息
1254
			$result["error"][]="\$conf變數須為陣列形態";
1255
 
1256
			#如果傳入的參數為 null
1257
			if($conf==null){
1258
 
1259
				#設置執行錯誤訊息
1260
				$result["error"][]="\$conf變數不得為null,請檢查函數「".$result["function"]."」的參數設置有無正確!";
1261
 
1262
				}#if end
1263
 
1264
			#回傳結果
1265
			return $result;
1266
 
1267
			}#if end
1268
 
1269
		#取得使用的參數
1270
		$result["argu"]=$conf;
1271
 
1272
		#函式說明:
1273
		#檢查必填與可省略的參數,可省略參數可指定預設要給與什麼數值內容.
1274
		#回傳結果:
1275
		#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
1276
		#$result["error"],執行不正常結束的錯訊息陣列.
1277
		#$result["simpleError"],簡單表示的錯誤訊息.
1278
		#$result["function"],當前執行的函式名稱.
1279
		#$result["argu"],設置給予的參數.
1280
		#$result["passed"],識別要檢查的全體變數是否存在以及型態是否正確的變數,"true"代表檢查全部通過;"false"代表檢查不通過
1281
		#$result[$shouldBeCheckedVarName]["varExist"],所檢查的變數是否存在,"false"代表不存在;"true"代表存在
1282
		#$result[$shouldBeCheckedVarName]["varType"],所檢查的變數型態是否正確,"false"代表錯誤;"true"代表正確
1283
		#$result[$shouldBeCheckedVarName]["error"],每個參數設定的錯誤訊息
1284
		#$result["shouldNotBeEmpty"],不應該為空字串或控陣列的變數.
1285
		#$result["argu"],字串陣列,目前輸入的參數名稱陣列.
1286
		#$result["legalVarName"],字串陣列,合法可用的參數名稱陣列.
1287
		#$result["notNeedVar"],字串陣列,多餘的參數名稱.
1288
		#必填參數:
1289
		#$conf["varInput"],陣列變數,要檢查的陣列變數,請在要檢查的參數前面加上&,這樣變動的結果才能被套用。
1290
		$conf["variableCheck::checkArguments"]["varInput"]=&$conf;
1291
		#$conf["referenceVarKey"],字串,$conf參數後面的key值,用於移除不要的參考陣列.
1292
		$conf["variableCheck::checkArguments"]["referenceVarKey"]="variableCheck::checkArguments";
1293
		#可省略參數:
1294
		#$conf["mustBeFilledVariableName"],爲必填參數的變數名稱陣列,形態爲陣列變數,元素數量需要跟"mustBeFilledVariableType"參數的元素數量一致,例如: $conf["mustBeFilledVariableName"] = array("id","account","password");
1295
		$conf["variableCheck::checkArguments"]["mustBeFilledVariableName"]=array("cmds");
1296
		#$conf["mustBeFilledVariableType"],爲必填參數的變數陣列應該爲何種變數形態,形態爲陣列,元素數量需要跟"mustBeFilledVariableName"參數的元素數量一致,例如: $conf["mustBeFilledVariableType"] = array("string",integer,"double","resource","object"); , null代表不指定變數形態.
1297
		$conf["variableCheck::checkArguments"]["mustBeFilledVariableType"]=array("array");
1298
		#$conf["canBeEmptyString"],字串,必填變數內容如果是空字串就不能算是有設置的話,請設為"false",預設爲"true",可以為空字串.
1299
		$conf["variableCheck::checkArguments"]["canBeEmptyString"]="false";
1300
		#$conf["canNotBeEmpty"],字串陣列,哪些必填參數的內容不得為空字串或空陣列,僅當$conf["canBeEmptyString"]為"true"時會生效.
1301
		#$conf["canNotBeEmpty"]=array();
1302
		#$conf["canBeEmpty"],字串陣列,哪些必填參數的內容可為空字串或空陣列,僅當$conf["canBeEmptyString"]為"false"時會生效.
1303
		#$conf["canBeEmpty"]=array();
1304
		#$conf["skipableVariableCanNotBeEmpty"],字串陣列,哪些可省略參數不可以為空字串或空陣列.
1305
		$conf["variableCheck::checkArguments"]["skipableVariableCanNotBeEmpty"]=array("sock");
1306
		#$conf["skipableVariableName"],陣列字串,爲可省略參數的變數名稱陣列,形態爲陣列變數,例如: $conf["skipableVariableName"] = array("id","account","password");
1307
		$conf["variableCheck::checkArguments"]["skipableVariableName"]=array("sock");
1308
		#$conf["skipableVariableType"],陣列字串,爲可省略參數的變數名稱陣列,形態爲陣列變數,例如: $conf["skipableVariableType"] = array("string",integer,"double");
1309
		$conf["variableCheck::checkArguments"]["skipableVariableType"]=array("string");
1310
		#$conf["skipableVarDefaultValue"],字串陣列,每個不存在的可省略變數要初始化為什麼,null與代表不指定,若預設值是參數之一,請將$conf["mustBeFilledVar"]改成"\$conf["\mustBeFilledVar\"]".
1311
		$conf["variableCheck::checkArguments"]["skipableVarDefaultValue"]=array(null);
1312
		#$conf["disallowAllSkipableVarIsEmpty"],字串,是否允許每個可省略參數都為空字串,預設為"true"允許,反之為"false".
1313
		#$conf["disallowAllSkipableVarIsEmpty"]="";
1314
		#$conf["disallowAllSkipableVarIsEmptyArray"],字串,是否允許每個可省略參數都為空陣列,預設為"true"允許,反之為"false".
1315
		#$conf["disallowAllSkipableVarIsEmptyArray"]="";
1316
		#$conf["disallowAllSkipableVarNotExist"],字串,是否不允許每個可省略參數都不存在,預設為"false"代表允許,反之為"true".
1317
		#$conf["disallowAllSkipableVarNotExist"]="";
1318
		#$conf["arrayCountEqualCheck"],字串陣列,為檢查哪些陣列參數的元素數量要一樣,$conf["arrayCountEqualCheck"][$i]=array()為第$i組key為哪些的變數其元素數量要相等.
1319
		#$conf["variableCheck::checkArguments"]["arrayCountEqualCheck"][]=array("");
1320
		#參考資料:
1321
		#array_keys=>http://php.net/manual/en/function.array-keys.php
1322
		#備註:
1323
		#無.
1324
		$checkArguments=variableCheck::checkArguments($conf["variableCheck::checkArguments"]);
1325
		unset($conf["variableCheck::checkArguments"]);
1326
 
1327
		#如果 $checkArguments["status"] 等於 "false"
1328
		if($checkArguments["status"]==="false"){
1329
 
1330
			#設置錯誤識別
1331
			$result["status"]="false";
1332
 
1333
			#設置錯誤訊息
1334
			$result["error"]=$checkArguments;
1335
 
1336
			#回傳結果
1337
			return $result;
1338
 
1339
			}#if end
1340
 
1341
		#如果 $checkArguments["passed"] 等於 "false"
1342
		if($checkArguments["passed"]==="false"){
1343
 
1344
			#設置錯誤識別
1345
			$result["status"]="false";
1346
 
1347
			#設置錯誤訊息
1348
			$result["error"]=$checkArguments;
1349
 
1350
			#回傳結果
1351
			return $result;
1352
 
1353
			}#if end
1354
 
1355
		#針對每個指令
1356
		foreach($conf["cmds"] as $cmd){
1357
 
1358
			#連線到 usr/bin/qbpwcf-usock.php 產生的  unix domain socket,運行指定的指令.
1359
			#回傳結果:
1360
			#$result["status"],"true"代表執行正常;"false"代表執行不正常.
1361
			#$result["error"],錯誤訊息陣列.
1362
			#$result["function"],當前執行的函式名稱.
1363
			#$result["argu"],使用的參數.
1364
			#$result["content"],執行完指令的結果.
1365
			#必填參數:
1366
			#$conf["fileArgu"],字串,變數__FILE__的內容.
1367
			$conf["sock::execAnyCmdByQBPWCFunixSocket"]["fileArgu"]=__FILE__;
1368
			#$conf["command"],字串,要執行的指令名稱.
1369
			$conf["sock::execAnyCmdByQBPWCFunixSocket"]["command"]=$cmd;
1370
			#可省略參數:
1371
 
1372
			#如果有設置 sock 參數
1373
			if(isset($conf["sock"])){
1374
 
1375
				#$conf["sock"],字串,要連線的 usr/bin/qbpwcf-sock.php 所產生的 unix domain socket 路徑與名稱,預設為 qbpwcf_usock_path.
1376
				$conf["sock::execAnyCmdByQBPWCFunixSocket"]["sock"]=$conf["sock"];
1377
 
1378
				}#if end
1379
 
1380
			#$conf["argu"],陣列字串,指令搭配的參數,預設為空陣列.
1381
			#$conf["sock::execAnyCmdByQBPWCFunixSocket"]["argu"]=$conf["argu"];
1382
			#$conf["commandIncludeArgu"],字串,是否command含有參數,預設為"false"代表沒有;反之為"true".
1383
			$conf["sock::execAnyCmdByQBPWCFunixSocket"]["commandIncludeArgu"]="true";
1384
			#$conf["commandInBg"],字串,是否要將程序放在背景執行,再取得相關資訊,預設為"false"代表不要;反之為"true".
1385
			$conf["sock::execAnyCmdByQBPWCFunixSocket"]["commandInBg"]="true";
1386
			#參考資料:
1387
			#無.
1388
			#備註:
1389
			#無.
1390
			$execAnyCmdByQBPWCFunixSocket=sock::execAnyCmdByQBPWCFunixSocket($conf["sock::execAnyCmdByQBPWCFunixSocket"]);
1391
			unset($conf["sock::execAnyCmdByQBPWCFunixSocket"]);
1392
 
1393
			#如果執行失敗
1394
			if($execAnyCmdByQBPWCFunixSocket["status"]==="false"){
1395
 
1396
				#設置錯誤識別
1397
				$result["status"]="false";
1398
 
1399
				#設置錯誤訊息
1400
				$result["error"]=$execAnyCmdByQBPWCFunixSocket;
1401
 
1402
				#回傳結果
1403
				return $result;
1404
 
1405
				}#if end
1406
 
1407
			#debug
1408
			#var_dump(__LINE__,$execAnyCmdByQBPWCFunixSocket);
1409
 
1410
			#儲存收到的回應
1411
			$result["content"][]=$execAnyCmdByQBPWCFunixSocket["content"];
1412
 
1413
			}#foreach end
1414
 
1415
		#設置執行正常
1416
		$result["status"]="true";
1417
 
1418
		#回傳結果
1419
		return $result;
1420
 
1421
		}#function socket end
1422
 
1423
	}#class threads end