Subversion Repositories php-qbpwcf

Rev

Rev 350 | 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.
239 liveuser 6
    Copyright (C) 2014~2026 MIN ZHI, CHEN
3 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(){
226 liveuser 126
 
3 liveuser 127
		#執行demo
128
		var_dump(self::proc_demo());
226 liveuser 129
 
3 liveuser 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(){
226 liveuser 149
 
3 liveuser 150
		#初始化 descriptorspec
151
		$descriptorspec = array();
226 liveuser 152
 
3 liveuser 153
		#stdin is a pipe that the child will read from
154
		$descriptorspec[]=array("pipe", "r");
226 liveuser 155
 
3 liveuser 156
		#stdout is a pipe that the child will write to
157
		$descriptorspec[]=array("pipe", "w");
226 liveuser 158
 
3 liveuser 159
		#stderr is a pipe that the child will write to
160
		$descriptorspec[]=array("pipe", "w");
226 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)
3 liveuser 163
		$cwd = null;
226 liveuser 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
3 liveuser 166
		$env = array("QBPWCF" => "Quick Build PHP Website Componment base on Fedora Linux");
226 liveuser 167
 
3 liveuser 168
		#初始化儲存要多執行序執行的程式
169
		$codes=array();
226 liveuser 170
 
3 liveuser 171
		#初始化要demo用的url
172
		$demoUrl="https://qbpwc.sourceforge.io/";
226 liveuser 173
 
3 liveuser 174
		#要多執行序執行的程式1
175
		$codes[]=array("bash","curl -v -L --ssl-reqd ".$demoUrl);
226 liveuser 176
 
3 liveuser 177
		#要多執行序執行的程式2
178
		$codes[]=array("bash","curl -v -L --ssl-reqd ".$demoUrl);
226 liveuser 179
 
3 liveuser 180
		#要多執行序執行的程式3
181
		$codes[]=array("bash","curl -v -L --ssl-reqd ".$demoUrl);
226 liveuser 182
 
3 liveuser 183
		#debug
184
		#var_dump(__LINE__,$codes);
226 liveuser 185
 
3 liveuser 186
		#儲存每個要執行的程式資訊
187
		$process=array();
226 liveuser 188
 
3 liveuser 189
		#針對每個要執行的程式內容
190
		foreach($codes as $index=>$code){
226 liveuser 191
 
3 liveuser 192
			#取得要用什麼程式執行
193
			$executeBy=$code[0];
226 liveuser 194
 
3 liveuser 195
			#取得要執行的程式內容
196
			$code=$code[1];
226 liveuser 197
 
3 liveuser 198
			#運行 php 程式,並儲存 resource
199
			$process[$index]["resource"] = proc_open($executeBy, $descriptorspec, $pipes, $cwd, $env);
226 liveuser 200
 
3 liveuser 201
			#儲存對應的 pipes
202
			$process[$index]["pipes"]=$pipes;
226 liveuser 203
 
3 liveuser 204
			#debug
205
			#var_dump(__LINE__,$process[$index]);
226 liveuser 206
 
3 liveuser 207
			#如果有成功執行
208
			if(is_resource($process[$index]["resource"])){
226 liveuser 209
 
3 liveuser 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
226 liveuser 214
 
3 liveuser 215
				#寫入內容作為 $executeBy 的輸入
216
				$bytes2write=fwrite($process[$index]["pipes"][0], $code);
226 liveuser 217
 
3 liveuser 218
				#debug
219
				#var_dump(__LINE__,$bytes2write);
226 liveuser 220
 
3 liveuser 221
				#結束輸入
222
				fclose($process[$index]["pipes"][0]);
226 liveuser 223
 
3 liveuser 224
				}#if end
226 liveuser 225
 
3 liveuser 226
			#反之,代表運行 php 失敗
227
			else{
226 liveuser 228
 
3 liveuser 229
				#初始化暫存執行結果的變數
230
				$cmdRes=array();
226 liveuser 231
 
3 liveuser 232
				#設置執行失敗
233
				$cmdRes["status"]="false";
226 liveuser 234
 
3 liveuser 235
				#設置執行錯誤訊息
236
				$cmdRes["error"]="execute program by \"".$executeBy."\" failed!";
226 liveuser 237
 
3 liveuser 238
				#設置執行結果
239
				$result["content"][]=$cmdRes;
226 liveuser 240
 
3 liveuser 241
				}#else end
226 liveuser 242
 
3 liveuser 243
			}#foreach end
226 liveuser 244
 
3 liveuser 245
		#debug
246
		#var_dump(__LINE__,$process);
226 liveuser 247
 
3 liveuser 248
		#針對每個回饋
249
		foreach($process as $index => $ps){
226 liveuser 250
 
3 liveuser 251
			#取得 proc resource
252
			$resource=$ps["resource"];
226 liveuser 253
 
3 liveuser 254
			#取得標準輸出
255
			$stdout=stream_get_contents($process[$index]["pipes"][1]);
226 liveuser 256
 
3 liveuser 257
			#取得錯誤輸出
258
			$stderr=stream_get_contents($process[$index]["pipes"][2]);
226 liveuser 259
 
3 liveuser 260
			#debug
261
			#var_dump($stdout);
226 liveuser 262
 
3 liveuser 263
			#初始化暫存執行狀況的變數
264
			$cmdRes=array();
226 liveuser 265
 
3 liveuser 266
			#設置執行失敗訊息
267
			$cmdRes["error"]=$stderr;
226 liveuser 268
 
3 liveuser 269
			#設置執行結果
270
			$cmdRes["content"]=$stdout;
226 liveuser 271
 
3 liveuser 272
			#debug
273
			#var_dump($cmdRes);
226 liveuser 274
 
3 liveuser 275
			#結束讀取標準輸出
276
			fclose($process[$index]["pipes"][1]);
226 liveuser 277
 
3 liveuser 278
			#結束讀取錯誤輸出
279
			fclose($process[$index]["pipes"][2]);
226 liveuser 280
 
3 liveuser 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);
226 liveuser 283
 
3 liveuser 284
			#debug
285
			#var_dump($cmdRes["statusCode"]);
226 liveuser 286
 
3 liveuser 287
			#預設執行不正常
288
			$cmdRes["status"]="false";
226 liveuser 289
 
3 liveuser 290
			#如果執行正常
291
			if($cmdRes["statusCode"]===0){
226 liveuser 292
 
3 liveuser 293
				#設置執行正常
294
				$cmdRes["status"]="true";
226 liveuser 295
 
3 liveuser 296
				}#if end
226 liveuser 297
 
3 liveuser 298
			#保存結果
299
			$result["content"][]=$cmdRes;
226 liveuser 300
 
3 liveuser 301
			#debug
302
			#var_dump($result);
226 liveuser 303
 
3 liveuser 304
			}#foreach end
226 liveuser 305
 
3 liveuser 306
		#設置執行正常
307
		$result["status"]="true";
226 liveuser 308
 
3 liveuser 309
		#debug
310
		#var_dump($result);
226 liveuser 311
 
3 liveuser 312
		#回傳結果
313
		return $result;
226 liveuser 314
 
3 liveuser 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"],使用的參數.
293 liveuser 325
	#$result["content"],陣列,每個元素為其指令執行的結果訊息陣列,key為"status"代表執行是否正常的識別;key為"statusCode"代表程式結束後回傳給對應executeBy程式的數值,若為"?"則代表程序尚未結束,若為整數0,則代表順利執行結束,可透過proc_update函式進行資訊的更新與取得;key為"content"代表標準輸出,若為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
	#備註:
249 liveuser 345
	#當wait參數為"true"時,會自動解析stdout與stderr,因此不用再透過 self::proc_update 來更新.
346
	#當wait參數不為"true"時,若需要取得當下的執行狀況,請使用 self::proc_update 來更新.
3 liveuser 347
	*/
348
	public static function proc(&$conf){
226 liveuser 349
 
3 liveuser 350
		#初始化要回傳的變數
351
		$result=array();
352
 
353
		#初始化當前執行的函數名稱
354
		$result["function"]=__FUNCTION__;
355
 
356
		#如果 $conf 不為陣列
66 liveuser 357
		if(gettype($conf)!=="array"){
226 liveuser 358
 
3 liveuser 359
			#設置執行失敗
360
			$result["status"]="false";
226 liveuser 361
 
3 liveuser 362
			#設置執行錯誤訊息
363
			$result["error"][]="\$conf變數須為陣列形態";
364
 
365
			#如果傳入的參數為 null
66 liveuser 366
			if($conf===null){
226 liveuser 367
 
3 liveuser 368
				#設置執行錯誤訊息
369
				$result["error"][]="\$conf變數不得為null,請檢查函數「".$result["function"]."」的參數設置有無正確!";
226 liveuser 370
 
3 liveuser 371
				}#if end
372
 
373
			#回傳結果
374
			return $result;
226 liveuser 375
 
3 liveuser 376
			}#if end
226 liveuser 377
 
3 liveuser 378
		#取得使用的參數
379
		$result["argu"]=$conf;
226 liveuser 380
 
3 liveuser 381
		#函式說明:
382
		#檢查必填與可省略的參數,可省略參數可指定預設要給與什麼數值內容.
383
		#回傳結果:
384
		#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
385
		#$result["error"],執行不正常結束的錯訊息陣列.
386
		#$result["simpleError"],簡單表示的錯誤訊息.
387
		#$result["function"],當前執行的函式名稱.
388
		#$result["argu"],設置給予的參數.
389
		#$result["passed"],識別要檢查的全體變數是否存在以及型態是否正確的變數,"true"代表檢查全部通過;"false"代表檢查不通過
390
		#$result[$shouldBeCheckedVarName]["varExist"],所檢查的變數是否存在,"false"代表不存在;"true"代表存在
391
		#$result[$shouldBeCheckedVarName]["varType"],所檢查的變數型態是否正確,"false"代表錯誤;"true"代表正確
392
		#$result[$shouldBeCheckedVarName]["error"],每個參數設定的錯誤訊息
393
		#$result["shouldNotBeEmpty"],不應該為空字串或控陣列的變數.
394
		#$result["argu"],字串陣列,目前輸入的參數名稱陣列.
395
		#$result["legalVarName"],字串陣列,合法可用的參數名稱陣列.
396
		#$result["notNeedVar"],字串陣列,多餘的參數名稱.
397
		#必填參數:
398
		#$conf["varInput"],陣列變數,要檢查的陣列變數,請在要檢查的參數前面加上&,這樣變動的結果才能被套用。
399
		$conf["variableCheck::checkArguments"]["varInput"]=&$conf;
400
		#$conf["referenceVarKey"],字串,$conf參數後面的key值,用於移除不要的參考陣列.
401
		$conf["variableCheck::checkArguments"]["referenceVarKey"]="variableCheck::checkArguments";
402
		#可省略參數:
403
		#$conf["mustBeFilledVariableName"],爲必填參數的變數名稱陣列,形態爲陣列變數,元素數量需要跟"mustBeFilledVariableType"參數的元素數量一致,例如: $conf["mustBeFilledVariableName"] = array("id","account","password");
404
		$conf["variableCheck::checkArguments"]["mustBeFilledVariableName"]=array("cmds");
405
		#$conf["mustBeFilledVariableType"],爲必填參數的變數陣列應該爲何種變數形態,形態爲陣列,元素數量需要跟"mustBeFilledVariableName"參數的元素數量一致,例如: $conf["mustBeFilledVariableType"] = array("string",integer,"double","resource","object"); , null代表不指定變數形態.
406
		$conf["variableCheck::checkArguments"]["mustBeFilledVariableType"]=array("array");
407
		#$conf["canBeEmptyString"],字串,必填變數內容如果是空字串就不能算是有設置的話,請設為"false",預設爲"true",可以為空字串.
408
		#$conf["variableCheck::checkArguments"]["canBeEmptyString"]="false";
409
		#$conf["canNotBeEmpty"],字串陣列,哪些必填參數的內容不得為空字串或空陣列,僅當$conf["canBeEmptyString"]為"true"時會生效.
410
		#$conf["canNotBeEmpty"]=array();
411
		#$conf["canBeEmpty"],字串陣列,哪些必填參數的內容可為空字串或空陣列,僅當$conf["canBeEmptyString"]為"false"時會生效.
412
		#$conf["canBeEmpty"]=array();
413
		#$conf["skipableVariableCanNotBeEmpty"],字串陣列,哪些可省略參數不可以為空字串或空陣列.
140 liveuser 414
		$conf["variableCheck::checkArguments"]["skipableVariableCanNotBeEmpty"]=array("wait","workingDir","envs","executeBy","timeout");
3 liveuser 415
		#$conf["skipableVariableName"],陣列字串,爲可省略參數的變數名稱陣列,形態爲陣列變數,例如: $conf["skipableVariableName"] = array("id","account","password");
140 liveuser 416
		$conf["variableCheck::checkArguments"]["skipableVariableName"]=array("wait","workingDir","envs","executeBy","timeout");
3 liveuser 417
		#$conf["skipableVariableType"],陣列字串,爲可省略參數的變數名稱陣列,形態爲陣列變數,例如: $conf["skipableVariableType"] = array("string",integer,"double");
140 liveuser 418
		$conf["variableCheck::checkArguments"]["skipableVariableType"]=array("string","array","array","array","array");
3 liveuser 419
		#$conf["skipableVarDefaultValue"],字串陣列,每個不存在的可省略變數要初始化為什麼,null與代表不指定,若預設值是參數之一,請將$conf["mustBeFilledVar"]改成"\$conf["\mustBeFilledVar\"]".
140 liveuser 420
		$conf["variableCheck::checkArguments"]["skipableVarDefaultValue"]=array("true",null,null,null,null);
3 liveuser 421
		#$conf["disallowAllSkipableVarIsEmpty"],字串,是否允許每個可省略參數都為空字串,預設為"true"允許,反之為"false".
422
		#$conf["disallowAllSkipableVarIsEmpty"]="";
423
		#$conf["disallowAllSkipableVarIsEmptyArray"],字串,是否允許每個可省略參數都為空陣列,預設為"true"允許,反之為"false".
424
		#$conf["disallowAllSkipableVarIsEmptyArray"]="";
425
		#$conf["disallowAllSkipableVarNotExist"],字串,是否不允許每個可省略參數都不存在,預設為"false"代表允許,反之為"true".
426
		#$conf["disallowAllSkipableVarNotExist"]="";
427
		#$conf["arrayCountEqualCheck"],字串陣列,為檢查哪些陣列參數的元素數量要一樣,$conf["arrayCountEqualCheck"][$i]=array()為第$i組key為哪些的變數其元素數量要相等.
428
		#$conf["variableCheck::checkArguments"]["arrayCountEqualCheck"][]=array("");
429
		#參考資料:
430
		#array_keys=>http://php.net/manual/en/function.array-keys.php
431
		#備註:
432
		#無.
433
		$checkArguments=variableCheck::checkArguments($conf["variableCheck::checkArguments"]);
434
		unset($conf["variableCheck::checkArguments"]);
226 liveuser 435
 
3 liveuser 436
		#如果 $checkArguments["status"] 等於 "false"
437
		if($checkArguments["status"]==="false"){
226 liveuser 438
 
3 liveuser 439
			#設置錯誤識別
440
			$result["status"]="false";
226 liveuser 441
 
3 liveuser 442
			#設置錯誤訊息
443
			$result["error"]=$checkArguments;
226 liveuser 444
 
3 liveuser 445
			#回傳結果
446
			return $result;
226 liveuser 447
 
3 liveuser 448
			}#if end
226 liveuser 449
 
3 liveuser 450
		#如果 $checkArguments["passed"] 等於 "false"
451
		if($checkArguments["passed"]==="false"){
226 liveuser 452
 
3 liveuser 453
			#設置錯誤識別
454
			$result["status"]="false";
226 liveuser 455
 
3 liveuser 456
			#設置錯誤訊息
457
			$result["error"]=$checkArguments;
226 liveuser 458
 
3 liveuser 459
			#回傳結果
460
			return $result;
226 liveuser 461
 
3 liveuser 462
			}#if end
226 liveuser 463
 
3 liveuser 464
		#初始化 descriptorspec
465
		$descriptorspec = array();
226 liveuser 466
 
3 liveuser 467
		#stdin is a pipe that the child will read from
468
		$descriptorspec[]=array("pipe", "r");
226 liveuser 469
 
3 liveuser 470
		#stdout is a pipe that the child will write to
471
		$descriptorspec[]=array("pipe", "w");
226 liveuser 472
 
3 liveuser 473
		#stderr is a pipe that the child will write to
474
		$descriptorspec[]=array("pipe", "w");
226 liveuser 475
 
476
		#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)
3 liveuser 477
		$defaultCWD = null;
226 liveuser 478
 
3 liveuser 479
		#初始化儲存每個指令的working dir.
480
		$cwds=array();
226 liveuser 481
 
3 liveuser 482
		#有幾個指令就執行幾次
483
		for($i=0;$i<count($conf["cmds"]);$i++){
226 liveuser 484
 
3 liveuser 485
			#設置預設working dir
486
			$cwds[]=$defaultCWD;
226 liveuser 487
 
3 liveuser 488
			}#for end
226 liveuser 489
 
3 liveuser 490
		#如果有設置 workingDir
491
		if(isset($conf["workingDir"])){
226 liveuser 492
 
3 liveuser 493
			#如果數量符合
494
			if(count($conf["cmds"])===count($conf["workingDir"])){
226 liveuser 495
 
3 liveuser 496
				#有幾個指令就執行幾次
497
				for($i=0;$i<count($conf["cmds"]);$i++){
226 liveuser 498
 
3 liveuser 499
					#預設為指定數值
340 liveuser 500
					$cwds[$i]=$conf["workingDir"][$i];
226 liveuser 501
 
3 liveuser 502
					}#for end
226 liveuser 503
 
3 liveuser 504
				}#if end
226 liveuser 505
 
3 liveuser 506
			}#if end
226 liveuser 507
 
508
		#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
3 liveuser 509
		$defaultENV = array("QBPWCF" => "Quick Build PHP Website Componment base on Fedora Linux");
226 liveuser 510
 
3 liveuser 511
		#初始化儲存每個指令的環境變數.
512
		$envs=array();
226 liveuser 513
 
3 liveuser 514
		#有幾個指令就執行幾次
515
		for($i=0;$i<count($conf["cmds"]);$i++){
226 liveuser 516
 
3 liveuser 517
			#設置預設環境變數
518
			$envs[]=$defaultENV;
226 liveuser 519
 
3 liveuser 520
			}#for end
226 liveuser 521
 
3 liveuser 522
		#如果有設置 envs
523
		if(isset($conf["envs"])){
226 liveuser 524
 
3 liveuser 525
			#如果數量符合
526
			if(count($conf["cmds"])===count($conf["envs"])){
226 liveuser 527
 
3 liveuser 528
				#有幾個指令就執行幾次
529
				for($i=0;$i<count($conf["cmds"]);$i++){
226 liveuser 530
 
3 liveuser 531
					#預設為指定數值
532
					$envs[]=$conf["envs"][$i];
226 liveuser 533
 
3 liveuser 534
					}#for end
226 liveuser 535
 
3 liveuser 536
				}#if end
226 liveuser 537
 
3 liveuser 538
			}#if end
226 liveuser 539
 
3 liveuser 540
		#預設程式都透過 bash 來執行
541
		$defaultExecBy="bash";
226 liveuser 542
 
3 liveuser 543
		#初始化儲存每個指令要透過什麼程式執行
544
		$executeBys=array();
226 liveuser 545
 
3 liveuser 546
		#有幾個指令就執行幾次
547
		for($i=0;$i<count($conf["cmds"]);$i++){
226 liveuser 548
 
3 liveuser 549
			#設置預設環境變數
550
			$executeBys[]=$defaultExecBy;
226 liveuser 551
 
3 liveuser 552
			}#for end
226 liveuser 553
 
3 liveuser 554
		#如果有設置 executeBy
555
		if(isset($conf["executeBy"])){
226 liveuser 556
 
3 liveuser 557
			#如果數量符合
558
			if(count($conf["cmds"])===count($conf["executeBy"])){
226 liveuser 559
 
3 liveuser 560
				#初始化儲存每個指令要透過什麼程式執行
561
				$executeBys=array();
226 liveuser 562
 
3 liveuser 563
				#有幾個指令就執行幾次
564
				for($i=0;$i<count($conf["cmds"]);$i++){
226 liveuser 565
 
3 liveuser 566
					#預設為指定數值
567
					$executeBys[]=$conf["executeBy"][$i];
226 liveuser 568
 
3 liveuser 569
					}#for end
226 liveuser 570
 
3 liveuser 571
				}#if end
226 liveuser 572
 
3 liveuser 573
			}#if end
226 liveuser 574
 
3 liveuser 575
		#儲存每個要執行的程式資訊
576
		$process=array();
226 liveuser 577
 
3 liveuser 578
		#debug
579
		#var_dump(__LINE__,$executeBys);
226 liveuser 580
 
3 liveuser 581
		#針對每個指令與參數字串
582
		foreach($conf["cmds"] as $index=>$cmdAndArguStr){
226 liveuser 583
 
3 liveuser 584
			#debug
585
			#var_dump(__LINE__,$executeBys[$index]);
226 liveuser 586
 
340 liveuser 587
			#debug
588
			#var_dump(__LINE__,$cwds[$index]);
589
 
3 liveuser 590
			#運行 php 程式,並儲存 resource
591
			$process[$index]["resource"] = proc_open($executeBys[$index], $descriptorspec, $pipes, $cwds[$index], $envs[$index]);
226 liveuser 592
 
3 liveuser 593
			#儲存對應的 pipes
594
			$process[$index]["pipes"]=$pipes;
226 liveuser 595
 
3 liveuser 596
			#如果有成功執行
597
			if(is_resource($process[$index]["resource"])){
226 liveuser 598
 
3 liveuser 599
				#$pipes now looks like this:
600
				#0 => writeable handle connected to child stdin
601
				#1 => readable handle connected to child stdout
602
				#2 => readable handle connected to child stdin
226 liveuser 603
 
3 liveuser 604
				#寫入內容作為 $executeBy 的輸入
605
				$bytes2write=fwrite($process[$index]["pipes"][0], $cmdAndArguStr);
226 liveuser 606
 
3 liveuser 607
				#結束輸入
608
				fclose($process[$index]["pipes"][0]);
226 liveuser 609
 
3 liveuser 610
				#如果有完整寫入指令
611
				if($bytes2write===strlen($cmdAndArguStr)){
226 liveuser 612
 
3 liveuser 613
					#記錄輸入的指令
614
					$process[$index]["input"]=$cmdAndArguStr;
226 liveuser 615
 
3 liveuser 616
					}#if end
226 liveuser 617
 
3 liveuser 618
				#反之
619
				else{
226 liveuser 620
 
3 liveuser 621
					#設置錯誤識別
622
					$result["status"]="false";
226 liveuser 623
 
3 liveuser 624
					#設置錯誤訊息
625
					$result["error"][]="將指令(".$cmdAndArguStr.")輸入(".$executeBys[$index].")失敗";
226 liveuser 626
 
3 liveuser 627
					#回傳結果
628
					return $result;
226 liveuser 629
 
3 liveuser 630
					}#else end
226 liveuser 631
 
3 liveuser 632
				}#if end
226 liveuser 633
 
3 liveuser 634
			#反之,代表運行 $executeBys[$index] 失敗
635
			else{
226 liveuser 636
 
3 liveuser 637
				#初始化暫存執行結果的變數
638
				$cmdRes=array();
226 liveuser 639
 
3 liveuser 640
				#設置執行失敗
641
				$cmdRes["status"]="false";
226 liveuser 642
 
3 liveuser 643
				#設置執行錯誤訊息
644
				$cmdRes["error"]="execute program by \"".$executeBys[$index]."\" failed!";
226 liveuser 645
 
3 liveuser 646
				#設置執行結果
647
				$result["content"][]=$cmdRes;
226 liveuser 648
 
3 liveuser 649
				}#else end
226 liveuser 650
 
3 liveuser 651
			}#foreach end
226 liveuser 652
 
3 liveuser 653
		#針對每個回饋
654
		foreach($process as $index => $ps){
226 liveuser 655
 
3 liveuser 656
			#取得 proc resource
657
			$resource=&$ps["resource"];
226 liveuser 658
 
3 liveuser 659
			#取得標準輸出的pipe
660
			$stdout=$process[$index]["pipes"][1];
226 liveuser 661
 
3 liveuser 662
			#取得非標準輸出的pipe
663
			$stderr=$process[$index]["pipes"][2];
226 liveuser 664
 
3 liveuser 665
			#如果需要等待程序執行完
666
			if($conf["wait"]==="true"){
226 liveuser 667
 
140 liveuser 668
				#如果有設置  timeout
669
				if(isset($conf["timeout"])){
226 liveuser 670
 
140 liveuser 671
					#如果有設置該程序的 timeout
672
					if(isset($conf["timeout"][$index])){
226 liveuser 673
 
140 liveuser 674
						#避免 timeout 仍然會等待程序結束 - start
226 liveuser 675
 
140 liveuser 676
						#不讓標準輸出會阻擋程式執行
677
						stream_set_blocking($stdout,false);
226 liveuser 678
 
140 liveuser 679
						#不讓錯誤輸出會阻擋程式執行
680
						stream_set_blocking($stderr,false);
226 liveuser 681
 
140 liveuser 682
						#避免 timeout 仍然會等待程序結束 - end
226 liveuser 683
 
140 liveuser 684
						}#if end
226 liveuser 685
 
140 liveuser 686
					}#if end
226 liveuser 687
 
3 liveuser 688
				}#if end
226 liveuser 689
 
3 liveuser 690
			#反之
691
			else{
226 liveuser 692
 
3 liveuser 693
				#不讓標準輸出會阻擋程式執行
694
				stream_set_blocking($stdout,false);
226 liveuser 695
 
3 liveuser 696
				#不讓錯誤輸出會阻擋程式執行
697
				stream_set_blocking($stderr,false);
226 liveuser 698
 
3 liveuser 699
				}#else end
226 liveuser 700
 
3 liveuser 701
			#初始化暫存執行狀況的變數
702
			$cmdRes=array();
326 liveuser 703
 
704
			#初始化標準輸出預設為空
705
			$cmdRes["content"]="";
706
 
707
			#初始化標準錯誤輸出預設為空
708
			$cmdRes["error"]="";
226 liveuser 709
 
3 liveuser 710
			#取得 proc_open 後的 process resource
711
			$cmdRes["process"]=$resource;
226 liveuser 712
 
3 liveuser 713
			#取得 process 的狀態,包含 pid 等資訊,若程式已經結束,則會自動將pipes關閉,再proc_close.
714
			$cmdRes["proc_get_status"]=proc_get_status($resource);
226 liveuser 715
 
3 liveuser 716
			#預設 statusCode 為 "?" 代表尚未 proc_close
717
			$cmdRes["statusCode"]="?";
226 liveuser 718
 
3 liveuser 719
			#如果執行已經結束,有回傳exitcode
720
			if($cmdRes["proc_get_status"]["exitcode"]!==-1){
226 liveuser 721
 
3 liveuser 722
				#設置 statusCode
723
				$cmdRes["statusCode"]=&$cmdRes["proc_get_status"]["exitcode"];
226 liveuser 724
 
312 liveuser 725
				#當有標準輸出時
726
				while(!feof($stdout)){
727
 
728
					#取得標準輸出
326 liveuser 729
					$cmdRes["content"]=$cmdRes["content"].fread($stdout,2048);
312 liveuser 730
 
731
					}#while end
732
 
733
				#當有錯誤輸出時
734
				while(!feof($stderr)){
735
 
326 liveuser 736
					$cmdRes["error"]=$cmdRes["content"].fread($stderr,2048);
312 liveuser 737
 
738
					}#while end
739
 
740
				#關閉其 proc 的運行 - start
741
 
742
				#關閉標準輸出的pipe
743
				fclose($stdout);
744
 
745
				#關閉標準錯誤的pipe
746
				fclose($stderr);
747
 
748
				#強制結束程序
749
				proc_terminate($resource);
750
 
751
				#結束proc.
752
				proc_close($resource);
753
 
754
				#關閉其 proc 的運行 - end
755
 
3 liveuser 756
				}#if end
226 liveuser 757
 
3 liveuser 758
			#反之未執行完畢,且需要等待程序執行完
759
			else if($conf["wait"]==="true"){
226 liveuser 760
 
140 liveuser 761
				#預設已經執行0秒
762
				$runtime=0;
226 liveuser 763
 
3 liveuser 764
				#無窮迴圈
765
				while(true){
226 liveuser 766
 
140 liveuser 767
					#debug
768
					#var_dump(__LINE__,$runtime,$conf["timeout"]);
226 liveuser 769
 
140 liveuser 770
					#如果有設置  timeout
771
					if(isset($conf["timeout"])){
226 liveuser 772
 
140 liveuser 773
						#如果有設置該程序的 timeout
774
						if(isset($conf["timeout"][$index])){
226 liveuser 775
 
140 liveuser 776
							#如果執行秒數逾時了
777
							if( $runtime > (int)($conf["timeout"][$index]) ){
226 liveuser 778
 
140 liveuser 779
								#debug
780
								#var_dump(__LINE__,"timeout!");
226 liveuser 781
 
140 liveuser 782
								#關閉標準輸出的pipe
783
								fclose($stdout);
226 liveuser 784
 
140 liveuser 785
								#關閉標準錯誤的pipe
786
								fclose($stderr);
226 liveuser 787
 
140 liveuser 788
								#強制結束程序
789
								proc_terminate($resource);
226 liveuser 790
 
140 liveuser 791
								#結束proc.
792
								proc_close($resource);
226 liveuser 793
 
159 liveuser 794
								#結束無窮迴圈
795
								break;
226 liveuser 796
 
140 liveuser 797
								}#if end
226 liveuser 798
 
140 liveuser 799
							}#if end
226 liveuser 800
 
140 liveuser 801
						}#if end
226 liveuser 802
 
3 liveuser 803
					#取得 process 的狀態,包含 pid 等資訊,若程式已經結束,則會自動將pipes關閉,再proc_close.
804
					$cmdRes["proc_get_status"]=proc_get_status($resource);
226 liveuser 805
 
3 liveuser 806
					#如果執行已經結束,有回傳exitcode
807
					if($cmdRes["proc_get_status"]["exitcode"]!==-1){
226 liveuser 808
 
3 liveuser 809
						#設置 statusCode
810
						$cmdRes["statusCode"]=&$cmdRes["proc_get_status"]["exitcode"];
249 liveuser 811
 
159 liveuser 812
						#結束無窮迴圈
3 liveuser 813
						break;
226 liveuser 814
 
3 liveuser 815
						}#if end
226 liveuser 816
 
3 liveuser 817
					#等待1秒鐘
818
					sleep(1);
226 liveuser 819
 
140 liveuser 820
					#執行秒數+1
821
					$runtime++;
226 liveuser 822
 
3 liveuser 823
					}#while end
226 liveuser 824
 
3 liveuser 825
				}#if end
226 liveuser 826
 
3 liveuser 827
			#設置執行失敗訊息
828
			$cmdRes["error"]=$stderr;
226 liveuser 829
 
3 liveuser 830
			#設置執行結果
831
			$cmdRes["content"]=$stdout;
226 liveuser 832
 
3 liveuser 833
			#如果有成功輸入指令
834
			if(isset($process[$index]["input"])){
226 liveuser 835
 
3 liveuser 836
				#設置有輸入的指令
837
				$cmdRes["input"]=$process[$index]["input"];
226 liveuser 838
 
3 liveuser 839
				}#if end
226 liveuser 840
 
3 liveuser 841
			#預設執行不正常
842
			$cmdRes["status"]="false";
226 liveuser 843
 
3 liveuser 844
			#如果執行正常 或 等於"?"(代表尚未 proc_close)
845
			if($cmdRes["statusCode"]===0 || $cmdRes["statusCode"]==="?"){
226 liveuser 846
 
3 liveuser 847
				#設置執行正常
848
				$cmdRes["status"]="true";
226 liveuser 849
 
3 liveuser 850
				}#if end
226 liveuser 851
 
3 liveuser 852
			#保存結果
853
			$result["content"][]=$cmdRes;
226 liveuser 854
 
3 liveuser 855
			}#foreach end
226 liveuser 856
 
249 liveuser 857
		#如果要等待程序執行結束
858
		if($conf["wait"]==="true"){
859
 
860
			#函式說明:
861
			#更新透過proc執行的多程序資訊.
862
			#回傳結果:
863
			#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
864
			#$reuslt["error"],執行不正常結束的錯訊息陣列.
865
			#$result["function"],當前執行的函式名稱.
866
			#$result["argu"],使用的參數.
867
			#$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"代表程序的資訊.
868
			#必填參數:
869
			#$conf["procs"],陣列,運行self::proc後回傳的content.
870
			$conf["threads::proc_update"]["procs"]=$result["content"];
871
			#可省略參數:
872
			#無.
873
			#參考資料:
874
			#無.
875
			#備註:
876
			#無.
877
			$proc_update=threads::proc_update($conf["threads::proc_update"]);
878
			unset($conf["threads::proc_update"]);
879
 
880
			#如果執行異常
881
			if($proc_update["status"]==="false"){
882
 
883
				#設置錯誤識別
884
				$result["status"]="false";
885
 
886
				#設置錯誤訊息
887
				$result["error"]=$proc_update;
888
 
889
				#回傳結果
890
				return $result;
891
 
892
				}#if end
893
 
894
			#debug
895
			#var_dump(__LINE__,$proc_update);exit;
896
 
897
			#取得執行後的標準輸出
898
			$result["content"]=$proc_update["content"];
899
 
900
			}#if end
901
 
3 liveuser 902
		#設置執行正常
903
		$result["status"]="true";
226 liveuser 904
 
3 liveuser 905
		#回傳結果
906
		return $result;
226 liveuser 907
 
3 liveuser 908
		}#function proc end
909
 
910
	/*
911
	#函式說明:
912
	#更新透過proc執行的多程序資訊.
913
	#回傳結果:
914
	#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
915
	#$reuslt["error"],執行不正常結束的錯訊息陣列.
916
	#$result["function"],當前執行的函式名稱.
917
	#$result["argu"],使用的參數.
66 liveuser 918
	#$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 919
	#必填參數:
920
	#$conf["procs"],陣列,運行self::proc後回傳的content.
921
	$conf["procs"]=$procs;
922
	#可省略參數:
923
	#無.
924
	#參考資料:
925
	#無.
926
	#備註:
927
	#無.
928
	*/
929
	public static function proc_update(&$conf){
226 liveuser 930
 
3 liveuser 931
		#初始化要回傳的變數
932
		$result=array();
933
 
934
		#初始化當前執行的函數名稱
935
		$result["function"]=__FUNCTION__;
936
 
937
		#如果 $conf 不為陣列
938
		if(gettype($conf)!="array"){
226 liveuser 939
 
3 liveuser 940
			#設置執行失敗
941
			$result["status"]="false";
226 liveuser 942
 
3 liveuser 943
			#設置執行錯誤訊息
944
			$result["error"][]="\$conf變數須為陣列形態";
945
 
946
			#如果傳入的參數為 null
947
			if($conf==null){
226 liveuser 948
 
3 liveuser 949
				#設置執行錯誤訊息
950
				$result["error"][]="\$conf變數不得為null,請檢查函數「".$result["function"]."」的參數設置有無正確!";
226 liveuser 951
 
3 liveuser 952
				}#if end
953
 
954
			#回傳結果
955
			return $result;
226 liveuser 956
 
3 liveuser 957
			}#if end
226 liveuser 958
 
3 liveuser 959
		#取得使用的參數
960
		$result["argu"]=$conf;
226 liveuser 961
 
3 liveuser 962
		#函式說明:
963
		#檢查必填與可省略的參數,可省略參數可指定預設要給與什麼數值內容.
964
		#回傳結果:
965
		#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
966
		#$result["error"],執行不正常結束的錯訊息陣列.
967
		#$result["simpleError"],簡單表示的錯誤訊息.
968
		#$result["function"],當前執行的函式名稱.
969
		#$result["argu"],設置給予的參數.
970
		#$result["passed"],識別要檢查的全體變數是否存在以及型態是否正確的變數,"true"代表檢查全部通過;"false"代表檢查不通過
971
		#$result[$shouldBeCheckedVarName]["varExist"],所檢查的變數是否存在,"false"代表不存在;"true"代表存在
972
		#$result[$shouldBeCheckedVarName]["varType"],所檢查的變數型態是否正確,"false"代表錯誤;"true"代表正確
973
		#$result[$shouldBeCheckedVarName]["error"],每個參數設定的錯誤訊息
974
		#$result["shouldNotBeEmpty"],不應該為空字串或控陣列的變數.
975
		#$result["argu"],字串陣列,目前輸入的參數名稱陣列.
976
		#$result["legalVarName"],字串陣列,合法可用的參數名稱陣列.
977
		#$result["notNeedVar"],字串陣列,多餘的參數名稱.
978
		#必填參數:
979
		#$conf["varInput"],陣列變數,要檢查的陣列變數,請在要檢查的參數前面加上&,這樣變動的結果才能被套用。
980
		$conf["variableCheck::checkArguments"]["varInput"]=&$conf;
981
		#$conf["referenceVarKey"],字串,$conf參數後面的key值,用於移除不要的參考陣列.
982
		$conf["variableCheck::checkArguments"]["referenceVarKey"]="variableCheck::checkArguments";
983
		#可省略參數:
984
		#$conf["mustBeFilledVariableName"],爲必填參數的變數名稱陣列,形態爲陣列變數,元素數量需要跟"mustBeFilledVariableType"參數的元素數量一致,例如: $conf["mustBeFilledVariableName"] = array("id","account","password");
985
		$conf["variableCheck::checkArguments"]["mustBeFilledVariableName"]=array("procs");
986
		#$conf["mustBeFilledVariableType"],爲必填參數的變數陣列應該爲何種變數形態,形態爲陣列,元素數量需要跟"mustBeFilledVariableName"參數的元素數量一致,例如: $conf["mustBeFilledVariableType"] = array("string",integer,"double","resource","object"); , null代表不指定變數形態.
987
		$conf["variableCheck::checkArguments"]["mustBeFilledVariableType"]=array("array");
988
		#$conf["canBeEmptyString"],字串,必填變數內容如果是空字串就不能算是有設置的話,請設為"false",預設爲"true",可以為空字串.
989
		#$conf["variableCheck::checkArguments"]["canBeEmptyString"]="false";
990
		#$conf["canNotBeEmpty"],字串陣列,哪些必填參數的內容不得為空字串或空陣列,僅當$conf["canBeEmptyString"]為"true"時會生效.
991
		$conf["variableCheck::checkArguments"]["canNotBeEmpty"]=array("procs");
992
		#$conf["canBeEmpty"],字串陣列,哪些必填參數的內容可為空字串或空陣列,僅當$conf["canBeEmptyString"]為"false"時會生效.
993
		#$conf["canBeEmpty"]=array();
994
		#$conf["skipableVariableCanNotBeEmpty"],字串陣列,哪些可省略參數不可以為空字串或空陣列.
995
		#$conf["variableCheck::checkArguments"]["skipableVariableCanNotBeEmpty"]=array("wait","workingDir","envs","executeBy");
996
		#$conf["skipableVariableName"],陣列字串,爲可省略參數的變數名稱陣列,形態爲陣列變數,例如: $conf["skipableVariableName"] = array("id","account","password");
997
		#$conf["variableCheck::checkArguments"]["skipableVariableName"]=array("wait","workingDir","envs","executeBy");
998
		#$conf["skipableVariableType"],陣列字串,爲可省略參數的變數名稱陣列,形態爲陣列變數,例如: $conf["skipableVariableType"] = array("string",integer,"double");
999
		#$conf["variableCheck::checkArguments"]["skipableVariableType"]=array("string","array","array","array");
1000
		#$conf["skipableVarDefaultValue"],字串陣列,每個不存在的可省略變數要初始化為什麼,null與代表不指定,若預設值是參數之一,請將$conf["mustBeFilledVar"]改成"\$conf["\mustBeFilledVar\"]".
1001
		#$conf["variableCheck::checkArguments"]["skipableVarDefaultValue"]=array("true",null,null,null);
1002
		#$conf["disallowAllSkipableVarIsEmpty"],字串,是否允許每個可省略參數都為空字串,預設為"true"允許,反之為"false".
1003
		#$conf["disallowAllSkipableVarIsEmpty"]="";
1004
		#$conf["disallowAllSkipableVarIsEmptyArray"],字串,是否允許每個可省略參數都為空陣列,預設為"true"允許,反之為"false".
1005
		#$conf["disallowAllSkipableVarIsEmptyArray"]="";
1006
		#$conf["disallowAllSkipableVarNotExist"],字串,是否不允許每個可省略參數都不存在,預設為"false"代表允許,反之為"true".
1007
		#$conf["disallowAllSkipableVarNotExist"]="";
1008
		#$conf["arrayCountEqualCheck"],字串陣列,為檢查哪些陣列參數的元素數量要一樣,$conf["arrayCountEqualCheck"][$i]=array()為第$i組key為哪些的變數其元素數量要相等.
1009
		#$conf["variableCheck::checkArguments"]["arrayCountEqualCheck"][]=array("");
1010
		#參考資料:
1011
		#array_keys=>http://php.net/manual/en/function.array-keys.php
1012
		#備註:
1013
		#無.
1014
		$checkArguments=variableCheck::checkArguments($conf["variableCheck::checkArguments"]);
1015
		unset($conf["variableCheck::checkArguments"]);
226 liveuser 1016
 
3 liveuser 1017
		#如果 $checkArguments["status"] 等於 "false"
1018
		if($checkArguments["status"]==="false"){
226 liveuser 1019
 
3 liveuser 1020
			#設置錯誤識別
1021
			$result["status"]="false";
226 liveuser 1022
 
3 liveuser 1023
			#設置錯誤訊息
1024
			$result["error"]=$checkArguments;
226 liveuser 1025
 
3 liveuser 1026
			#回傳結果
1027
			return $result;
226 liveuser 1028
 
3 liveuser 1029
			}#if end
226 liveuser 1030
 
3 liveuser 1031
		#如果 $checkArguments["passed"] 等於 "false"
1032
		if($checkArguments["passed"]==="false"){
226 liveuser 1033
 
3 liveuser 1034
			#設置錯誤識別
1035
			$result["status"]="false";
226 liveuser 1036
 
3 liveuser 1037
			#設置錯誤訊息
1038
			$result["error"]=$checkArguments;
226 liveuser 1039
 
3 liveuser 1040
			#回傳結果
1041
			return $result;
226 liveuser 1042
 
3 liveuser 1043
			}#if end
226 liveuser 1044
 
3 liveuser 1045
		#檢查 content
1046
		/*
1047
		#$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"代表程序的資訊.
1048
		*/
226 liveuser 1049
 
3 liveuser 1050
		#針對每個程序
1051
		foreach($conf["procs"] as $index => $proc){
226 liveuser 1052
 
3 liveuser 1053
			#函式說明:
1054
			#檢查必填與可省略的參數,可省略參數可指定預設要給與什麼數值內容.
1055
			#回傳結果:
1056
			#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
1057
			#$result["error"],執行不正常結束的錯訊息陣列.
1058
			#$result["simpleError"],簡單表示的錯誤訊息.
1059
			#$result["function"],當前執行的函式名稱.
1060
			#$result["argu"],設置給予的參數.
1061
			#$result["passed"],識別要檢查的全體變數是否存在以及型態是否正確的變數,"true"代表檢查全部通過;"false"代表檢查不通過
1062
			#$result[$shouldBeCheckedVarName]["varExist"],所檢查的變數是否存在,"false"代表不存在;"true"代表存在
1063
			#$result[$shouldBeCheckedVarName]["varType"],所檢查的變數型態是否正確,"false"代表錯誤;"true"代表正確
1064
			#$result[$shouldBeCheckedVarName]["error"],每個參數設定的錯誤訊息
1065
			#$result["shouldNotBeEmpty"],不應該為空字串或控陣列的變數.
1066
			#$result["argu"],字串陣列,目前輸入的參數名稱陣列.
1067
			#$result["legalVarName"],字串陣列,合法可用的參數名稱陣列.
1068
			#$result["notNeedVar"],字串陣列,多餘的參數名稱.
1069
			#必填參數:
1070
			#$conf["varInput"],陣列變數,要檢查的陣列變數,請在要檢查的參數前面加上&,這樣變動的結果才能被套用。
1071
			$conf["variableCheck::checkArguments"]["varInput"]=&$proc;
1072
			#$conf["referenceVarKey"],字串,$conf參數後面的key值,用於移除不要的參考陣列.
1073
			$conf["variableCheck::checkArguments"]["referenceVarKey"]="variableCheck::checkArguments";
1074
			#可省略參數:
1075
			#$conf["mustBeFilledVariableName"],爲必填參數的變數名稱陣列,形態爲陣列變數,元素數量需要跟"mustBeFilledVariableType"參數的元素數量一致,例如: $conf["mustBeFilledVariableName"] = array("id","account","password");
1076
			$conf["variableCheck::checkArguments"]["mustBeFilledVariableName"]=array("status","statusCode","content","error","input","process","proc_get_status");
1077
			#$conf["mustBeFilledVariableType"],爲必填參數的變數陣列應該爲何種變數形態,形態爲陣列,元素數量需要跟"mustBeFilledVariableName"參數的元素數量一致,例如: $conf["mustBeFilledVariableType"] = array("string",integer,"double","resource","object"); , null代表不指定變數形態.
1078
			$conf["variableCheck::checkArguments"]["mustBeFilledVariableType"]=array("string",null,null,null,"string","resource","array");
1079
			#$conf["canBeEmptyString"],字串,必填變數內容如果是空字串就不能算是有設置的話,請設為"false",預設爲"true",可以為空字串.
1080
			#$conf["variableCheck::checkArguments"]["canBeEmptyString"]="false";
1081
			#$conf["canNotBeEmpty"],字串陣列,哪些必填參數的內容不得為空字串或空陣列,僅當$conf["canBeEmptyString"]為"true"時會生效.
1082
			#$conf["variableCheck::checkArguments"]["canNotBeEmpty"]=array("procs");
1083
			#$conf["canBeEmpty"],字串陣列,哪些必填參數的內容可為空字串或空陣列,僅當$conf["canBeEmptyString"]為"false"時會生效.
1084
			#$conf["variableCheck::checkArguments"]["canBeEmpty"]=array();
1085
			#$conf["skipableVariableCanNotBeEmpty"],字串陣列,哪些可省略參數不可以為空字串或空陣列.
1086
			#$conf["variableCheck::checkArguments"]["skipableVariableCanNotBeEmpty"]=array("wait","workingDir","envs","executeBy");
1087
			#$conf["skipableVariableName"],陣列字串,爲可省略參數的變數名稱陣列,形態爲陣列變數,例如: $conf["skipableVariableName"] = array("id","account","password");
1088
			#$conf["variableCheck::checkArguments"]["skipableVariableName"]=array("error");
1089
			#$conf["skipableVariableType"],陣列字串,爲可省略參數的變數名稱陣列,形態爲陣列變數,例如: $conf["skipableVariableType"] = array("string",integer,"double");
1090
			#$conf["variableCheck::checkArguments"]["skipableVariableType"]=array("array");
1091
			#$conf["skipableVarDefaultValue"],字串陣列,每個不存在的可省略變數要初始化為什麼,null與代表不指定,若預設值是參數之一,請將$conf["mustBeFilledVar"]改成"\$conf["\mustBeFilledVar\"]".
1092
			#$conf["variableCheck::checkArguments"]["skipableVarDefaultValue"]=array("true",null,null,null);
1093
			#$conf["disallowAllSkipableVarIsEmpty"],字串,是否允許每個可省略參數都為空字串,預設為"true"允許,反之為"false".
1094
			#$conf["disallowAllSkipableVarIsEmpty"]="";
1095
			#$conf["disallowAllSkipableVarIsEmptyArray"],字串,是否允許每個可省略參數都為空陣列,預設為"true"允許,反之為"false".
1096
			#$conf["disallowAllSkipableVarIsEmptyArray"]="";
1097
			#$conf["disallowAllSkipableVarNotExist"],字串,是否不允許每個可省略參數都不存在,預設為"false"代表允許,反之為"true".
1098
			#$conf["disallowAllSkipableVarNotExist"]="";
1099
			#$conf["arrayCountEqualCheck"],字串陣列,為檢查哪些陣列參數的元素數量要一樣,$conf["arrayCountEqualCheck"][$i]=array()為第$i組key為哪些的變數其元素數量要相等.
1100
			#$conf["variableCheck::checkArguments"]["arrayCountEqualCheck"][]=array("");
1101
			#參考資料:
1102
			#array_keys=>http://php.net/manual/en/function.array-keys.php
1103
			#備註:
1104
			#無.
1105
			$checkArguments=variableCheck::checkArguments($conf["variableCheck::checkArguments"]);
1106
			unset($conf["variableCheck::checkArguments"]);
226 liveuser 1107
 
3 liveuser 1108
			#如果 $checkArguments["status"] 等於 "false"
1109
			if($checkArguments["status"]==="false"){
226 liveuser 1110
 
3 liveuser 1111
				#設置錯誤識別
1112
				$result["status"]="false";
226 liveuser 1113
 
3 liveuser 1114
				#設置錯誤訊息
1115
				$result["error"]=$checkArguments;
226 liveuser 1116
 
3 liveuser 1117
				#回傳結果
1118
				return $result;
226 liveuser 1119
 
3 liveuser 1120
				}#if end
226 liveuser 1121
 
3 liveuser 1122
			#如果 $checkArguments["passed"] 等於 "false"
1123
			if($checkArguments["passed"]==="false"){
226 liveuser 1124
 
3 liveuser 1125
				#設置錯誤識別
1126
				$result["status"]="false";
226 liveuser 1127
 
3 liveuser 1128
				#設置錯誤訊息
1129
				$result["error"]=$checkArguments;
226 liveuser 1130
 
3 liveuser 1131
				#回傳結果
1132
				return $result;
226 liveuser 1133
 
3 liveuser 1134
				}#if end
226 liveuser 1135
 
3 liveuser 1136
			#如果可能尚在執行中
1137
			if($proc["statusCode"]==="?"){
226 liveuser 1138
 
3 liveuser 1139
				#取得當下的狀態
1140
				$proc_get_status=proc_get_status($proc["process"]);
226 liveuser 1141
 
3 liveuser 1142
				#如果執行已經結束,有回傳exitcode
1143
				if($proc_get_status["exitcode"]!==-1){
226 liveuser 1144
 
3 liveuser 1145
					#設置 statusCode
1146
					$conf["procs"][$index]["statusCode"]=$proc_get_status["exitcode"];
226 liveuser 1147
 
3 liveuser 1148
					#取得標準輸出
1149
					$stdout=stream_get_contents($proc["content"]);
226 liveuser 1150
 
3 liveuser 1151
					#取得錯誤輸出
1152
					$stderr=stream_get_contents($proc["error"]);
226 liveuser 1153
 
3 liveuser 1154
					#設置執行失敗訊息
1155
					$conf["procs"][$index]["error"]=$stderr;
226 liveuser 1156
 
3 liveuser 1157
					#設置執行結果
1158
					$conf["procs"][$index]["content"]=$stdout;
226 liveuser 1159
 
3 liveuser 1160
					}#if end
226 liveuser 1161
 
3 liveuser 1162
				}#if end
249 liveuser 1163
 
1164
			#反之已經執行完畢
1165
			else{
1166
 
1167
				#如果標準輸出依然為 resource
1168
				if(gettype($proc["content"])==="resource"){
1169
 
1170
					#取得標準輸出
1171
					$stdout=stream_get_contents($proc["content"]);
226 liveuser 1172
 
249 liveuser 1173
					#設置執行結果
1174
					$conf["procs"][$index]["content"]=$stdout;
1175
 
1176
					}#if end
1177
 
1178
				#如果錯誤輸出依然為 resource
1179
				if(gettype($proc["error"])==="resource"){
1180
 
1181
					#取得錯誤輸出
1182
					$stderr=stream_get_contents($proc["error"]);
1183
 
1184
					#設置執行失敗訊息
1185
					$conf["procs"][$index]["error"]=$stderr;
1186
 
1187
					}#if end
1188
 
1189
				}#else end
1190
 
3 liveuser 1191
			}#foreach end
226 liveuser 1192
 
3 liveuser 1193
		#設置要回傳的結果
1194
		$result["content"]=$conf["procs"];
226 liveuser 1195
 
3 liveuser 1196
		#設置執行正常
1197
		$result["status"]="true";
226 liveuser 1198
 
3 liveuser 1199
		#回傳結果
1200
		return $result;
226 liveuser 1201
 
3 liveuser 1202
		}#function proc_update end
383 liveuser 1203
 
1204
	/*
1205
	#函式說明:
1206
	#類似stream_select的替代方案, 用來檢查透過proc運行的多執行序其標準輸出、錯誤輸出是否有訊息,程序是否已經結束.
1207
	#回傳結果:
1208
	#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
1209
	#$reuslt["error"],執行不正常結束的錯訊息陣列.
1210
	#$result["function"],當前執行的函式名稱.
1211
	#$result["argu"],使用的參數.
1212
	#$result["content"],陣列,每個元素的key代表有訊息的channel名稱,數值為陣列.
1213
	#$result["content"][$channel],陣列,$channel為通道的名稱亦即streams參數陣列中的key.陣列的key有"content",代表得到的訊息;"alive"則代表通道是否還處於開啟的狀態.
1214
	#$result["streams"],陣列,依然開啟的通道(運行中),元素的key為該channel的名稱;數值為channel.
1215
	#$result["allChannelClosed"],字串,"true"代表streams參數的通道已經全部關閉;反之為"false".
1216
	#必填參數:
1217
	#$conf["streams"],陣列,每個元素為threads::proc回傳結果content中每個元素的content跟error,key為該stream的名稱,例如:"client_1_std"、"client_1_err".
1218
	$conf["streams"]=array();
1219
	#可省略參數:
1220
	#$conf["periodToWait"],整數,要等待多少秒來嘗試取得訊息,預設為1秒鐘.
1221
	#$conf["periodToWait"]=1;
1222
	#參考資料:
1223
	#https://www.php.net/manual/en/function.proc-open.php
1224
	#https://www.php.net/manual/en/function.proc-get-status.php
1225
	#https://www.php.net/manual/en/function.proc-terminate.php
1226
	#備註:
1227
	#無.
1228
	*/
1229
	public static function proc_stream_select(&$conf){
1230
 
1231
		#初始化要回傳的結果
1232
		$result=array();
3 liveuser 1233
 
383 liveuser 1234
		#取得當前執行的函數名稱
1235
		$result["function"]=__FUNCTION__;
1236
 
1237
		#如果沒有參數
1238
		if(func_num_args()==0){
1239
 
1240
			#設置執行失敗
1241
			$result["status"]="false";
1242
 
1243
			#設置執行錯誤訊息
1244
			$result["error"]="函數".$result["function"]."需要參數";
1245
 
1246
			#回傳結果
1247
			return $result;
1248
 
1249
			}#if end
1250
 
1251
		#涵式說明:
1252
		#判斷當前環境為web還是cmd
1253
		#回傳結果:
1254
		#$result,"web"或"cmd"
1255
		if(csInformation::getEnv()==="web"){
1256
 
1257
			#設置執行失敗
1258
			$result["status"]="false";
1259
 
1260
			#設置執行錯誤訊息
1261
			$result["error"][]="函數 ".$result["function"]." 僅能在命令列環境下運行!";
1262
 
1263
			#回傳結果
1264
			return $result;
1265
 
1266
			}#if end
1267
 
1268
		#取得參數
1269
		$result["argu"]=$conf;
1270
 
1271
		#如果 $conf 不為陣列
1272
		if(gettype($conf)!=="array"){
1273
 
1274
			#設置執行失敗
1275
			$result["status"]="false";
1276
 
1277
			#設置執行錯誤訊息
1278
			$result["error"][]="\$conf變數須為陣列形態";
1279
 
1280
			#如果傳入的參數為 null
1281
			if(is_null($conf)){
1282
 
1283
				#設置執行錯誤訊息
1284
				$result["error"][]="\$conf變數不得為null,請檢查函數「".$result["function"]."」的參數設置有無正確!";
1285
 
1286
				}#if end
1287
 
1288
			#回傳結果
1289
			return $result;
1290
 
1291
			}#if end
1292
 
1293
		#函式說明:
1294
		#檢查必填與可省略的參數,可省略參數可指定預設要給與什麼數值內容.
1295
		#回傳結果:
1296
		#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
1297
		#$result["error"],執行不正常結束的錯訊息陣列.
1298
		#$result["simpleError"],簡單表示的錯誤訊息.
1299
		#$result["function"],當前執行的函式名稱.
1300
		#$result["argu"],設置給予的參數.
1301
		#$result["passed"],識別要檢查的全體變數是否存在以及型態是否正確的變數,"true"代表檢查全部通過;"false"代表檢查不通過
1302
		#$result[$shouldBeCheckedVarName]["varExist"],所檢查的變數是否存在,"false"代表不存在;"true"代表存在
1303
		#$result[$shouldBeCheckedVarName]["varType"],所檢查的變數型態是否正確,"false"代表錯誤;"true"代表正確
1304
		#$result[$shouldBeCheckedVarName]["error"],每個參數設定的錯誤訊息
1305
		#$result["shouldNotBeEmpty"],不應該為空字串或控陣列的變數.
1306
		#$result["argu"],字串陣列,目前輸入的參數名稱陣列.
1307
		#$result["legalVarName"],字串陣列,合法可用的參數名稱陣列.
1308
		#$result["notNeedVar"],字串陣列,多餘的參數名稱.
1309
		#必填參數:
1310
		#$conf["varInput"],陣列變數,要檢查的陣列變數,請在要檢查的參數前面加上&,這樣變動的結果才能被套用。
1311
		$conf["variableCheck::checkArguments"]["varInput"]=&$conf;
1312
		#$conf["referenceVarKey"],字串,$conf參數後面的key值,用於移除不要的參考陣列.
1313
		$conf["variableCheck::checkArguments"]["referenceVarKey"]="variableCheck::checkArguments";
1314
		#可省略參數:
1315
		#$conf["mustBeFilledVariableName"],爲必填參數的變數名稱陣列,形態爲陣列變數,元素數量需要跟"mustBeFilledVariableType"參數的元素數量一致,例如: $conf["mustBeFilledVariableName"] = array("id","account","password");
1316
		$conf["variableCheck::checkArguments"]["mustBeFilledVariableName"]=array("streams");
1317
		#$conf["mustBeFilledVariableType"],爲必填參數的變數陣列應該爲何種變數形態,形態爲陣列,元素數量需要跟"mustBeFilledVariableName"參數的元素數量一致,例如: $conf["mustBeFilledVariableType"] = array("string",integer,"double","resource","object"); , null、any代表不指定變數形態.其中 resource也包含"resource (closed)".
1318
		$conf["variableCheck::checkArguments"]["mustBeFilledVariableType"]=array("array");
1319
		#$conf["canBeEmptyString"],字串,必填變數內容如果是空字串就不能算是有設置的話,請設為"false",預設爲"true",可以為空字串.
1320
		#$conf["canBeEmptyString"]="false";
1321
		#$conf["canNotBeEmpty"],字串陣列,哪些必填參數的內容不得為空字串或空陣列,僅當$conf["canBeEmptyString"]為"true"時會生效.
1322
		#$conf["canNotBeEmpty"]=array();
1323
		#$conf["canBeEmpty"],字串陣列,哪些必填參數的內容可為空字串或空陣列,僅當$conf["canBeEmptyString"]為"false"時會生效.
1324
		#$conf["canBeEmpty"]=array();
1325
		#$conf["skipableVariableCanNotBeEmpty"],字串陣列,哪些可省略參數不可以為空字串或空陣列.
1326
		$conf["variableCheck::checkArguments"]["skipableVariableCanNotBeEmpty"]=array("periodToWait");
1327
		#$conf["skipableVariableName"],陣列字串,爲可省略參數的變數名稱陣列,形態爲陣列變數,例如: $conf["skipableVariableName"] = array("id","account","password");
1328
		$conf["variableCheck::checkArguments"]["skipableVariableName"]=array("periodToWait");
1329
		#$conf["skipableVariableType"],陣列字串,爲可省略參數的變數名稱陣列,形態爲陣列變數,例如: $conf["skipableVariableType"] = array("string",integer,"double");
1330
		$conf["variableCheck::checkArguments"]["skipableVariableType"]=array("integer");
1331
		#$conf["skipableVarDefaultValue"],字串陣列,每個不存在的可省略變數要初始化為什麼,null與代表不指定,若預設值是參數之一,請將$conf["mustBeFilledVar"]改成"\$conf["\mustBeFilledVar\"]".
1332
		$conf["variableCheck::checkArguments"]["skipableVarDefaultValue"]=array(1);
1333
		#$conf["disallowAllSkipableVarIsEmpty"],字串,是否允許每個可省略參數都為空字串,預設為"true"允許,反之為"false".
1334
		#$conf["disallowAllSkipableVarIsEmpty"]="";
1335
		#$conf["disallowAllSkipableVarIsEmptyArray"],字串,是否允許每個可省略參數都為空陣列,預設為"true"允許,反之為"false".
1336
		#$conf["disallowAllSkipableVarIsEmptyArray"]="";
1337
		#$conf["disallowAllSkipableVarNotExist"],字串,是否不允許每個可省略參數都不存在,預設為"false"代表允許,反之為"true".
1338
		#$conf["disallowAllSkipableVarNotExist"]="";
1339
		#$conf["arrayCountEqualCheck"],字串陣列,為檢查哪些陣列參數的元素數量要一樣,$conf["arrayCountEqualCheck"][$i]=array()為第$i組key為哪些的變數其元素數量要相等.
1340
		#$conf["arrayCountEqualCheck"][]=array();
1341
		#參考資料:
1342
		#array_keys=>http://php.net/manual/en/function.array-keys.php
1343
		#備註:
1344
		#無.
1345
		$checkArguments=variableCheck::checkArguments($conf["variableCheck::checkArguments"]);
1346
		unset($conf["variableCheck::checkArguments"]);
1347
 
1348
		#如果執行異常
1349
		if($checkArguments["status"]==="false"){
1350
 
1351
			#設置執行失敗
1352
			$result["status"]="false";
1353
 
1354
			#設置執行錯誤訊息
1355
			$result["error"]=$checkArguments;
1356
 
1357
			#回傳結果
1358
			return $result;
1359
 
1360
			}#if end
1361
 
1362
		#如果參數檢查不通過
1363
		if($checkArguments["passed"]==="false"){
1364
 
1365
			#設置執行失敗
1366
			$result["status"]="false";
1367
 
1368
			#設置執行錯誤訊息
1369
			$result["error"]=$checkArguments;
1370
 
1371
			#回傳結果
1372
			return $result;
1373
 
1374
			}#if end
1375
 
1376
		#初始化設置要監控的 stream 陣列資訊
1377
		$streamInfo=array();
1378
 
1379
		#針對每個 stream
1380
		foreach($conf["streams"] as $channelName => $stream){
1381
 
1382
			#設置 channel 的 stream
1383
			$streamInfo[$channelName]["stream"]=$stream;
1384
 
1385
			#預設 channel 視為開啟的狀況
1386
			$streamInfo[$channelName]["alive"]=true;
1387
 
1388
			#初始化該chnnel得到的回應為空.
1389
			$result["content"][$channelName]["content"]="";
1390
 
1391
			#初始化該chnnel為開啟的狀態
1392
			$result["content"][$channelName]["alive"]=true;
1393
 
1394
			}#foreach end
1395
 
1396
		#無窮迴圈
1397
		while(true){
1398
 
1399
			#針對每個 stream
1400
			foreach($streamInfo as $name=>$info){
1401
 
1402
				#如果通道是開啟的
1403
				if($info["alive"]){
1404
 
1405
					#確認是否尚未關閉
1406
					if(!feof($info["stream"])){
1407
 
1408
						#讀取訊息
1409
						$msg=fread($info["stream"],2048);
1410
 
1411
						#如果有訊息
1412
						if(!empty($msg)){
1413
 
1414
							#記錄訊息
1415
							$result["content"][$name]["content"]=$result["content"][$name]["content"].$msg.PHP_EOL;
1416
 
1417
							}#if end
1418
 
1419
						}#if end
1420
 
1421
					#反之
1422
					else{
1423
 
1424
						#設置通道已經關閉的識別
1425
						$streamInfo[$name]["alive"]=false;
1426
 
1427
						#初始化該chnnel為開啟的狀態
1428
						$result["content"][$channelName]["alive"]=false;
1429
 
1430
						#卸除作為參數的通道
1431
						unset($conf["streams"][$name]);
1432
 
1433
						}#else end
1434
 
1435
					}#if end
1436
 
1437
				}#foreach end
1438
 
1439
			#如果已經沒有要監控的通道存在
1440
			if(empty($conf["streams"])){
1441
 
1442
				#跳出 while
1443
				break;
1444
 
1445
				}#if end
1446
 
1447
			#如果等待時間已經結束
1448
			if(--$conf["periodToWait"]===0){
1449
 
1450
				#跳出 while
1451
				break;
1452
 
1453
				}#if end
1454
 
1455
			#休息1秒鐘
1456
			sleep(1);
1457
 
1458
			}#while end
1459
 
1460
		#針對每個 stream
1461
		foreach($result["content"] as $channelName => $stream){
1462
 
1463
			#如果輸出為空
1464
			if(empty($result["content"][$channelName]["content"])){
1465
 
1466
				#卸除之
1467
				unset($result["content"][$channelName]);
1468
 
1469
				}#if end
1470
 
1471
			}#foreach end
1472
 
1473
		#取得依然可以使用的通道
1474
		$result["streams"]=$conf["streams"];
1475
 
1476
		#如果可以使用的通道已經不存在
1477
		if(empty($result["streams"])){
1478
 
1479
			#設置所有 channel 已經關閉.
1480
			$result["allChannelClosed"]="true";
1481
 
1482
			}#if end
1483
 
1484
		#反之
1485
		else{
1486
 
1487
			#設置所有 channel 未關閉.
1488
			$result["allChannelClosed"]="false";
1489
 
1490
			}#else end
1491
 
1492
		#設置執行正常
1493
		$result["status"]="true";
1494
 
1495
		#回傳結果
1496
		return $result;
1497
 
1498
		}#function proc_stream_select end
1499
 
3 liveuser 1500
	/*
1501
	#函式說明:
1502
	#透過parallel展示多執行序運作.
1503
	#回傳結果:
1504
	#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
1505
	#$reuslt["error"],執行不正常結束的錯訊息陣列.
1506
	#$result["function"],當前執行的函式名稱.
1507
	#必填參數:
1508
	#無.
1509
	#可省略參數:
1510
	#無.
1511
	#參考資料:
1512
	#https://www.php.net/manual/en/class.parallel-runtime.php
1513
	#備註:
226 liveuser 1514
	#需要於編譯PHP時啟用該套件
3 liveuser 1515
	*/
1516
	public static function parallel_demo(){
226 liveuser 1517
 
3 liveuser 1518
		#初始化要回傳的結果
1519
		$result=array();
1520
 
1521
		#取得當前執行的函數名稱
1522
		$result["function"]=__FUNCTION__;
226 liveuser 1523
 
3 liveuser 1524
		#新增程序r1
1525
		$r1=new \parallel\Runtime();
226 liveuser 1526
 
3 liveuser 1527
		#r1要執行的函式
1528
		$thread_r1_function=function($conf){
226 liveuser 1529
 
3 liveuser 1530
			#提示開始
1531
			echo $conf["id"]." start".PHP_EOL;
226 liveuser 1532
 
3 liveuser 1533
			#跑 $conf["i"] 次
1534
			for($i=0;$i<$conf["i"];$i++){
226 liveuser 1535
 
3 liveuser 1536
				#題書$i數值
1537
				echo "\$i=".$i.PHP_EOL;
226 liveuser 1538
 
3 liveuser 1539
				}#for end
226 liveuser 1540
 
3 liveuser 1541
			#提示結束
1542
			echo $conf["id"]." end".PHP_EOL;
226 liveuser 1543
 
3 liveuser 1544
			};#function end
1545
 
1546
		#r1的參數
1547
		$args_r1=array();
1548
		$args_r1["id"]="r1";
1549
		$args_r1["i"]=10;
1550
 
1551
		#運行程序r1
1552
		#程序函式為 $thread_r1_function
1553
		#參數陣列為 $args_r1
1554
		$future_r1=$r1->run($thread_r1_function, $args_r1);
226 liveuser 1555
 
3 liveuser 1556
		#新增程序r2
1557
		$r2=new \parallel\Runtime();
226 liveuser 1558
 
3 liveuser 1559
		#r2要執行的函式
1560
		$thread_r2_function=function($conf){
226 liveuser 1561
 
3 liveuser 1562
			#提示開始
1563
			echo $conf["id"]." start".PHP_EOL;
226 liveuser 1564
 
3 liveuser 1565
			#跑 $conf["i"] 次
1566
			for($i=$conf["i"];$i>0;$i--){
226 liveuser 1567
 
3 liveuser 1568
				#題書$i數值
1569
				echo "\$i=".$i.PHP_EOL;
226 liveuser 1570
 
3 liveuser 1571
				}#for end
226 liveuser 1572
 
3 liveuser 1573
			#提示結束
1574
			echo $conf["id"]." end".PHP_EOL;
226 liveuser 1575
 
3 liveuser 1576
			};#function end
1577
 
1578
		#r2的參數
1579
		$args_r2=array();
1580
		$args_r2["id"]="r2";
1581
		$args_r2["i"]=10;
226 liveuser 1582
 
3 liveuser 1583
		#運行程序r2
1584
		#程序函式為 $thread__r2_function
1585
		#參數陣列為 $args_r2
1586
		$future_r2=$r2->run($thread_r2_function, $args_r2);
226 liveuser 1587
 
3 liveuser 1588
		#存放有多少在執行的程序
1589
		$futureArray=array();
1590
		$futureArray[]=$future_r1;
1591
		$futureArray[]=$future_r2;
226 liveuser 1592
 
3 liveuser 1593
		#當有程序尚未結束時
1594
		while(!empty($futureArray)){
226 liveuser 1595
 
3 liveuser 1596
			#針對每個 Future
1597
			foreach($futureArray as $index => $Future){
226 liveuser 1598
 
3 liveuser 1599
				#如果執行完成了
1600
				if($Future->done()){
226 liveuser 1601
 
3 liveuser 1602
					#移除之
1603
					unset($futureArray[$index]);
226 liveuser 1604
 
3 liveuser 1605
					}#if end
226 liveuser 1606
 
3 liveuser 1607
				}#foreach end
226 liveuser 1608
 
3 liveuser 1609
			}#while end
226 liveuser 1610
 
3 liveuser 1611
		#提示所有程序都執行結束了
1612
		echo "all done!".PHP_EOL;
226 liveuser 1613
 
3 liveuser 1614
		#設置執行正常
1615
		$result["status"]="true";
226 liveuser 1616
 
3 liveuser 1617
		#回傳結果
1618
		return $result;
226 liveuser 1619
 
3 liveuser 1620
		}#function parallel_demo end
226 liveuser 1621
 
3 liveuser 1622
	/*
1623
	#函式說明:
1624
	#透過 unix socket 來多執行序運作.
1625
	#回傳結果:
1626
	#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
1627
	#$reuslt["error"],執行不正常結束的錯訊息陣列.
1628
	#$result["function"],當前執行的函式名稱.
1629
	#$result["argu"],使用的參數.
1630
	#$result["content"],陣列,每個元素為cmds參數中個別元素其指令傳送後得到的uuid,可透過sock::getProcInfo來查詢結果.
1631
	#必填參數:
1632
	#$conf["cmds"],字串陣列,每個元素代表要執行的指令與參數.
1633
	#$conf["cmds"]=array();
1634
	#可省略參數:
1635
	#$conf["sock"],字串,要連線的 usr/bin/qbpwcf-sock.php 所產生的 unix domain socket 路徑與名稱,預設為 qbpwcf_usock_path.
1636
	#$conf["sock"]=qbpwcf_usock_path;
1637
	#參考資料:
1638
	#無
1639
	#備註:
1640
	#需要透過sock::unixDomainSockServer來運行.
1641
	*/
1642
	public static function socket(&$conf){
226 liveuser 1643
 
3 liveuser 1644
		#初始化要回傳的變數
1645
		$result=array();
1646
 
1647
		#初始化當前執行的函數名稱
1648
		$result["function"]=__FUNCTION__;
1649
 
1650
		#如果 $conf 不為陣列
1651
		if(gettype($conf)!="array"){
226 liveuser 1652
 
3 liveuser 1653
			#設置執行失敗
1654
			$result["status"]="false";
226 liveuser 1655
 
3 liveuser 1656
			#設置執行錯誤訊息
1657
			$result["error"][]="\$conf變數須為陣列形態";
1658
 
1659
			#如果傳入的參數為 null
1660
			if($conf==null){
226 liveuser 1661
 
3 liveuser 1662
				#設置執行錯誤訊息
1663
				$result["error"][]="\$conf變數不得為null,請檢查函數「".$result["function"]."」的參數設置有無正確!";
226 liveuser 1664
 
3 liveuser 1665
				}#if end
1666
 
1667
			#回傳結果
1668
			return $result;
226 liveuser 1669
 
3 liveuser 1670
			}#if end
226 liveuser 1671
 
3 liveuser 1672
		#取得使用的參數
1673
		$result["argu"]=$conf;
226 liveuser 1674
 
3 liveuser 1675
		#函式說明:
1676
		#檢查必填與可省略的參數,可省略參數可指定預設要給與什麼數值內容.
1677
		#回傳結果:
1678
		#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
1679
		#$result["error"],執行不正常結束的錯訊息陣列.
1680
		#$result["simpleError"],簡單表示的錯誤訊息.
1681
		#$result["function"],當前執行的函式名稱.
1682
		#$result["argu"],設置給予的參數.
1683
		#$result["passed"],識別要檢查的全體變數是否存在以及型態是否正確的變數,"true"代表檢查全部通過;"false"代表檢查不通過
1684
		#$result[$shouldBeCheckedVarName]["varExist"],所檢查的變數是否存在,"false"代表不存在;"true"代表存在
1685
		#$result[$shouldBeCheckedVarName]["varType"],所檢查的變數型態是否正確,"false"代表錯誤;"true"代表正確
1686
		#$result[$shouldBeCheckedVarName]["error"],每個參數設定的錯誤訊息
1687
		#$result["shouldNotBeEmpty"],不應該為空字串或控陣列的變數.
1688
		#$result["argu"],字串陣列,目前輸入的參數名稱陣列.
1689
		#$result["legalVarName"],字串陣列,合法可用的參數名稱陣列.
1690
		#$result["notNeedVar"],字串陣列,多餘的參數名稱.
1691
		#必填參數:
1692
		#$conf["varInput"],陣列變數,要檢查的陣列變數,請在要檢查的參數前面加上&,這樣變動的結果才能被套用。
1693
		$conf["variableCheck::checkArguments"]["varInput"]=&$conf;
1694
		#$conf["referenceVarKey"],字串,$conf參數後面的key值,用於移除不要的參考陣列.
1695
		$conf["variableCheck::checkArguments"]["referenceVarKey"]="variableCheck::checkArguments";
1696
		#可省略參數:
1697
		#$conf["mustBeFilledVariableName"],爲必填參數的變數名稱陣列,形態爲陣列變數,元素數量需要跟"mustBeFilledVariableType"參數的元素數量一致,例如: $conf["mustBeFilledVariableName"] = array("id","account","password");
1698
		$conf["variableCheck::checkArguments"]["mustBeFilledVariableName"]=array("cmds");
1699
		#$conf["mustBeFilledVariableType"],爲必填參數的變數陣列應該爲何種變數形態,形態爲陣列,元素數量需要跟"mustBeFilledVariableName"參數的元素數量一致,例如: $conf["mustBeFilledVariableType"] = array("string",integer,"double","resource","object"); , null代表不指定變數形態.
1700
		$conf["variableCheck::checkArguments"]["mustBeFilledVariableType"]=array("array");
1701
		#$conf["canBeEmptyString"],字串,必填變數內容如果是空字串就不能算是有設置的話,請設為"false",預設爲"true",可以為空字串.
1702
		$conf["variableCheck::checkArguments"]["canBeEmptyString"]="false";
1703
		#$conf["canNotBeEmpty"],字串陣列,哪些必填參數的內容不得為空字串或空陣列,僅當$conf["canBeEmptyString"]為"true"時會生效.
1704
		#$conf["canNotBeEmpty"]=array();
1705
		#$conf["canBeEmpty"],字串陣列,哪些必填參數的內容可為空字串或空陣列,僅當$conf["canBeEmptyString"]為"false"時會生效.
1706
		#$conf["canBeEmpty"]=array();
1707
		#$conf["skipableVariableCanNotBeEmpty"],字串陣列,哪些可省略參數不可以為空字串或空陣列.
1708
		$conf["variableCheck::checkArguments"]["skipableVariableCanNotBeEmpty"]=array("sock");
1709
		#$conf["skipableVariableName"],陣列字串,爲可省略參數的變數名稱陣列,形態爲陣列變數,例如: $conf["skipableVariableName"] = array("id","account","password");
1710
		$conf["variableCheck::checkArguments"]["skipableVariableName"]=array("sock");
1711
		#$conf["skipableVariableType"],陣列字串,爲可省略參數的變數名稱陣列,形態爲陣列變數,例如: $conf["skipableVariableType"] = array("string",integer,"double");
1712
		$conf["variableCheck::checkArguments"]["skipableVariableType"]=array("string");
1713
		#$conf["skipableVarDefaultValue"],字串陣列,每個不存在的可省略變數要初始化為什麼,null與代表不指定,若預設值是參數之一,請將$conf["mustBeFilledVar"]改成"\$conf["\mustBeFilledVar\"]".
1714
		$conf["variableCheck::checkArguments"]["skipableVarDefaultValue"]=array(null);
1715
		#$conf["disallowAllSkipableVarIsEmpty"],字串,是否允許每個可省略參數都為空字串,預設為"true"允許,反之為"false".
1716
		#$conf["disallowAllSkipableVarIsEmpty"]="";
1717
		#$conf["disallowAllSkipableVarIsEmptyArray"],字串,是否允許每個可省略參數都為空陣列,預設為"true"允許,反之為"false".
1718
		#$conf["disallowAllSkipableVarIsEmptyArray"]="";
1719
		#$conf["disallowAllSkipableVarNotExist"],字串,是否不允許每個可省略參數都不存在,預設為"false"代表允許,反之為"true".
1720
		#$conf["disallowAllSkipableVarNotExist"]="";
1721
		#$conf["arrayCountEqualCheck"],字串陣列,為檢查哪些陣列參數的元素數量要一樣,$conf["arrayCountEqualCheck"][$i]=array()為第$i組key為哪些的變數其元素數量要相等.
1722
		#$conf["variableCheck::checkArguments"]["arrayCountEqualCheck"][]=array("");
1723
		#參考資料:
1724
		#array_keys=>http://php.net/manual/en/function.array-keys.php
1725
		#備註:
1726
		#無.
1727
		$checkArguments=variableCheck::checkArguments($conf["variableCheck::checkArguments"]);
1728
		unset($conf["variableCheck::checkArguments"]);
226 liveuser 1729
 
3 liveuser 1730
		#如果 $checkArguments["status"] 等於 "false"
1731
		if($checkArguments["status"]==="false"){
226 liveuser 1732
 
3 liveuser 1733
			#設置錯誤識別
1734
			$result["status"]="false";
226 liveuser 1735
 
3 liveuser 1736
			#設置錯誤訊息
1737
			$result["error"]=$checkArguments;
226 liveuser 1738
 
3 liveuser 1739
			#回傳結果
1740
			return $result;
226 liveuser 1741
 
3 liveuser 1742
			}#if end
226 liveuser 1743
 
3 liveuser 1744
		#如果 $checkArguments["passed"] 等於 "false"
1745
		if($checkArguments["passed"]==="false"){
226 liveuser 1746
 
3 liveuser 1747
			#設置錯誤識別
1748
			$result["status"]="false";
226 liveuser 1749
 
3 liveuser 1750
			#設置錯誤訊息
1751
			$result["error"]=$checkArguments;
226 liveuser 1752
 
3 liveuser 1753
			#回傳結果
1754
			return $result;
226 liveuser 1755
 
3 liveuser 1756
			}#if end
226 liveuser 1757
 
3 liveuser 1758
		#針對每個指令
1759
		foreach($conf["cmds"] as $cmd){
226 liveuser 1760
 
3 liveuser 1761
			#連線到 usr/bin/qbpwcf-usock.php 產生的  unix domain socket,運行指定的指令.
1762
			#回傳結果:
1763
			#$result["status"],"true"代表執行正常;"false"代表執行不正常.
1764
			#$result["error"],錯誤訊息陣列.
1765
			#$result["function"],當前執行的函式名稱.
1766
			#$result["argu"],使用的參數.
1767
			#$result["content"],執行完指令的結果.
1768
			#必填參數:
1769
			#$conf["fileArgu"],字串,變數__FILE__的內容.
1770
			$conf["sock::execAnyCmdByQBPWCFunixSocket"]["fileArgu"]=__FILE__;
1771
			#$conf["command"],字串,要執行的指令名稱.
1772
			$conf["sock::execAnyCmdByQBPWCFunixSocket"]["command"]=$cmd;
1773
			#可省略參數:
226 liveuser 1774
 
3 liveuser 1775
			#如果有設置 sock 參數
1776
			if(isset($conf["sock"])){
226 liveuser 1777
 
3 liveuser 1778
				#$conf["sock"],字串,要連線的 usr/bin/qbpwcf-sock.php 所產生的 unix domain socket 路徑與名稱,預設為 qbpwcf_usock_path.
1779
				$conf["sock::execAnyCmdByQBPWCFunixSocket"]["sock"]=$conf["sock"];
226 liveuser 1780
 
3 liveuser 1781
				}#if end
226 liveuser 1782
 
3 liveuser 1783
			#$conf["argu"],陣列字串,指令搭配的參數,預設為空陣列.
1784
			#$conf["sock::execAnyCmdByQBPWCFunixSocket"]["argu"]=$conf["argu"];
1785
			#$conf["commandIncludeArgu"],字串,是否command含有參數,預設為"false"代表沒有;反之為"true".
1786
			$conf["sock::execAnyCmdByQBPWCFunixSocket"]["commandIncludeArgu"]="true";
1787
			#$conf["commandInBg"],字串,是否要將程序放在背景執行,再取得相關資訊,預設為"false"代表不要;反之為"true".
1788
			$conf["sock::execAnyCmdByQBPWCFunixSocket"]["commandInBg"]="true";
1789
			#參考資料:
1790
			#無.
1791
			#備註:
1792
			#無.
1793
			$execAnyCmdByQBPWCFunixSocket=sock::execAnyCmdByQBPWCFunixSocket($conf["sock::execAnyCmdByQBPWCFunixSocket"]);
1794
			unset($conf["sock::execAnyCmdByQBPWCFunixSocket"]);
226 liveuser 1795
 
3 liveuser 1796
			#如果執行失敗
1797
			if($execAnyCmdByQBPWCFunixSocket["status"]==="false"){
226 liveuser 1798
 
3 liveuser 1799
				#設置錯誤識別
1800
				$result["status"]="false";
226 liveuser 1801
 
3 liveuser 1802
				#設置錯誤訊息
1803
				$result["error"]=$execAnyCmdByQBPWCFunixSocket;
226 liveuser 1804
 
3 liveuser 1805
				#回傳結果
1806
				return $result;
226 liveuser 1807
 
3 liveuser 1808
				}#if end
226 liveuser 1809
 
3 liveuser 1810
			#debug
1811
			#var_dump(__LINE__,$execAnyCmdByQBPWCFunixSocket);
226 liveuser 1812
 
3 liveuser 1813
			#儲存收到的回應
1814
			$result["content"][]=$execAnyCmdByQBPWCFunixSocket["content"];
226 liveuser 1815
 
3 liveuser 1816
			}#foreach end
226 liveuser 1817
 
3 liveuser 1818
		#設置執行正常
1819
		$result["status"]="true";
226 liveuser 1820
 
3 liveuser 1821
		#回傳結果
1822
		return $result;
226 liveuser 1823
 
3 liveuser 1824
		}#function socket end
1825
 
226 liveuser 1826
	}#class threads end