Subversion Repositories qbpwcf-lib(archive)

Rev

Rev 915 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
566 liveuser 1
<?php
2
 
3
/*
4
 
5
	QBPWCF, Quick Build PHP website Component base on Fedora Linux.
622 liveuser 6
    Copyright (C) 2015~2024 Min-Jhin,Chen
566 liveuser 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
 
606 liveuser 159
		#stderr is a pipe that the child will write to
160
		$descriptorspec[]=array("pipe", "w");
566 liveuser 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
 
606 liveuser 171
		#初始化要demo用的url
172
		$demoUrl="https://qbpwc.sourceforge.io/";
173
 
566 liveuser 174
		#要多執行序執行的程式1
606 liveuser 175
		$codes[]=array("bash","curl -v -L --ssl-reqd ".$demoUrl);
566 liveuser 176
 
177
		#要多執行序執行的程式2
606 liveuser 178
		$codes[]=array("bash","curl -v -L --ssl-reqd ".$demoUrl);
566 liveuser 179
 
180
		#要多執行序執行的程式3
606 liveuser 181
		$codes[]=array("bash","curl -v -L --ssl-reqd ".$demoUrl);
566 liveuser 182
 
183
		#debug
606 liveuser 184
		#var_dump(__LINE__,$codes);
566 liveuser 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
606 liveuser 205
			#var_dump(__LINE__,$process[$index]);
566 liveuser 206
 
207
			#如果有成功執行
606 liveuser 208
			if(is_resource($process[$index]["resource"])){
566 liveuser 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
606 liveuser 219
				#var_dump(__LINE__,$bytes2write);
566 liveuser 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;
606 liveuser 240
 
566 liveuser 241
				}#else end
242
 
243
			}#foreach end
244
 
245
		#debug
606 liveuser 246
		#var_dump(__LINE__,$process);
566 liveuser 247
 
248
		#針對每個回饋
606 liveuser 249
		foreach($process as $index => $ps){
566 liveuser 250
 
606 liveuser 251
			#取得 proc resource
252
			$resource=$ps["resource"];
253
 
566 liveuser 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
			#如果執行正常
606 liveuser 291
			if($cmdRes["statusCode"]===0){
566 liveuser 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
	#函式說明:
666 liveuser 319
	#透過proc來多執行序運作.
320
	#回傳結果:
321
	#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
322
	#$reuslt["error"],執行不正常結束的錯訊息陣列.
323
	#$result["function"],當前執行的函式名稱.
668 liveuser 324
	#$result["argu"],使用的參數.
667 liveuser 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"代表程序的資訊.
666 liveuser 326
	#必填參數:
327
	#$conf["cmds"],字串陣列,每個元素代表要執行的指令與參數.
328
	#$conf["cmds"]=array();
329
	#可省略參數:
667 liveuser 330
	#$conf["wait"],字串,是否需要等待所有程序結束,預設為"true"要等待;反之為"false"不要等待.
331
	#$conf["wait"]="false";
666 liveuser 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
667 liveuser 340
	#https://www.php.net/manual/en/function.proc-get-status.php
666 liveuser 341
	#備註:
849 liveuser 342
	#若需要取得當下的執行狀況,請使用 self::proc_update 來更新.
666 liveuser 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"],字串陣列,哪些可省略參數不可以為空字串或空陣列.
667 liveuser 410
		$conf["variableCheck::checkArguments"]["skipableVariableCanNotBeEmpty"]=array("wait","workingDir","envs","executeBy");
666 liveuser 411
		#$conf["skipableVariableName"],陣列字串,爲可省略參數的變數名稱陣列,形態爲陣列變數,例如: $conf["skipableVariableName"] = array("id","account","password");
667 liveuser 412
		$conf["variableCheck::checkArguments"]["skipableVariableName"]=array("wait","workingDir","envs","executeBy");
666 liveuser 413
		#$conf["skipableVariableType"],陣列字串,爲可省略參數的變數名稱陣列,形態爲陣列變數,例如: $conf["skipableVariableType"] = array("string",integer,"double");
667 liveuser 414
		$conf["variableCheck::checkArguments"]["skipableVariableType"]=array("string","array","array","array");
666 liveuser 415
		#$conf["skipableVarDefaultValue"],字串陣列,每個不存在的可省略變數要初始化為什麼,null與代表不指定,若預設值是參數之一,請將$conf["mustBeFilledVar"]改成"\$conf["\mustBeFilledVar\"]".
667 liveuser 416
		$conf["variableCheck::checkArguments"]["skipableVarDefaultValue"]=array("true",null,null,null);
666 liveuser 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
			#回傳結果
849 liveuser 442
			return $result;
666 liveuser 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
 
849 liveuser 556
				#初始化儲存每個指令要透過什麼程式執行
557
				$executeBys=array();
558
 
666 liveuser 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
 
849 liveuser 574
		#debug
575
		#var_dump(__LINE__,$executeBys);
576
 
666 liveuser 577
		#針對每個指令與參數字串
578
		foreach($conf["cmds"] as $index=>$cmdAndArguStr){
579
 
849 liveuser 580
			#debug
581
			#var_dump(__LINE__,$executeBys[$index]);
582
 
666 liveuser 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
 
667 liveuser 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
 
666 liveuser 625
				}#if end
626
 
667 liveuser 627
			#反之,代表運行 $executeBys[$index] 失敗
666 liveuser 628
			else{
629
 
630
				#初始化暫存執行結果的變數
631
				$cmdRes=array();
632
 
633
				#設置執行失敗
634
				$cmdRes["status"]="false";
635
 
636
				#設置執行錯誤訊息
667 liveuser 637
				$cmdRes["error"]="execute program by \"".$executeBys[$index]."\" failed!";
666 liveuser 638
 
639
				#設置執行結果
640
				$result["content"][]=$cmdRes;
641
 
642
				}#else end
643
 
644
			}#foreach end
667 liveuser 645
 
666 liveuser 646
		#針對每個回饋
647
		foreach($process as $index => $ps){
648
 
649
			#取得 proc resource
667 liveuser 650
			$resource=&$ps["resource"];
666 liveuser 651
 
667 liveuser 652
			#取得標準輸出的pipe
653
			$stdout=$process[$index]["pipes"][1];
654
 
655
			#取得非標準輸出的pipe
656
			$stderr=$process[$index]["pipes"][2];
666 liveuser 657
 
667 liveuser 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
 
744 liveuser 669
			#反之
670
			else{
671
 
672
				#不讓標準輸出會阻擋程式執行
673
				stream_set_blocking($stdout,false);
674
 
675
				#不讓錯誤輸出會阻擋程式執行
676
				stream_set_blocking($stderr,false);
677
 
678
				}#else end
679
 
666 liveuser 680
			#初始化暫存執行狀況的變數
681
			$cmdRes=array();
682
 
667 liveuser 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
849 liveuser 693
			if($cmdRes["proc_get_status"]["exitcode"]!==-1){
667 liveuser 694
 
695
				#設置 statusCode
696
				$cmdRes["statusCode"]=&$cmdRes["proc_get_status"]["exitcode"];
697
 
698
				}#if end
699
 
666 liveuser 700
			#設置執行失敗訊息
701
			$cmdRes["error"]=$stderr;
702
 
703
			#設置執行結果
704
			$cmdRes["content"]=$stdout;
705
 
667 liveuser 706
			#如果有成功輸入指令
707
			if(isset($process[$index]["input"])){
666 liveuser 708
 
667 liveuser 709
				#設置有輸入的指令
710
				$cmdRes["input"]=$process[$index]["input"];
666 liveuser 711
 
667 liveuser 712
				}#if end
666 liveuser 713
 
714
			#預設執行不正常
715
			$cmdRes["status"]="false";
716
 
667 liveuser 717
			#如果執行正常 或 等於"?"(代表尚未 proc_close)
718
			if($cmdRes["statusCode"]===0 || $cmdRes["statusCode"]==="?"){
666 liveuser 719
 
720
				#設置執行正常
721
				$cmdRes["status"]="true";
722
 
723
				}#if end
724
 
725
			#保存結果
726
			$result["content"][]=$cmdRes;
727
 
728
			}#foreach end
729
 
730
		#設置執行正常
731
		$result["status"]="true";
732
 
733
		#回傳結果
734
		return $result;
735
 
736
		}#function proc end
737
 
738
	/*
739
	#函式說明:
849 liveuser 740
	#更新透過proc執行的多程序資訊.
741
	#回傳結果:
742
	#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
743
	#$reuslt["error"],執行不正常結束的錯訊息陣列.
744
	#$result["function"],當前執行的函式名稱.
745
	#$result["argu"],使用的參數.
746
	#$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"代表程序的資訊.
747
	#必填參數:
748
	#$conf["procs"],陣列,運行self::proc後回傳的content.
749
	$conf["procs"]=$procs;
750
	#可省略參數:
751
	#無.
752
	#參考資料:
753
	#無.
754
	#備註:
755
	#無.
756
	*/
757
	public static function proc_update(&$conf){
758
 
759
		#初始化要回傳的變數
760
		$result=array();
761
 
762
		#初始化當前執行的函數名稱
763
		$result["function"]=__FUNCTION__;
764
 
765
		#如果 $conf 不為陣列
766
		if(gettype($conf)!="array"){
767
 
768
			#設置執行失敗
769
			$result["status"]="false";
770
 
771
			#設置執行錯誤訊息
772
			$result["error"][]="\$conf變數須為陣列形態";
773
 
774
			#如果傳入的參數為 null
775
			if($conf==null){
776
 
777
				#設置執行錯誤訊息
778
				$result["error"][]="\$conf變數不得為null,請檢查函數「".$result["function"]."」的參數設置有無正確!";
779
 
780
				}#if end
781
 
782
			#回傳結果
783
			return $result;
784
 
785
			}#if end
786
 
787
		#取得使用的參數
788
		$result["argu"]=$conf;
789
 
790
		#函式說明:
791
		#檢查必填與可省略的參數,可省略參數可指定預設要給與什麼數值內容.
792
		#回傳結果:
793
		#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
794
		#$result["error"],執行不正常結束的錯訊息陣列.
795
		#$result["simpleError"],簡單表示的錯誤訊息.
796
		#$result["function"],當前執行的函式名稱.
797
		#$result["argu"],設置給予的參數.
798
		#$result["passed"],識別要檢查的全體變數是否存在以及型態是否正確的變數,"true"代表檢查全部通過;"false"代表檢查不通過
799
		#$result[$shouldBeCheckedVarName]["varExist"],所檢查的變數是否存在,"false"代表不存在;"true"代表存在
800
		#$result[$shouldBeCheckedVarName]["varType"],所檢查的變數型態是否正確,"false"代表錯誤;"true"代表正確
801
		#$result[$shouldBeCheckedVarName]["error"],每個參數設定的錯誤訊息
802
		#$result["shouldNotBeEmpty"],不應該為空字串或控陣列的變數.
803
		#$result["argu"],字串陣列,目前輸入的參數名稱陣列.
804
		#$result["legalVarName"],字串陣列,合法可用的參數名稱陣列.
805
		#$result["notNeedVar"],字串陣列,多餘的參數名稱.
806
		#必填參數:
807
		#$conf["varInput"],陣列變數,要檢查的陣列變數,請在要檢查的參數前面加上&,這樣變動的結果才能被套用。
808
		$conf["variableCheck::checkArguments"]["varInput"]=&$conf;
809
		#$conf["referenceVarKey"],字串,$conf參數後面的key值,用於移除不要的參考陣列.
810
		$conf["variableCheck::checkArguments"]["referenceVarKey"]="variableCheck::checkArguments";
811
		#可省略參數:
812
		#$conf["mustBeFilledVariableName"],爲必填參數的變數名稱陣列,形態爲陣列變數,元素數量需要跟"mustBeFilledVariableType"參數的元素數量一致,例如: $conf["mustBeFilledVariableName"] = array("id","account","password");
813
		$conf["variableCheck::checkArguments"]["mustBeFilledVariableName"]=array("procs");
814
		#$conf["mustBeFilledVariableType"],爲必填參數的變數陣列應該爲何種變數形態,形態爲陣列,元素數量需要跟"mustBeFilledVariableName"參數的元素數量一致,例如: $conf["mustBeFilledVariableType"] = array("string",integer,"double","resource","object"); , null代表不指定變數形態.
815
		$conf["variableCheck::checkArguments"]["mustBeFilledVariableType"]=array("array");
816
		#$conf["canBeEmptyString"],字串,必填變數內容如果是空字串就不能算是有設置的話,請設為"false",預設爲"true",可以為空字串.
817
		#$conf["variableCheck::checkArguments"]["canBeEmptyString"]="false";
818
		#$conf["canNotBeEmpty"],字串陣列,哪些必填參數的內容不得為空字串或空陣列,僅當$conf["canBeEmptyString"]為"true"時會生效.
819
		$conf["variableCheck::checkArguments"]["canNotBeEmpty"]=array("procs");
820
		#$conf["canBeEmpty"],字串陣列,哪些必填參數的內容可為空字串或空陣列,僅當$conf["canBeEmptyString"]為"false"時會生效.
821
		#$conf["canBeEmpty"]=array();
822
		#$conf["skipableVariableCanNotBeEmpty"],字串陣列,哪些可省略參數不可以為空字串或空陣列.
823
		#$conf["variableCheck::checkArguments"]["skipableVariableCanNotBeEmpty"]=array("wait","workingDir","envs","executeBy");
824
		#$conf["skipableVariableName"],陣列字串,爲可省略參數的變數名稱陣列,形態爲陣列變數,例如: $conf["skipableVariableName"] = array("id","account","password");
825
		#$conf["variableCheck::checkArguments"]["skipableVariableName"]=array("wait","workingDir","envs","executeBy");
826
		#$conf["skipableVariableType"],陣列字串,爲可省略參數的變數名稱陣列,形態爲陣列變數,例如: $conf["skipableVariableType"] = array("string",integer,"double");
827
		#$conf["variableCheck::checkArguments"]["skipableVariableType"]=array("string","array","array","array");
828
		#$conf["skipableVarDefaultValue"],字串陣列,每個不存在的可省略變數要初始化為什麼,null與代表不指定,若預設值是參數之一,請將$conf["mustBeFilledVar"]改成"\$conf["\mustBeFilledVar\"]".
829
		#$conf["variableCheck::checkArguments"]["skipableVarDefaultValue"]=array("true",null,null,null);
830
		#$conf["disallowAllSkipableVarIsEmpty"],字串,是否允許每個可省略參數都為空字串,預設為"true"允許,反之為"false".
831
		#$conf["disallowAllSkipableVarIsEmpty"]="";
832
		#$conf["disallowAllSkipableVarIsEmptyArray"],字串,是否允許每個可省略參數都為空陣列,預設為"true"允許,反之為"false".
833
		#$conf["disallowAllSkipableVarIsEmptyArray"]="";
834
		#$conf["disallowAllSkipableVarNotExist"],字串,是否不允許每個可省略參數都不存在,預設為"false"代表允許,反之為"true".
835
		#$conf["disallowAllSkipableVarNotExist"]="";
836
		#$conf["arrayCountEqualCheck"],字串陣列,為檢查哪些陣列參數的元素數量要一樣,$conf["arrayCountEqualCheck"][$i]=array()為第$i組key為哪些的變數其元素數量要相等.
837
		#$conf["variableCheck::checkArguments"]["arrayCountEqualCheck"][]=array("");
838
		#參考資料:
839
		#array_keys=>http://php.net/manual/en/function.array-keys.php
840
		#備註:
841
		#無.
842
		$checkArguments=variableCheck::checkArguments($conf["variableCheck::checkArguments"]);
843
		unset($conf["variableCheck::checkArguments"]);
844
 
845
		#如果 $checkArguments["status"] 等於 "false"
846
		if($checkArguments["status"]==="false"){
847
 
848
			#設置錯誤識別
849
			$result["status"]="false";
850
 
851
			#設置錯誤訊息
852
			$result["error"]=$checkArguments;
853
 
854
			#回傳結果
855
			return $result;
856
 
857
			}#if end
858
 
859
		#如果 $checkArguments["passed"] 等於 "false"
860
		if($checkArguments["passed"]==="false"){
861
 
862
			#設置錯誤識別
863
			$result["status"]="false";
864
 
865
			#設置錯誤訊息
866
			$result["error"]=$checkArguments;
867
 
868
			#回傳結果
869
			return $result;
870
 
871
			}#if end
872
 
873
		#檢查 content
874
		/*
875
		#$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"代表程序的資訊.
876
		*/
877
 
878
		#針對每個程序
879
		foreach($conf["procs"] as $index => $proc){
880
 
881
			#函式說明:
882
			#檢查必填與可省略的參數,可省略參數可指定預設要給與什麼數值內容.
883
			#回傳結果:
884
			#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
885
			#$result["error"],執行不正常結束的錯訊息陣列.
886
			#$result["simpleError"],簡單表示的錯誤訊息.
887
			#$result["function"],當前執行的函式名稱.
888
			#$result["argu"],設置給予的參數.
889
			#$result["passed"],識別要檢查的全體變數是否存在以及型態是否正確的變數,"true"代表檢查全部通過;"false"代表檢查不通過
890
			#$result[$shouldBeCheckedVarName]["varExist"],所檢查的變數是否存在,"false"代表不存在;"true"代表存在
891
			#$result[$shouldBeCheckedVarName]["varType"],所檢查的變數型態是否正確,"false"代表錯誤;"true"代表正確
892
			#$result[$shouldBeCheckedVarName]["error"],每個參數設定的錯誤訊息
893
			#$result["shouldNotBeEmpty"],不應該為空字串或控陣列的變數.
894
			#$result["argu"],字串陣列,目前輸入的參數名稱陣列.
895
			#$result["legalVarName"],字串陣列,合法可用的參數名稱陣列.
896
			#$result["notNeedVar"],字串陣列,多餘的參數名稱.
897
			#必填參數:
898
			#$conf["varInput"],陣列變數,要檢查的陣列變數,請在要檢查的參數前面加上&,這樣變動的結果才能被套用。
899
			$conf["variableCheck::checkArguments"]["varInput"]=&$proc;
900
			#$conf["referenceVarKey"],字串,$conf參數後面的key值,用於移除不要的參考陣列.
901
			$conf["variableCheck::checkArguments"]["referenceVarKey"]="variableCheck::checkArguments";
902
			#可省略參數:
903
			#$conf["mustBeFilledVariableName"],爲必填參數的變數名稱陣列,形態爲陣列變數,元素數量需要跟"mustBeFilledVariableType"參數的元素數量一致,例如: $conf["mustBeFilledVariableName"] = array("id","account","password");
854 liveuser 904
			$conf["variableCheck::checkArguments"]["mustBeFilledVariableName"]=array("status","statusCode","content","error","input","process","proc_get_status");
849 liveuser 905
			#$conf["mustBeFilledVariableType"],爲必填參數的變數陣列應該爲何種變數形態,形態爲陣列,元素數量需要跟"mustBeFilledVariableName"參數的元素數量一致,例如: $conf["mustBeFilledVariableType"] = array("string",integer,"double","resource","object"); , null代表不指定變數形態.
854 liveuser 906
			$conf["variableCheck::checkArguments"]["mustBeFilledVariableType"]=array("string",null,null,null,"string","resource","array");
849 liveuser 907
			#$conf["canBeEmptyString"],字串,必填變數內容如果是空字串就不能算是有設置的話,請設為"false",預設爲"true",可以為空字串.
908
			#$conf["variableCheck::checkArguments"]["canBeEmptyString"]="false";
909
			#$conf["canNotBeEmpty"],字串陣列,哪些必填參數的內容不得為空字串或空陣列,僅當$conf["canBeEmptyString"]為"true"時會生效.
910
			#$conf["variableCheck::checkArguments"]["canNotBeEmpty"]=array("procs");
911
			#$conf["canBeEmpty"],字串陣列,哪些必填參數的內容可為空字串或空陣列,僅當$conf["canBeEmptyString"]為"false"時會生效.
912
			#$conf["variableCheck::checkArguments"]["canBeEmpty"]=array();
913
			#$conf["skipableVariableCanNotBeEmpty"],字串陣列,哪些可省略參數不可以為空字串或空陣列.
914
			#$conf["variableCheck::checkArguments"]["skipableVariableCanNotBeEmpty"]=array("wait","workingDir","envs","executeBy");
915
			#$conf["skipableVariableName"],陣列字串,爲可省略參數的變數名稱陣列,形態爲陣列變數,例如: $conf["skipableVariableName"] = array("id","account","password");
916
			#$conf["variableCheck::checkArguments"]["skipableVariableName"]=array("error");
917
			#$conf["skipableVariableType"],陣列字串,爲可省略參數的變數名稱陣列,形態爲陣列變數,例如: $conf["skipableVariableType"] = array("string",integer,"double");
918
			#$conf["variableCheck::checkArguments"]["skipableVariableType"]=array("array");
919
			#$conf["skipableVarDefaultValue"],字串陣列,每個不存在的可省略變數要初始化為什麼,null與代表不指定,若預設值是參數之一,請將$conf["mustBeFilledVar"]改成"\$conf["\mustBeFilledVar\"]".
920
			#$conf["variableCheck::checkArguments"]["skipableVarDefaultValue"]=array("true",null,null,null);
921
			#$conf["disallowAllSkipableVarIsEmpty"],字串,是否允許每個可省略參數都為空字串,預設為"true"允許,反之為"false".
922
			#$conf["disallowAllSkipableVarIsEmpty"]="";
923
			#$conf["disallowAllSkipableVarIsEmptyArray"],字串,是否允許每個可省略參數都為空陣列,預設為"true"允許,反之為"false".
924
			#$conf["disallowAllSkipableVarIsEmptyArray"]="";
925
			#$conf["disallowAllSkipableVarNotExist"],字串,是否不允許每個可省略參數都不存在,預設為"false"代表允許,反之為"true".
926
			#$conf["disallowAllSkipableVarNotExist"]="";
927
			#$conf["arrayCountEqualCheck"],字串陣列,為檢查哪些陣列參數的元素數量要一樣,$conf["arrayCountEqualCheck"][$i]=array()為第$i組key為哪些的變數其元素數量要相等.
928
			#$conf["variableCheck::checkArguments"]["arrayCountEqualCheck"][]=array("");
929
			#參考資料:
930
			#array_keys=>http://php.net/manual/en/function.array-keys.php
931
			#備註:
932
			#無.
933
			$checkArguments=variableCheck::checkArguments($conf["variableCheck::checkArguments"]);
934
			unset($conf["variableCheck::checkArguments"]);
935
 
936
			#如果 $checkArguments["status"] 等於 "false"
937
			if($checkArguments["status"]==="false"){
938
 
939
				#設置錯誤識別
940
				$result["status"]="false";
941
 
942
				#設置錯誤訊息
943
				$result["error"]=$checkArguments;
944
 
945
				#回傳結果
946
				return $result;
947
 
948
				}#if end
949
 
950
			#如果 $checkArguments["passed"] 等於 "false"
951
			if($checkArguments["passed"]==="false"){
952
 
953
				#設置錯誤識別
954
				$result["status"]="false";
955
 
956
				#設置錯誤訊息
957
				$result["error"]=$checkArguments;
958
 
959
				#回傳結果
960
				return $result;
961
 
962
				}#if end
963
 
964
			#如果可能尚在執行中
965
			if($proc["statusCode"]==="?"){
966
 
967
				#取得當下的狀態
968
				$proc_get_status=proc_get_status($proc["process"]);
969
 
970
				#如果執行已經結束,有回傳exitcode
971
				if($proc_get_status["exitcode"]!==-1){
972
 
973
					#設置 statusCode
974
					$conf["procs"][$index]["statusCode"]=$proc_get_status["exitcode"];
975
 
976
					#取得標準輸出
977
					$stdout=stream_get_contents($proc["content"]);
978
 
979
					#取得錯誤輸出
980
					$stderr=stream_get_contents($proc["error"]);
981
 
982
					#設置執行失敗訊息
983
					$conf["procs"][$index]["error"]=$stderr;
984
 
985
					#設置執行結果
986
					$conf["procs"][$index]["content"]=$stdout;
987
 
988
					}#if end
989
 
990
				}#if end
991
 
992
			}#foreach end
993
 
994
		#設置要回傳的結果
995
		$result["content"]=$conf["procs"];
996
 
997
		#設置執行正常
998
		$result["status"]="true";
999
 
1000
		#回傳結果
1001
		return $result;
1002
 
854 liveuser 1003
		}#function proc_update end
849 liveuser 1004
 
1005
	/*
1006
	#函式說明:
566 liveuser 1007
	#透過parallel展示多執行序運作.
1008
	#回傳結果:
1009
	#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
1010
	#$reuslt["error"],執行不正常結束的錯訊息陣列.
1011
	#$result["function"],當前執行的函式名稱.
1012
	#必填參數:
1013
	#無.
1014
	#可省略參數:
1015
	#無.
1016
	#參考資料:
1017
	#https://www.php.net/manual/en/class.parallel-runtime.php
1018
	#備註:
1019
	#需要於編譯PHP時啟用該套件	
1020
	*/
1021
	public static function parallel_demo(){
1022
 
1023
		#初始化要回傳的結果
1024
		$result=array();
1025
 
1026
		#取得當前執行的函數名稱
1027
		$result["function"]=__FUNCTION__;
1028
 
1029
		#新增程序r1
1030
		$r1=new \parallel\Runtime();
1031
 
1032
		#r1要執行的函式
1033
		$thread_r1_function=function($conf){
1034
 
1035
			#提示開始
1036
			echo $conf["id"]." start".PHP_EOL;
1037
 
1038
			#跑 $conf["i"] 次
1039
			for($i=0;$i<$conf["i"];$i++){
1040
 
1041
				#題書$i數值
1042
				echo "\$i=".$i.PHP_EOL;
1043
 
1044
				}#for end
1045
 
1046
			#提示結束
1047
			echo $conf["id"]." end".PHP_EOL;
1048
 
1049
			};#function end
1050
 
1051
		#r1的參數
1052
		$args_r1=array();
1053
		$args_r1["id"]="r1";
1054
		$args_r1["i"]=10;
1055
 
1056
		#運行程序r1
1057
		#程序函式為 $thread_r1_function
1058
		#參數陣列為 $args_r1
1059
		$future_r1=$r1->run($thread_r1_function, $args_r1);
1060
 
1061
		#新增程序r2
1062
		$r2=new \parallel\Runtime();
1063
 
1064
		#r2要執行的函式
1065
		$thread_r2_function=function($conf){
1066
 
1067
			#提示開始
1068
			echo $conf["id"]." start".PHP_EOL;
1069
 
1070
			#跑 $conf["i"] 次
1071
			for($i=$conf["i"];$i>0;$i--){
1072
 
1073
				#題書$i數值
1074
				echo "\$i=".$i.PHP_EOL;
1075
 
1076
				}#for end
1077
 
1078
			#提示結束
1079
			echo $conf["id"]." end".PHP_EOL;
1080
 
1081
			};#function end
1082
 
1083
		#r2的參數
1084
		$args_r2=array();
1085
		$args_r2["id"]="r2";
1086
		$args_r2["i"]=10;
1087
 
1088
		#運行程序r2
1089
		#程序函式為 $thread__r2_function
1090
		#參數陣列為 $args_r2
1091
		$future_r2=$r2->run($thread_r2_function, $args_r2);
1092
 
1093
		#存放有多少在執行的程序
1094
		$futureArray=array();
1095
		$futureArray[]=$future_r1;
1096
		$futureArray[]=$future_r2;
1097
 
1098
		#當有程序尚未結束時
1099
		while(!empty($futureArray)){
1100
 
1101
			#針對每個 Future
1102
			foreach($futureArray as $index => $Future){
1103
 
1104
				#如果執行完成了
1105
				if($Future->done()){
1106
 
1107
					#移除之
1108
					unset($futureArray[$index]);
1109
 
1110
					}#if end
1111
 
1112
				}#foreach end
1113
 
1114
			}#while end
1115
 
1116
		#提示所有程序都執行結束了
1117
		echo "all done!".PHP_EOL;
1118
 
1119
		#設置執行正常
1120
		$result["status"]="true";
1121
 
1122
		#回傳結果
1123
		return $result;
1124
 
1125
		}#function parallel_demo end
851 liveuser 1126
 
1127
	/*
1128
	#函式說明:
1129
	#透過 unix socket 來多執行序運作.
1130
	#回傳結果:
1131
	#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
1132
	#$reuslt["error"],執行不正常結束的錯訊息陣列.
1133
	#$result["function"],當前執行的函式名稱.
1134
	#$result["argu"],使用的參數.
855 liveuser 1135
	#$result["content"],陣列,每個元素為cmds參數中個別元素其指令傳送後得到的uuid,可透過sock::getProcInfo來查詢結果.
851 liveuser 1136
	#必填參數:
1137
	#$conf["cmds"],字串陣列,每個元素代表要執行的指令與參數.
1138
	#$conf["cmds"]=array();
1139
	#可省略參數:
852 liveuser 1140
	#$conf["sock"],字串,要連線的 usr/bin/qbpwcf-sock.php 所產生的 unix domain socket 路徑與名稱,預設為 qbpwcf_usock_path.
1141
	#$conf["sock"]=qbpwcf_usock_path;
851 liveuser 1142
	#參考資料:
1143
	#無
1144
	#備註:
1145
	#需要透過sock::unixDomainSockServer來運行.
1146
	*/
1147
	public static function socket(&$conf){
1148
 
1149
		#初始化要回傳的變數
1150
		$result=array();
566 liveuser 1151
 
851 liveuser 1152
		#初始化當前執行的函數名稱
1153
		$result["function"]=__FUNCTION__;
1154
 
1155
		#如果 $conf 不為陣列
1156
		if(gettype($conf)!="array"){
1157
 
1158
			#設置執行失敗
1159
			$result["status"]="false";
1160
 
1161
			#設置執行錯誤訊息
1162
			$result["error"][]="\$conf變數須為陣列形態";
1163
 
1164
			#如果傳入的參數為 null
1165
			if($conf==null){
1166
 
1167
				#設置執行錯誤訊息
1168
				$result["error"][]="\$conf變數不得為null,請檢查函數「".$result["function"]."」的參數設置有無正確!";
1169
 
1170
				}#if end
1171
 
1172
			#回傳結果
1173
			return $result;
1174
 
1175
			}#if end
1176
 
1177
		#取得使用的參數
1178
		$result["argu"]=$conf;
1179
 
1180
		#函式說明:
1181
		#檢查必填與可省略的參數,可省略參數可指定預設要給與什麼數值內容.
1182
		#回傳結果:
1183
		#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
1184
		#$result["error"],執行不正常結束的錯訊息陣列.
1185
		#$result["simpleError"],簡單表示的錯誤訊息.
1186
		#$result["function"],當前執行的函式名稱.
1187
		#$result["argu"],設置給予的參數.
1188
		#$result["passed"],識別要檢查的全體變數是否存在以及型態是否正確的變數,"true"代表檢查全部通過;"false"代表檢查不通過
1189
		#$result[$shouldBeCheckedVarName]["varExist"],所檢查的變數是否存在,"false"代表不存在;"true"代表存在
1190
		#$result[$shouldBeCheckedVarName]["varType"],所檢查的變數型態是否正確,"false"代表錯誤;"true"代表正確
1191
		#$result[$shouldBeCheckedVarName]["error"],每個參數設定的錯誤訊息
1192
		#$result["shouldNotBeEmpty"],不應該為空字串或控陣列的變數.
1193
		#$result["argu"],字串陣列,目前輸入的參數名稱陣列.
1194
		#$result["legalVarName"],字串陣列,合法可用的參數名稱陣列.
1195
		#$result["notNeedVar"],字串陣列,多餘的參數名稱.
1196
		#必填參數:
1197
		#$conf["varInput"],陣列變數,要檢查的陣列變數,請在要檢查的參數前面加上&,這樣變動的結果才能被套用。
1198
		$conf["variableCheck::checkArguments"]["varInput"]=&$conf;
1199
		#$conf["referenceVarKey"],字串,$conf參數後面的key值,用於移除不要的參考陣列.
1200
		$conf["variableCheck::checkArguments"]["referenceVarKey"]="variableCheck::checkArguments";
1201
		#可省略參數:
1202
		#$conf["mustBeFilledVariableName"],爲必填參數的變數名稱陣列,形態爲陣列變數,元素數量需要跟"mustBeFilledVariableType"參數的元素數量一致,例如: $conf["mustBeFilledVariableName"] = array("id","account","password");
1203
		$conf["variableCheck::checkArguments"]["mustBeFilledVariableName"]=array("cmds");
1204
		#$conf["mustBeFilledVariableType"],爲必填參數的變數陣列應該爲何種變數形態,形態爲陣列,元素數量需要跟"mustBeFilledVariableName"參數的元素數量一致,例如: $conf["mustBeFilledVariableType"] = array("string",integer,"double","resource","object"); , null代表不指定變數形態.
1205
		$conf["variableCheck::checkArguments"]["mustBeFilledVariableType"]=array("array");
1206
		#$conf["canBeEmptyString"],字串,必填變數內容如果是空字串就不能算是有設置的話,請設為"false",預設爲"true",可以為空字串.
1207
		$conf["variableCheck::checkArguments"]["canBeEmptyString"]="false";
1208
		#$conf["canNotBeEmpty"],字串陣列,哪些必填參數的內容不得為空字串或空陣列,僅當$conf["canBeEmptyString"]為"true"時會生效.
1209
		#$conf["canNotBeEmpty"]=array();
1210
		#$conf["canBeEmpty"],字串陣列,哪些必填參數的內容可為空字串或空陣列,僅當$conf["canBeEmptyString"]為"false"時會生效.
1211
		#$conf["canBeEmpty"]=array();
1212
		#$conf["skipableVariableCanNotBeEmpty"],字串陣列,哪些可省略參數不可以為空字串或空陣列.
852 liveuser 1213
		$conf["variableCheck::checkArguments"]["skipableVariableCanNotBeEmpty"]=array("sock");
851 liveuser 1214
		#$conf["skipableVariableName"],陣列字串,爲可省略參數的變數名稱陣列,形態爲陣列變數,例如: $conf["skipableVariableName"] = array("id","account","password");
852 liveuser 1215
		$conf["variableCheck::checkArguments"]["skipableVariableName"]=array("sock");
851 liveuser 1216
		#$conf["skipableVariableType"],陣列字串,爲可省略參數的變數名稱陣列,形態爲陣列變數,例如: $conf["skipableVariableType"] = array("string",integer,"double");
852 liveuser 1217
		$conf["variableCheck::checkArguments"]["skipableVariableType"]=array("string");
851 liveuser 1218
		#$conf["skipableVarDefaultValue"],字串陣列,每個不存在的可省略變數要初始化為什麼,null與代表不指定,若預設值是參數之一,請將$conf["mustBeFilledVar"]改成"\$conf["\mustBeFilledVar\"]".
852 liveuser 1219
		$conf["variableCheck::checkArguments"]["skipableVarDefaultValue"]=array(null);
851 liveuser 1220
		#$conf["disallowAllSkipableVarIsEmpty"],字串,是否允許每個可省略參數都為空字串,預設為"true"允許,反之為"false".
1221
		#$conf["disallowAllSkipableVarIsEmpty"]="";
1222
		#$conf["disallowAllSkipableVarIsEmptyArray"],字串,是否允許每個可省略參數都為空陣列,預設為"true"允許,反之為"false".
1223
		#$conf["disallowAllSkipableVarIsEmptyArray"]="";
1224
		#$conf["disallowAllSkipableVarNotExist"],字串,是否不允許每個可省略參數都不存在,預設為"false"代表允許,反之為"true".
1225
		#$conf["disallowAllSkipableVarNotExist"]="";
1226
		#$conf["arrayCountEqualCheck"],字串陣列,為檢查哪些陣列參數的元素數量要一樣,$conf["arrayCountEqualCheck"][$i]=array()為第$i組key為哪些的變數其元素數量要相等.
1227
		#$conf["variableCheck::checkArguments"]["arrayCountEqualCheck"][]=array("");
1228
		#參考資料:
1229
		#array_keys=>http://php.net/manual/en/function.array-keys.php
1230
		#備註:
1231
		#無.
1232
		$checkArguments=variableCheck::checkArguments($conf["variableCheck::checkArguments"]);
1233
		unset($conf["variableCheck::checkArguments"]);
1234
 
1235
		#如果 $checkArguments["status"] 等於 "false"
1236
		if($checkArguments["status"]==="false"){
1237
 
1238
			#設置錯誤識別
1239
			$result["status"]="false";
1240
 
1241
			#設置錯誤訊息
1242
			$result["error"]=$checkArguments;
1243
 
1244
			#回傳結果
1245
			return $result;
1246
 
1247
			}#if end
1248
 
1249
		#如果 $checkArguments["passed"] 等於 "false"
1250
		if($checkArguments["passed"]==="false"){
1251
 
1252
			#設置錯誤識別
1253
			$result["status"]="false";
1254
 
1255
			#設置錯誤訊息
1256
			$result["error"]=$checkArguments;
1257
 
1258
			#回傳結果
1259
			return $result;
1260
 
1261
			}#if end
1262
 
1263
		#針對每個指令
1264
		foreach($conf["cmds"] as $cmd){
1265
 
1266
			#連線到 usr/bin/qbpwcf-usock.php 產生的  unix domain socket,運行指定的指令.
1267
			#回傳結果:
1268
			#$result["status"],"true"代表執行正常;"false"代表執行不正常.
1269
			#$result["error"],錯誤訊息陣列.
1270
			#$result["function"],當前執行的函式名稱.
1271
			#$result["argu"],使用的參數.
1272
			#$result["content"],執行完指令的結果.
1273
			#必填參數:
1274
			#$conf["fileArgu"],字串,變數__FILE__的內容.
1275
			$conf["sock::execAnyCmdByQBPWCFunixSocket"]["fileArgu"]=__FILE__;
1276
			#$conf["command"],字串,要執行的指令名稱.
1277
			$conf["sock::execAnyCmdByQBPWCFunixSocket"]["command"]=$cmd;
1278
			#可省略參數:
852 liveuser 1279
 
1280
			#如果有設置 sock 參數
1281
			if(isset($conf["sock"])){
1282
 
1283
				#$conf["sock"],字串,要連線的 usr/bin/qbpwcf-sock.php 所產生的 unix domain socket 路徑與名稱,預設為 qbpwcf_usock_path.
1284
				$conf["sock::execAnyCmdByQBPWCFunixSocket"]["sock"]=$conf["sock"];
1285
 
1286
				}#if end
1287
 
851 liveuser 1288
			#$conf["argu"],陣列字串,指令搭配的參數,預設為空陣列.
1289
			#$conf["sock::execAnyCmdByQBPWCFunixSocket"]["argu"]=$conf["argu"];
1290
			#$conf["commandIncludeArgu"],字串,是否command含有參數,預設為"false"代表沒有;反之為"true".
1291
			$conf["sock::execAnyCmdByQBPWCFunixSocket"]["commandIncludeArgu"]="true";
1292
			#$conf["commandInBg"],字串,是否要將程序放在背景執行,再取得相關資訊,預設為"false"代表不要;反之為"true".
1293
			$conf["sock::execAnyCmdByQBPWCFunixSocket"]["commandInBg"]="true";
1294
			#參考資料:
1295
			#無.
1296
			#備註:
1297
			#無.
1298
			$execAnyCmdByQBPWCFunixSocket=sock::execAnyCmdByQBPWCFunixSocket($conf["sock::execAnyCmdByQBPWCFunixSocket"]);
1299
			unset($conf["sock::execAnyCmdByQBPWCFunixSocket"]);
1300
 
1301
			#如果執行失敗
1302
			if($execAnyCmdByQBPWCFunixSocket["status"]==="false"){
1303
 
1304
				#設置錯誤識別
1305
				$result["status"]="false";
1306
 
1307
				#設置錯誤訊息
1308
				$result["error"]=$execAnyCmdByQBPWCFunixSocket;
1309
 
1310
				#回傳結果
1311
				return $result;
1312
 
1313
				}#if end
855 liveuser 1314
 
1315
			#debug
873 liveuser 1316
			#var_dump(__LINE__,$execAnyCmdByQBPWCFunixSocket);
855 liveuser 1317
 
851 liveuser 1318
			#儲存收到的回應
852 liveuser 1319
			$result["content"][]=$execAnyCmdByQBPWCFunixSocket["content"];
851 liveuser 1320
 
1321
			}#foreach end
1322
 
1323
		#設置執行正常
1324
		$result["status"]="true";
1325
 
1326
		#回傳結果
1327
		return $result;
1328
 
1329
		}#function socket end
1330
 
566 liveuser 1331
	}#class threads end