Subversion Repositories php-qbpwcf

Rev

Rev 183 | Rev 226 | 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
	QBPWCF, Quick Build PHP website Component base on Fedora Linux.
5
    Copyright (C) 2015~2024 Min-Jhin,Chen
6
 
7
    This file is part of QBPWCF.
8
 
9
    QBPWCF is free software: you can redistribute it and/or modify
10
    it under the terms of the GNU General Public License as published by
11
    the Free Software Foundation, either version 3 of the License, or
12
    (at your option) any later version.
13
 
14
    QBPWCF is distributed in the hope that it will be useful,
15
    but WITHOUT ANY WARRANTY; without even the implied warranty of
16
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17
    GNU General Public License for more details.
18
 
19
    You should have received a copy of the GNU General Public License
20
    along with QBPWCF.  If not, see <http://www.gnu.org/licenses/>.
21
 
22
*/
23
namespace qbpwcf;
24
 
25
/*
26
類別說明:
27
跟socket應用相關的類別.
28
備註:
29
無.
30
*/
31
class sock{
32
 
33
	/*
34
	#函式說明:
35
	#當前類別被呼叫的靜態方法不存在時,將會執行該函數,回報該方法不存在.
36
	#回傳結果:
37
	#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
38
	#$reuslt["error"],執行不正常結束的錯訊息陣列.
39
	#$result["function"],當前執行的函式名稱.
40
	#必填參數:
41
	#$method,物件,為物件實體或類別名稱,會自動置入該參數.
42
	#$arguments,陣列,為呼叫方法時所用的參數.
43
	#可省略參數:
44
	#無.
45
	#參考資料:
46
	#__call=>http://php.net/manual/en/language.oop5.overloading.php#object.callstatic
47
	#備註:
48
	#無.
49
	*/
50
	public function __call($method,$arguments){
51
 
52
		#取得當前執行的函式
53
		$result["function"]=__FUNCTION__;
54
 
55
		#設置執行不正常
56
		$result["status"]="false";
57
 
58
		#設置執行錯誤
59
		$result["error"][]=__NAMESPACE__ ."/".$method."() 不存在!";
60
 
61
		#設置所丟入的參數
62
		$result["error"][]=$arguments;
63
 
64
		#回傳結果
65
		return $result;
66
 
67
		}#function __call end
68
 
69
	/*
70
	#函式說明:
71
	#當前類別被呼叫的靜態方法不存在時,將會執行該函數,回報該方法不存在.
72
	#回傳結果:
73
	#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
74
	#$reuslt["error"],執行不正常結束的錯訊息陣列.
75
	#$result["function"],當前執行的函式名稱.
76
	#必填參數:
77
	#$method,物件,為物件實體或類別名稱,會自動置入該參數.
78
	#$arguments,陣列,為呼叫方法時所用的參數.
79
	#可省略參數:
80
	#無.
81
	#參考資料:
82
	#__callStatic=>http://php.net/manual/en/language.oop5.overloading.php#object.callstatic
83
	#備註:
84
	#無.
85
	*/
86
	public static function __callStatic($method,$arguments){
87
 
88
		#取得當前執行的函式
89
		$result["function"]=__FUNCTION__;
90
 
91
		#設置執行不正常
92
		$result["status"]="false";
93
 
94
		#設置執行錯誤
95
		$result["error"][]="欲呼叫的". __NAMESPACE__ ."/".$method."() 不存在!";
96
 
97
		#設置所丟入的參數
98
		$result["error"][]=$arguments;
99
 
100
		#回傳結果
101
		return $result;
102
 
103
		}#function __callStatic end	
104
 
105
	/*
106
	#函式說明:
107
	#建立 unix domain socket server, 僅提供具備檔案存取權限的用戶使用,預設提供可以下達任何指令的功能.
108
	#回傳結果:
109
	#$result["status"],"true"代表執行正常;"false"代表執行不正常.
110
	#$result["error"],錯誤訊息陣列.
111
	#$result["function"],當前執行的函式名稱.
112
	#$result["serverCache"],函式結束前,儲存在serverCache的內容,若有元素"exit"存在則代表是正常結束.
113
	#$result["serverCache"]["serverSide"],server side 的 cache.
114
	#$result["serverCache"]["serverSide"]["procs"], server side 的 procs cache,儲存執行的子程序資訊.
115
	#$result["serverCache"]["clientSide"],client site 的 cache.
116
	#必填參數:
117
	#$conf["sock"],字串,socket檔案要放在哪邊,名稱為何.
118
	$conf["sock"]="";
119
	#$conf["fileArgu"],字串,變數__FILE__的內容.
120
	$conf["fileArgu"]=__FILE__;
121
	#可省略參數:
122
	#$conf["changeOwner"],字串,要將socket檔案的擁有着權限進行修改."user.group"代表擁有者帳號為user,群組為group.
123
	#$conf["changeOwner"]="";
124
	#$conf["changePermission"],字串,要將socket檔案的權限設為多少.ex: "0666"(所有帳戶都有存取的權限) 或 "0660"(僅有擁有者與群組帳戶有存取的權限) 或 "0600"(只有擁有者有權限執行).
125
	#$conf["changePermission"]="";
126
	#$conf["sessionTimeout"],字串,當連線結束後於下一次連線間隔多久就算session timeout,server端會將記錄移除,client端需要重新拿取id,預設為300秒.
127
	#$conf["sessionTimeout"]="300";
128
	#$conf["addOnProcessFunc"],字串陣列,增加用於處理 json request 的函式名稱,給予的參數為array("request"=>收到的json訊息,"sock"=>用戶的socket,"clientCache"=>給予所有用戶的cache),若收到的不是json而是"quit"則代表用戶要結束連線;若收到的是$shutdownStr則代表要結束本函式.回傳的內容必須為陣列,例如 $res["continue"]="true"代表要繼續執行下一個addOnProcessFunc;"false"代表代表到此為止. $res["content"]="replaced content";代表要將收到的訊息取代成"replaced content". 最少要有回傳 $res["status"]數值"true"代表執行正常;"false"代表執行不正常.
129
	#$conf["addOnProcessFunc"]=array();
130
	#$conf["funcToRunWhenIdle"],字串陣列,當沒有事件產生時,要執行的函式名稱,給予參數為array("client"=>所有用戶,"clientCache"=>$result["serverCache"]["clientSide"]["addOnProcessFunc"][$funcToRunWhenIdle],"serverCache"=>$result["serverCache"]["serverSide"]["funcToRunWhenIdle"][$funcToRunWhenIdle]).
131
	#$conf["funcToRunWhenIdle"]=array();
132
	#$conf["paramsForFuncToRunWhenIdle"],2維陣列,每個元素代表指定給予funcToRunWhenIdle參數中的指定元素的參數.
133
	#$conf["paramsForFuncToRunWhenIdle"]=array();
134
	#$conf["infoToFunction"],陣列,需要增加給addOnProcessFunc跟funcToRunWhenIdle函式的資訊,在函式中其參數的info鍵值.
135
	#$conf["infoToFunction"]=array("debug"=>$debug);
136
	#$conf["shutdownStrAddr"],字串,儲存收到用戶傳什麼樣的字串會結束本函式的檔案位置與名稱,預設為 $conf["sock"].".shutdown".
137
	#$conf["shutdownStrAddr"]="";
138
	#參考資料:
139
	#http://php.net/manual/en/function.stream-socket-server.php
140
	#備註:
141
	#無.
142
	*/
143
	public static function unixDomainSockServer(&$conf){
144
 
145
		#初始化要回傳的結果
146
		$result=array();
147
 
148
		#取得當前執行的函數名稱
149
		$result["function"]=__FUNCTION__;
150
 
151
		#如果沒有參數
152
		if(func_num_args()==0){
153
 
154
			#設置執行失敗
155
			$result["status"]="false";
156
 
157
			#設置執行錯誤訊息
158
			$result["error"]="函數".$result["function"]."需要參數";
159
 
160
			#回傳結果
161
			return $result;
162
 
163
			}#if end
164
 
165
		#涵式說明:
166
		#判斷當前環境為web還是cmd
167
		#回傳結果:
168
		#$result,"web"或"cmd"
169
		if(csInformation::getEnv()==="web"){
170
 
171
			#設置執行失敗
172
			$result["status"]="false";
173
 
174
			#設置執行錯誤訊息
175
			$result["error"][]="函數 ".$result["function"]." 僅能在命令列環境下運行!";
176
 
177
			#回傳結果
178
			return $result;
179
 
180
			}#if end
181
 
182
		#取得參數
183
		$result["argu"]=$conf;
184
 
185
		#如果 $conf 不為陣列
186
		if(gettype($conf)!="array"){
187
 
188
			#設置執行失敗
189
			$result["status"]="false";
190
 
191
			#設置執行錯誤訊息
192
			$result["error"][]="\$conf變數須為陣列形態";
193
 
194
			#如果傳入的參數為 null
195
			if($conf==null){
196
 
197
				#設置執行錯誤訊息
198
				$result["error"][]="\$conf變數不得為null,請檢查函數「".$result["function"]."」的參數設置有無正確!";
199
 
200
				}#if end
201
 
202
			#回傳結果
203
			return $result;
204
 
205
			}#if end
220 liveuser 206
 
3 liveuser 207
		#檢查參數
208
		#函式說明:
209
		#檢查必填與可省略的參數,可省略參數可指定預設要給與什麼數值內容。
210
		#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
211
		#$reuslt["error"],執行不正常結束的錯訊息陣列.
212
		#$result["function"],當前執行的函式名稱.
213
		#$result["argu"],設置給予的參數.
214
		#$result["passed"],識別要檢查的全體變數是否存在以及型態是否正確的變數,"true"代表檢查全部通過;"false"代表檢查不通過
215
		#$result[$shouldBeCheckedVarName]["varExist"],所檢查的變數是否存在,"false"代表不存在;"true"代表存在
216
		#$result[$shouldBeCheckedVarName]["varType"],所檢查的變數型態是否正確,"false"代表錯誤;"true"代表正確
217
		#$result[$shouldBeCheckedVarName]["error"],每個參數設定的錯誤訊息
218
		#$result["shouldNotBeEmpty"],不應該為空字串或控陣列的變數.
219
		#$result["argu"],字串陣列,目前輸入的參數名稱陣列.
220
		#$result["legalVarName"],字串陣列,合法可用的參數名稱陣列.
221
		#$result["notNeedVar"],字串陣列,多餘的參數名稱.
222
		#必填寫的參數:
223
		#$conf["varInput"],陣列變數,要檢查的陣列變數,請在要檢查的參數前面加上&,這樣變動的結果才能被套用。
224
		$conf["variableCheck::checkArguments"]["varInput"]=&$conf;	
225
		#$conf["referenceVarKey"],字串,$conf參數後面的key值,用於移除不要的參考陣列.
226
		$conf["variableCheck::checkArguments"]["referenceVarKey"]="variableCheck::checkArguments";
227
		#可以省略的參數:
228
		#$conf["mustBeFilledVariableName"],爲必填參數的變數名稱陣列,形態爲陣列變數,元素數量需要跟"mustBeFilledVariableType"參數的元素數量一致,例如: $conf["mustBeFilledVariableName"] = array("id","account","password");
229
		$conf["variableCheck::checkArguments"]["mustBeFilledVariableName"]=array("sock","fileArgu");
230
		#$conf["mustBeFilledVariableType"],爲必填參數的變數陣列應該爲何種變數形態,形態爲陣列,元素數量需要跟"mustBeFilledVariableName"參數的元素數量一致,例如: $conf["mustBeFilledVariableType"] = array("string",integer,"double","resource","object"); , null代表不指定變數形態.
231
		$conf["variableCheck::checkArguments"]["mustBeFilledVariableType"]=array("string","string");
232
		#$conf["canBeEmptyString"],字串,必填變數內容如果是空字串就不能算是有設置的話,請設為"false",預設爲"true",可以為空字串.
233
		#$conf["canBeEmptyString"]="false";
234
		#$conf["canNotBeEmpty"],字串陣列,哪些必填參數的內容不得為空字串或空陣列,僅當$conf["canBeEmptyString"]為"true"時會生效.
235
		#$conf["canNotBeEmpty"]=array();
236
		#$conf["canBeEmpty"],字串陣列,哪些必填參數的內容可為空字串或空陣列,僅當$conf["canBeEmptyString"]為"false"時會生效.
237
		#$conf["canBeEmpty"]=array();
238
		#$conf["skipableVariableCanNotBeEmpty"],字串陣列,哪些可省略參數不可以為空字串或空陣列.
239
		$conf["variableCheck::checkArguments"]["skipableVariableCanNotBeEmpty"]=array("changeOwner","changePermission","sessionTimeout","addOnProcessFunc","funcToRunWhenIdle","infoToFunction","shutdownStrAddr");
240
		#$conf["skipableVariableName"],陣列字串,爲可省略參數的變數名稱陣列,形態爲陣列變數,例如: $conf["skipableVariableName"] = array("id","account","password");
241
		$conf["variableCheck::checkArguments"]["skipableVariableName"]=array("changeOwner","changePermission","sessionTimeout","addOnProcessFunc","funcToRunWhenIdle","infoToFunction","paramsForFuncToRunWhenIdle","shutdownStrAddr");
242
		#$conf["skipableVariableType"],陣列字串,爲可省略參數的變數名稱陣列,形態爲陣列變數,例如: $conf["skipableVariableType"] = array("string",integer,"double"); 
243
		$conf["variableCheck::checkArguments"]["skipableVariableType"]=array("string","string","string","array","array","array","array","array");
244
		#$conf["skipableVarDefaultValue"],字串陣列,每個不存在的可省略變數要初始化為什麼,null與代表不指定,若預設值是參數之一,請將$conf["mustBeFilledVar"]改成"\$conf[\"mustBeFilledVar\"]".
77 liveuser 245
		$conf["variableCheck::checkArguments"]["skipableVarDefaultValue"]=array("root.".webUser,null,"300",null,null,null,array(),null);
3 liveuser 246
		#$conf["disallowAllSkipableVarIsEmpty"],字串,是否允許每個可省略參數都為空字串,預設為"true"允許,反之為"false".
247
		#$conf["disallowAllSkipableVarIsEmpty"]="";
248
		#$conf["disallowAllSkipableVarIsEmptyArray"],字串,是否允許每個可省略參數都為空陣列,預設為"true"允許,反之為"false".
249
		#$conf["disallowAllSkipableVarIsEmptyArray"]="";
250
		#$conf["arrayCountEqualCheck"],字串陣列,為檢查哪些陣列參數的元素數量要一樣,$conf["arrayCountEqualCheck"][$i]=array()為第$i組key為哪些的變數其元素數量要相等.
251
		#$conf["arrayCountEqualCheck"][]=array();
252
		#參考資料來源:
253
		#array_keys=>http://php.net/manual/en/function.array-keys.php
254
		$checkArguments=variableCheck::checkArguments($conf["variableCheck::checkArguments"]);
255
		unset($conf["variableCheck::checkArguments"]);
256
 
257
		#如果檢查參數失敗
258
		if($checkArguments["status"]==="false"){
259
 
260
			#設置執行失敗
261
			$result["status"]="false";
262
 
263
			#設置錯誤訊息
264
			$result["error"]=$checkArguments;
265
 
266
			#回傳結果
267
			return $result;
268
 
269
			}#if end
270
 
271
		#如果檢查參數不通過
272
		if($checkArguments["passed"]==="false"){
273
 
274
			#設置執行失敗
275
			$result["status"]="false";
276
 
277
			#設置錯誤訊息
278
			$result["error"]=$checkArguments;
279
 
280
			#回傳結果
281
			return $result;
282
 
283
			}#if end
284
 
285
		#縮減 socket 的路徑,避免出錯.
286
		#函式說明:
287
		#將檔案目錄的絕對位置中的 "../" 剔除變成直觀的路徑.
288
		#回傳結果:
289
		#$result["status"],執行是否成功,"true"代表執行成功,"false"代表執行失敗.
290
		#$result["function"],當前執行的函數.
291
		#$result["error"],錯誤訊息陣列.
292
		#$result["argu"],使用者參數.
293
		#$result["changedPath"],處理完後回傳的目錄字串.
294
		#$result["oriPath"],原始的路徑字串
295
		#必填參數:
296
		#$conf["dirStr"],字串,要處理的檔案目錄字串.
297
		$conf["stringProcess::changeDirByDotDotSolidus"]["dirStr"]=$conf["sock"];
298
		#可省略參數:
299
		#無.
300
		#參考資料:
301
		#無.
302
		#備註:
303
		#考慮用realpath取代
304
		$changeDirByDotDotSolidus=stringProcess::changeDirByDotDotSolidus($conf["stringProcess::changeDirByDotDotSolidus"]);
305
		unset($conf["stringProcess::changeDirByDotDotSolidus"]);
306
 
307
		#如果執行異常
308
		if($changeDirByDotDotSolidus["status"]==="false"){
309
 
310
			#設置執行失敗
311
			$result["status"]="false";
312
 
313
			#設置錯誤訊息
314
			$result["error"]=$changeDirByDotDotSolidus;
315
 
316
			#回傳結果
317
			return $result;
318
 
319
			}#if end
320
 
321
		#取得整理過後的直觀路徑
322
		$conf["sock"]=$changeDirByDotDotSolidus["changedPath"];
323
 
324
		#取得 socket 的路徑
325
		#函式說明:
326
		#將字串特定關鍵字與其後面的內容剔除
327
		#回傳結果:
328
		#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
329
		#$result["error"],錯誤訊息陣列.
330
		#$result["warning"],警告訊息鎮列.
331
		#$result["founded"],有無找到定字串"true"代表有,"false"代表沒有.
332
		#$result["function"],當前執行的函數名稱.
333
		#$result["oriStr"],要處理的原始字串內容.
334
		#$result["content"],處理好的的字串內容.
335
		#$result["argu"],使用的參數.
336
		#必填參數:
337
		#$conf["stringIn"],字串,要處理的字串.
338
		$conf["stringProcess::delStrAfterKeyWord"]["stringIn"]=$conf["sock"];
339
		#$conf["keyWord"],字串,特定字串.
340
		$conf["stringProcess::delStrAfterKeyWord"]["keyWord"]="/";
341
		#可省略參數:
342
		#$conf["deleteLastRepeatedOne"],字串,預設為"false";若為"true"則代表連續遇到同 $conf["keyWord"] 的內容,要將移除內容的起點往後移動到為後一個 $conf["keyWord"].
343
		$conf["stringProcess::delStrAfterKeyWord"]["deleteLastRepeatedOne"]="true";
344
		#參考資料:
345
		#無.
346
		#備註:
347
		#無.
348
		$delStrAfterKeyWord=stringProcess::delStrAfterKeyWord($conf["stringProcess::delStrAfterKeyWord"]);
349
		unset($conf["stringProcess::delStrAfterKeyWord"]);
350
 
351
		#如果執行失敗
352
		if($delStrAfterKeyWord["status"]==="false"){
353
 
354
			#設置執行失敗
355
			$result["status"]="false";
356
 
357
			#設置錯誤訊息
358
			$result["error"][]=$delStrAfterKeyWord;
359
 
360
			#設置錯誤訊息
361
			$result["error"][]="建立 unix domain socket(".$conf["sock"].") 失敗";
362
 
363
			#印出錯誤訊息
364
			echo print_r($result,true);
365
 
366
			#回傳結果
367
			return $result;
368
 
369
			}#if end
370
 
371
		#如果有 "/"
372
		if($delStrAfterKeyWord["founded"]==="true"){
373
 
374
			#確保建立socket的路徑有存在
375
			#函式說明:
376
			#確保路徑存在.
377
			#回傳結果:
378
			#$result["status"],執行正常與否,"true"代表正常,"false"代表不正常.
379
			#$result["error"],錯誤訊息陣列.
380
			#$resutl["function"],當前執行的涵式名稱.
381
			#$result["path"],建立好的路徑字串.
382
			#$result["fileName"],檔案名稱,若 $conf["haveFileName"] 為 "true" 則會回傳.
383
			#$result["argu"],使用的參數.
384
			#必填參數:
385
			#$conf["path"],要檢查的路徑
386
			$conf["fileAccess::validatePath"]["path"]=$delStrAfterKeyWord["content"];
387
			#$conf["fileArgu"],字串,php變數__FILE__的內容,亦即該檔案在檔案系統的絕對路徑
388
			$conf["fileAccess::validatePath"]["fileArgu"]=__FILE__;
389
			#可省略參數:
390
			#$conf["haveFileName"],字串,"true"代表有$conf["path"]檔案名稱,"false"代表$conf["path"]為純路徑,預設為"false".
391
			$conf["fileAccess::validatePath"]["haveFileName"]="false";
392
			#$conf["dirPermission"],字串,新建資料夾的權限設定,預設爲0770,亦即擁有者,同群組者可以讀,寫,存取,其他人僅能存取.
393
			#$conf["dirPermission"]="";
394
			#$conf["web"],是否為檔案系統,"true"為網頁路徑,"false"為網頁系統,預設為"false".
395
			$conf["fileAccess::validatePath"]["web"]="false";
396
			#參考資料:
397
			#無.
398
			#備註:
399
			#無.
400
			$validatePath=fileAccess::validatePath($conf["fileAccess::validatePath"]);
401
			unset($conf["fileAccess::validatePath"]);
402
 
403
			#如果執行失敗
404
			if($validatePath["status"]==="false"){
405
 
406
				#設置執行失敗
407
				$result["status"]="false";
408
 
409
				#設置錯誤訊息
410
				$result["error"][]=$validatePath;
411
 
412
				#設置錯誤訊息
413
				$result["error"][]="建立 unix domain socket(".$conf["sock"].") 失敗";
414
 
415
				#印出錯誤訊息
416
				echo print_r($result,true);
417
 
418
				#回傳結果
419
				return $result;
420
 
421
				}#if end
422
 
423
			}#if end
424
 
425
		#如果同名 unix domain socket file 存在
426
		if(file_exists($conf["sock"])){
427
 
428
			#則移除之.
429
			unlink($conf["sock"]);
430
 
431
			}#if end
432
 
433
		#預設的 unix socket addr
434
		$unixAddr="unix://".$conf["sock"];
435
 
436
		#建立 unix domain socket
437
		$socket=stream_socket_server($unixAddr, $errno, $errstr);
438
 
439
		#如果建立 unix domain socket 失敗
440
		if(!$socket){
441
 
442
			#設置執行失敗
443
			$result["status"]="false";
444
 
445
			#設置錯誤訊息
446
			$result["error"][]=$errstr." (".$errno.")";
447
 
448
			#設置錯誤訊息
449
			$result["error"][]="建立 unix domain socket(".$conf["sock"].") 失敗";
450
 
451
			#印出錯誤訊息
452
			echo print_r($result,true);
453
 
454
			#回傳結果
455
			return $result;
456
 
457
			}#if end
458
 
459
		#如果建立 unix domain socket 成功
460
		else{
461
 
462
			#產生用於代表結束本函式的字串
463
			#函式說明:
464
			#使用 linux 的 uuid 指令來產生 uuid 字串
465
			#回傳結果:
466
			#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
467
			#$result["error"],錯誤訊息.
468
			#$result["function"],當前執行的函式名稱.
469
			#$result["content"],uuid.
470
			#必填參數:
471
			#無.
472
			#可省略參數:
473
			#無.
474
			#參考資料:
475
			#無.
476
			#備註:
477
			#無.
478
			$uuid=cmd::uuid();
479
 
480
			#如果執行失敗
481
			if($uuid["status"]==="false"){
482
 
483
				#設置執行失敗
484
				$result["status"]="false";
485
 
486
				#設置錯誤訊息
487
				$result["error"]=$uuid;
488
 
489
				#回傳結果
490
				return $result;
491
 
492
				}#if end
493
 
494
			#設置代表結束本服務的uuid字串
495
			$shutdownStr=$uuid["content"];
496
 
497
			#如果沒有設置
498
			if(!isset($conf["shutdownStrAddr"])){
499
 
500
				#初始化存放 shutdownStr 的檔案
501
				$conf["shutdownStrAddr"]=$conf["sock"].".shutdownStr";
502
 
503
				}#if end
504
 
505
			#如果檔案位置名稱跟socket一樣
506
			else if($conf["sock"]===$conf["shutdownStrAddr"]){
507
 
508
				#設置執行失敗
509
				$result["status"]="false";
510
 
511
				#設置錯誤訊息
512
				$result["error"][]="參數shutdownStrAddr跟sock不可一樣";
513
 
514
				#設置錯誤訊息
515
				$result["error"][]=$checkArguments;
516
 
517
				#回傳結果
518
				return $result;
519
 
520
				}#else end
521
 
522
			#建立裡面儲存若要結束本程式需要接收到什麼樣的字串
523
			#函式說明:
524
			#將字串寫入到檔案
525
			#回傳結果:
526
			#$result["status"],"true"表示檔案寫入成功,"false"表示檔案寫入失敗.
527
			#$result["error"],錯誤訊息陣列.
528
			#$result["function"],當前執行的函數名稱.
529
			#$result["fileInfo"],實際上寫入的檔案資訊陣列.
530
			#$result["fileInfo"]["createdFileName"],建立好的檔案名稱.
531
			#$result["fileInfo"]["createdFilePath"],檔案建立的路徑.
532
			#$result["fileInfo"]["createdFilePathAndName"].建立好的檔案名稱與路徑.
533
			#$result["argu"],使用的參數.
534
			#必填參數:
535
			#$conf["fileArgu"],字串,php變數__FILE__的內容,亦即該檔案在檔案系統的絕對路徑
536
			$conf["fileAccess::writeTextIntoFile"]["fileArgu"]=$conf["fileArgu"];
537
			#可省略參數:
538
			#$conf["fileName"],字串,爲要編輯的檔案名稱,預設為隨機產生的檔案名稱.
539
			$conf["fileAccess::writeTextIntoFile"]["fileName"]=$conf["shutdownStrAddr"];
540
			#$conf["inputString"],字串,爲要寫入到裏面的內容,若要每筆資料寫入後換行,則可以在字串內容後面加上 \r\n 即可,預設為"".
541
			$conf["fileAccess::writeTextIntoFile"]["inputString"]=$shutdownStr;
542
			#$conf["writeMethod"],字串,爲檔案撰寫的方式,可省略,是複寫'a'還是,重新寫入'w',預設爲'w',重新寫入.
543
			#$conf["writeMethod"]="a";
544
			#$conf["checkRepeat"],字串,"true"代表建立檔案之前要先檢查檔案是否存在,若存在則在原名稱後面加上從(1)開始的編號.
545
			#$conf["checkRepeat"]="";
546
			#$conf["filenameExtensionStartPoint"],字串,檔案的副檔名是從倒數第幾個小數點(dot)開始,預設為"1",最後一個小數點,必須與$conf["checkRepeat"]搭配才會生效.
547
			#$conf["filenameExtensionStartPoint"]="";
548
			#$conf["repeatNameRule"],字串,遇到相同名稱的檔案要如何加上識別的編號,編號用「\$i」表示,預設為"(\$i)",必須與$conf["checkRepeat"]搭配才會生效.
549
			#$conf["repeatNameRule"]="";
550
			#$conf["web"],檔案是否位於網站上"true",若是在檔案系統則為"false",預設為"true".
551
			$conf["fileAccess::writeTextIntoFile"]["web"]="false";
552
			#參考資料:
553
			#無.
554
			#備註:
555
			#無.
556
			$writeTextIntoFile=fileAccess::writeTextIntoFile($conf["fileAccess::writeTextIntoFile"]);
557
			unset($conf["fileAccess::writeTextIntoFile"]);
558
 
559
			#如果執行失敗
560
			if($writeTextIntoFile["status"]==="false"){
561
 
562
				#設置執行失敗
563
				$result["status"]="false";
564
 
565
				#設置錯誤訊息
566
				$result["error"]=$writeTextIntoFile;
567
 
568
				#回傳結果
569
				return $result;
570
 
571
				}#if end
572
 
573
			#debug
574
			#var_dump(__LINE__,$writeTextIntoFile);exit;
575
 
576
			#初始化 client 陣列
577
			$client=array();
578
 
579
			#如果有設置$conf["changeOwner"]
580
			if(isset($conf["changeOwner"])){
581
 
582
				#如果裡面的"."不是一個
583
				if(substr_count($conf["changeOwner"],".")!==1){
584
 
585
					#設置執行失敗
586
					$result["status"]="false";
587
 
588
					#設置錯誤訊息
589
					$result["error"][]="參數 changeOwner 應為 username.groupname";
590
 
591
					#印出錯誤訊息
592
					echo print_r($result,true);
593
 
594
					#回傳結果
595
					return $result;
596
 
597
					}#if end
598
 
599
				#改變檔案的擁有者
600
				#函式說明:
601
				#使用 linux 的 chown 指令來修改目標檔案或目錄的擁有者跟群組擁有者資訊.
602
				#回傳結果:
603
				#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
604
				#$result["error"],錯誤訊息.
605
				#$result["function"],當前執行的函式名稱.
606
				#$result["cmd"],執行的指令.
607
				#$result["content"],執行的結果陣列,如果參數 "recursive" 跟 "excludeSelf" 都有設定的話,就會回傳該結果.
608
				#必填參數:
609
				#$conf["owner"],字串,要變哪個使用者擁有.
610
				$conf["cmd::chown"]["owner"]=explode(".",$conf["changeOwner"])[0];
611
				#$conf["target"],字串,需要變更擁有者、 群組的目標.
612
				$conf["cmd::chown"]["target"]=$conf["sock"];
613
				#可省略參數:
614
				#$conf["group"],字串,要變成什麼群組擁有,預設跟"owner"一樣.
615
				$conf["cmd::chown"]["group"]=explode(".",$conf["changeOwner"])[1];
616
				#$conf["recursive"],字串,"true"代表目標目錄底下的內容都要套用,預設為"false".
617
				#$conf["recursive"]="true";
618
				#$conf["excludeSelf"],字串,預設為"false"代表不處理;若為"true"則會排除目標自己(資料夾).
619
				#$conf["excludeSelf"]="true";
620
				#參考資料:
621
				#無.
622
				#備註:
623
				#無.
624
				$chown=cmd::chown($conf["cmd::chown"]);
625
				unset($conf["cmd::chown"]);
220 liveuser 626
 
3 liveuser 627
				#如果改變檔案擁有者限失敗
628
				if($chown===false){
220 liveuser 629
 
3 liveuser 630
					#設置執行失敗
631
					$result["status"]="false";
632
 
633
					#設置錯誤訊息
634
					$result["error"][]="改變 ".$conf["sock"]." 檔案的擁有資訊為 ".explode(".",$conf["changeOwner"])[0]." 失敗,通常只有系統帳戶才能變更之.";
635
 
636
					#印出錯誤訊息
637
					echo print_r($result,true);
638
 
639
					#回傳結果
640
					return $result;	
220 liveuser 641
 
3 liveuser 642
					}#if end
643
 
644
				}#if end
645
 
646
			#如果有設置 $conf["changePermission"]
647
			if(isset($conf["changePermission"])){
648
 
649
				#函式說明:
650
				#使用 linux 的 chmod 指令來修改目標檔案或目錄的權限.
651
				#回傳結果:
652
				#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
653
				#$result["error"],錯誤訊息.
654
				#$result["function"],當前執行的函式名稱.
655
				#$result["cmd"],執行的指令.
656
				#$result["content"],執行的結果陣列,如果參數 "recursive" 跟 "excludeSelf" 都有設定的話,就會回傳該結果.
657
				#必填參數:
658
				#$conf["mode"],字串,要變成什麼權限.
659
				$conf["cmd::chmod"]["mode"]=$conf["changePermission"];
660
				#$conf["target"],字串,需要變更權限的目標.
661
				$conf["cmd::chmod"]["target"]=$conf["sock"];
662
				#可省略參數:
663
				#$conf["recursive"],字串,"true"代表目標目錄底下的內容都要套用,預設為"false".
664
				#$conf["recursive"]="true";
665
				#$conf["excludeSelf"],字串,預設為"false"代表不處理;若為"true"則會排除目標自己(資料夾).
666
				#$conf["excludeSelf"]="true";
667
				#參考資料:
668
				#無.
669
				#備註:
670
				#無.
671
				$chmod=cmd::chmod($conf["cmd::chmod"]);
672
				unset($conf["cmd::chmod"]);
673
 
674
				#如果變更檔案權限失敗
675
				if($chmod["status"]==="false"){
676
 
677
					#設置執行失敗
678
					$result["status"]="false";
679
 
680
					#設置錯誤訊息
681
					$result["error"]=$chmod;
682
 
683
					#印出錯誤訊息
684
					echo print_r($result,true);
685
 
686
					#回傳結果
687
					return $result;	
688
 
689
					}#if end
690
 
691
				}#if end
692
 
693
			#初始化儲存 server 資訊的變數,預設數值為 $result 自己
694
			$result["serverCache"]=&$result;
695
 
696
			#初始化方便識別 server 資訊的變數
697
			$serverCache=&$result["serverCache"];
698
 
699
			#初始化 server site cache
700
			$serverCache["serverSide"]=array();
701
 
702
			#初始化 儲存 透過 proc 執行的子程序 
703
			$serverCache["serverSide"]["procs"]=array();
704
 
705
			#初始化 client site cache
706
			$serverCache["clientSide"]=array();
707
 
708
			#初始化方便識別 client site cache 資訊的變數
709
			$clientCache=&$serverCache["clientSide"];
710
 
711
			#將建立的 listen sock 放到 $master 陣列
712
			$master[] = $socket;
713
 
714
			#永久監聽, 不 timeout
715
			while(true){
716
 
717
				#debug
718
				#var_dump(__LINE__,gmdate("Y-m-d H:i:s",time()));
719
 
720
				#設置給 stream_select 監控的sock變數
721
				$read = $write = $except = $master;
722
 
723
				#等待5秒,看有沒有連線進來讀寫資料
724
				$mod_fd = stream_select($read, $write, $except, 5);
725
 
726
				#如果執行失敗
727
				if($mod_fd===FALSE){
728
 
729
					#提示錯誤訊息
730
					echo "Stream_select failed at ".gmdate("Y-m-d H:i:s",time());
731
 
732
					#結束監聽
733
					exit(1);
734
 
735
					}#if end
736
 
737
				#如果沒有訊息,代表閒置時可以做的事情
738
				else if($mod_fd===0){
739
 
740
					#提示idle
741
					echo ".";
742
 
743
					#清除 session timeout 的連線 - start
744
 
745
					#初始化要給 server 的回應
746
					$res=array();
747
 
748
					#初始化計數移除幾個用戶
749
					$res["delIdleConCount"]=0;
750
 
751
					#針對每個 $client
752
					foreach($client as $index=>$uncheckClient){
753
 
754
						#如果上次的要求時間為300秒前.
755
						if(time()-(int)$uncheckClient["last_req_time"]>$conf["sessionTimeout"]){
756
 
757
							#移除該用戶變數
758
							unset($client["$index"]);
759
 
760
							#計數移除了幾個用戶
761
							$res["delIdleConCount"]++;
762
 
763
							}#if end
764
 
765
						}#foreach end
766
 
767
					#設置執行正常
768
					$res["status"]="true";
769
 
770
					#如果有移除閒置的連線
771
					if($res["delIdleConCount"]>0){
772
 
773
						#印出給 server 的訊息
774
						echo PHP_EOL."response:".PHP_EOL.print_r($res,true);
775
 
776
						}#if end
777
 
778
					#清除 session timeout 的連線 - end
779
 
780
					#清除 太久沒有 被查詢的 proc(子程序) - start
781
 
782
					#初始化要給 server 的回應
783
					$res=array();
784
 
785
					#初始化計數移除幾個沒被關注的子程序
786
					$res["delIdleProcCount"]=0;
787
 
788
					#針對每個 子程序
789
					foreach($serverCache["serverSide"]["procs"] as $procIndex=>$procInfo){
790
 
791
						#debug
792
						#var_dump(__FUNCTION__,__LINE__,$procInfo);
793
 
794
						#如果上次的要求時間為300秒前.
795
						if(time()-(int)$procInfo["latestAccessTime"]>$conf["sessionTimeout"]){
796
 
797
							#若運行中
798
							if($procInfo["content"][0]["statusCode"]==="?"){
799
 
800
								#更新資訊
801
								#函式說明:
802
								#更新透過proc執行的多程序資訊.
803
								#回傳結果:
804
								#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
805
								#$reuslt["error"],執行不正常結束的錯訊息陣列.
806
								#$result["function"],當前執行的函式名稱.
807
								#$result["argu"],使用的參數.
808
								#$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"代表程序的資訊.
809
								#必填參數:
810
								#$conf["procs"],陣列,運行self::proc後回傳的content.
811
								$conf["threads::proc_update"]["procs"]=$procInfo["content"];
812
								#可省略參數:
813
								#無.
814
								#參考資料:
815
								#無.
816
								#備註:
817
								#無.
818
								$proc_update=threads::proc_update($conf["threads::proc_update"]);
819
								unset($conf["threads::proc_update"]);
820
 
821
								#若執行不正常
822
								if($proc_update["status"]==="false"){
823
 
824
									#設置執行失敗
825
									$result["status"]="false";
826
 
827
									#設置錯誤訊息
828
									$result["error"]=$proc_update;
829
 
830
									#印出錯誤訊息
831
									echo print_r($result,true);
832
 
833
									#回傳結果
834
									return $result;	
835
 
836
									}#if end
837
 
838
								#更新程序狀態
839
								$procInfo["content"]=$proc_update["content"][0];
840
 
841
								#更新會後存取時間
842
 
843
								#若已經執行結束
844
								if($procInfo["content"]["statusCode"]!=="?"){
845
 
846
									#換下一個
847
									continue;
848
 
849
									}#if end
850
 
851
								#執行到這代表一樣再運行中
57 liveuser 852
 
3 liveuser 853
								#終止程序
854
								proc_close($procInfo["content"]["process"]);
57 liveuser 855
 
3 liveuser 856
								#移除該用戶變數
857
								unset($serverCache["serverSide"]["procs"][$procIndex]);	
57 liveuser 858
 
3 liveuser 859
								#換下一個
860
								continue;
861
 
862
								}#if end
863
 
864
							#反之為已運行結束
865
 
866
							#移除該用戶變數
867
							unset($serverCache["serverSide"]["procs"][$procIndex]);
868
 
869
							#計數移除幾個沒被關注的子程序
870
							$res["delIdleProcCount"]++;
871
 
872
							}#if end
873
 
874
						}#foreach end
875
 
876
					#設置執行正常
877
					$res["status"]="true";
878
 
879
					#如果有移除沒被關注的子程序
880
					if($res["delIdleProcCount"]>0){
881
 
882
						#印出給 server 的訊息
883
						echo PHP_EOL."response:".PHP_EOL.print_r($res,true);
884
 
885
						}#if end
886
 
887
					#清除 太久沒有 被查詢的 proc(子程序) - end
888
 
889
					#如果有設置 idle 要執行的函式
890
					if(isset($conf["funcToRunWhenIdle"])){
891
 
892
						#提示有idle要執行的函式
893
						echo "response:".PHP_EOL."There is funcToRunWhenIdle param set.".PHP_EOL;
894
 
895
						#針對每個 funcToRunWhenIdle
896
						foreach($conf["funcToRunWhenIdle"] as $index => $funcToRunWhenIdle){
897
 
898
							#提示正要執行的函式
899
							echo "response:".PHP_EOL."Executeing ".$funcToRunWhenIdle."...".PHP_EOL;
900
 
901
							#初始化要給 funcToRunWhenIdle 函式的參數
902
							$parasmForFuncToRunWhenIdle=array();
903
 
904
							#取得所有用戶
905
							$parasmForFuncToRunWhenIdle["client"]=&$client;
906
 
907
							#如果有設置 infoToFunction
908
							if(isset($conf["infoToFunction"])){
909
 
910
								#設置info
911
								$parasmForFuncToRunWhenIdle["info"]=&$conf["infoToFunction"];
912
 
913
								}#if end
914
 
915
							#debug
916
							#var_dump(__FILE__,__LINE__,$serverCache["serverSide"]);
917
 
918
							#如果屬於該 $funcToRunWhenIdle 的 server side cache 不存在
919
							if(!isset($serverCache["serverSide"]["funcToRunWhenIdle"][$funcToRunWhenIdle])){
920
 
921
								#初始化為空陣列
922
								$serverCache["serverSide"]["funcToRunWhenIdle"][$funcToRunWhenIdle]=array();
923
 
924
								}#if end
925
 
926
							#設置給予 $funcToRunWhenIdle 函式的 serverCache 參數
927
							$parasmForFuncToRunWhenIdle["serverCache"]=&$serverCache;
928
 
929
							#儲存 $funcToRunWhenIdle 函式 的運行結束的時間點到 server side 的 cache
930
							$serverCache["serverSide"]["funcToRunWhenIdle"][$funcToRunWhenIdle]["lastRunTime"]=time::unix()["content"];
931
 
932
							#如果有要指定給 $funcToRunWhenIdle 的參數
933
							if(isset($conf["paramsForFuncToRunWhenIdle"][$index])){
934
 
935
								#針對每個 要給予 funcToRunWhenIdle 的參數
936
								foreach($conf["paramsForFuncToRunWhenIdle"][$index] as $arguKeyForFuncToRunWhenIdle => $arguValueForFuncToRunWhenIdle){
937
 
938
									#設置給予 funcToRunWhenIdle 的參數
939
									$parasmForFuncToRunWhenIdle[$arguKeyForFuncToRunWhenIdle]=$arguValueForFuncToRunWhenIdle;
940
 
941
									#debug
942
									#var_dump(__LINE__,$parasmForFuncToRunWhenIdle);
943
 
944
									}#foreach end
945
 
946
								}#if end
947
 
948
							/* debug
949
 
950
							#函式說明:
951
							#撰寫log
952
							#回傳結果:
953
							#$result["status"],狀態,"true"或"false".
954
							#$result["error"],錯誤訊息陣列.
955
							#$result["function"],當前函式的名稱.
956
							#$result["argu"],使用的參數.
957
							#$result["content"],要寫入log的內容字串.
958
							#必填參數:
959
							#$conf["path"],字串,log檔案的路徑與名稱.
960
							$conf["logs::record"]["path"]=$conf["sock"].".log";
961
							#$conf["content"],any,要寫的內容,若內容不為字串則會用var_dump的格式寫入.
962
							$conf["logs::record"]["content"]=$parasmForFuncToRunWhenIdle;
963
							#$conf["fileArgu"],字串,php變數__FILE__的內容,亦即該檔案在檔案系統的絕對路徑
964
							$conf["logs::record"]["fileArgu"]=__FILE__;
965
							#可省略參數:
966
							#$conf["rewrite"],預設為"false",接續寫入;反之"true"代表重新寫入.
967
							#$conf["rewrite"]="false";
968
							#$conf["returnOnly"],預設為"false",會寫入到log檔案.若為"true"則不會寫入log.
969
							#$conf["returnOnly"]="true";
970
							#參考資料:
971
							#無.
972
							#備註:
973
							#無.
974
							$record=logs::record($conf["logs::record"]);
975
							unset($conf["logs::record"]);
57 liveuser 976
 
3 liveuser 977
							#如果執行失敗
978
							if($record["status"]==="false"){
979
 
980
								#設置執行錯誤識別
981
								$result["status"]="false";
982
 
983
								#設置執行錯誤
984
								$result["error"]=$record;
985
 
986
								#回傳結果
987
								return $result;
988
 
989
								}#if end
990
 
991
							*/
992
 
993
							#debug
994
							#var_dump(__LINE__,$parasmForFuncToRunWhenIdle);
995
 
996
							#debug
997
							#var_dump(__LINE__,"\$call_user_func=".$funcToRunWhenIdle."(\$parasmForFuncToRunWhenIdle);");
998
 
999
							#呼叫 $funcToRunWhenIdle 函式,參數用 $client[$request->id], 取得執行後的回應.
1000
							eval("\$call_user_func=".$funcToRunWhenIdle."(\$parasmForFuncToRunWhenIdle);");
57 liveuser 1001
 
3 liveuser 1002
							/* debug
1003
 
1004
							#函式說明:
1005
							#撰寫log
1006
							#回傳結果:
1007
							#$result["status"],狀態,"true"或"false".
1008
							#$result["error"],錯誤訊息陣列.
1009
							#$result["function"],當前函式的名稱.
1010
							#$result["argu"],使用的參數.
1011
							#$result["content"],要寫入log的內容字串.
1012
							#必填參數:
1013
							#$conf["path"],字串,log檔案的路徑與名稱.
1014
							$conf["logs::record"]["path"]=$conf["sock"].".log";
1015
							#$conf["content"],any,要寫的內容,若內容不為字串則會用var_dump的格式寫入.
1016
							$conf["logs::record"]["content"]=$call_user_func;
1017
							#$conf["fileArgu"],字串,php變數__FILE__的內容,亦即該檔案在檔案系統的絕對路徑
1018
							$conf["logs::record"]["fileArgu"]=__FILE__;
1019
							#可省略參數:
1020
							#$conf["rewrite"],預設為"false",接續寫入;反之"true"代表重新寫入.
1021
							#$conf["rewrite"]="false";
1022
							#$conf["returnOnly"],預設為"false",會寫入到log檔案.若為"true"則不會寫入log.
1023
							#$conf["returnOnly"]="true";
1024
							#參考資料:
1025
							#無.
1026
							#備註:
1027
							#無.
1028
							$record=logs::record($conf["logs::record"]);
1029
							unset($conf["logs::record"]);
1030
 
1031
							#如果執行失敗
1032
							if($record["status"]==="false"){
1033
 
1034
								#設置執行錯誤識別
1035
								$result["status"]="false";
1036
 
1037
								#設置執行錯誤
1038
								$result["error"]=$record;
1039
 
1040
								#回傳結果
1041
								return $result;
1042
 
1043
								}#if end
1044
 
1045
							*/	
1046
 
1047
							#儲存 $funcToRunWhenIdle 函式 的運行結果資訊到 server side 的 cache
1048
							$serverCache["serverSide"]["funcToRunWhenIdle"][$funcToRunWhenIdle]["result"]=&$call_user_func;
1049
 
1050
							#儲存 $funcToRunWhenIdle 函式 的運行結束的時間點到 server side 的 cache
1051
							$serverCache["serverSide"]["funcToRunWhenIdle"][$funcToRunWhenIdle]["lastEndTime"]=time::unix()["content"];
1052
 
1053
							#debug
1054
							#var_dump(__FILE__,__LINE__,$serverCache);
1055
 
1056
							#如果 運行 $funcToRunWhenIdle 後回傳的內容含有 key 為 status 的元素
1057
							if(isset($call_user_func["status"])){
1058
 
1059
								#如果其數值為 "false"
1060
								if($call_user_func["status"]==="false"){
1061
 
1062
									#印出訊息,結束執行
1063
									var_dump(__FILE__,__LINE__,$call_user_func);exit;
1064
 
1065
									}#if end
1066
 
1067
								}#if end
1068
 
1069
							#如果有訊息要提示
1070
							if(isset($call_user_func["content"])){
1071
 
1072
								#印出提示訊息
1073
								var_dump($call_user_func["content"]);
1074
 
1075
								}#if end
1076
 
1077
							#如果 運行 $funcToRunWhenIdle 後回傳的內容含有 key 為 cache 的元素
1078
							if(isset($call_user_func["cache"])){
1079
 
1080
								#debug
1081
								#var_dump(__FILE__,__LINE__,$call_user_func["cache"]);
1082
 
1083
								#儲存到 server side 的 cache
1084
								$serverCache["serverSide"]["funcToRunWhenIdle"][$funcToRunWhenIdle]["cache"]=&$call_user_func["cache"];
1085
 
1086
								/*
1087
								#debug
1088
								#函式說明:
1089
								#撰寫log
1090
								#回傳結果:
1091
								#$result["status"],狀態,"true"或"false".
1092
								#$result["error"],錯誤訊息陣列.
1093
								#$result["function"],當前函式的名稱.
1094
								#$result["argu"],使用的參數.
1095
								#$result["content"],要寫入log的內容字串.
1096
								#必填參數:
1097
								#$conf["path"],字串,log檔案的路徑與名稱.
1098
								$conf["logs::record"]["path"]=$conf["sock"].".log";
1099
								#$conf["content"],any,要寫的內容,若內容不為字串則會用var_dump的格式寫入.
1100
								$conf["logs::record"]["content"]=$call_user_func;
1101
								#$conf["fileArgu"],字串,php變數__FILE__的內容,亦即該檔案在檔案系統的絕對路徑
1102
								$conf["logs::record"]["fileArgu"]=__FILE__;
1103
								#可省略參數:
1104
								#$conf["rewrite"],預設為"false",接續寫入;反之"true"代表重新寫入.
1105
								#$conf["rewrite"]="false";
1106
								#$conf["returnOnly"],預設為"false",會寫入到log檔案.若為"true"則不會寫入log.
1107
								#$conf["returnOnly"]="true";
1108
								#參考資料:
1109
								#無.
1110
								#備註:
1111
								#無.
1112
								$record=logs::record($conf["logs::record"]);
1113
								unset($conf["logs::record"]);
57 liveuser 1114
 
3 liveuser 1115
								#如果執行失敗
1116
								if($record["status"]==="false"){
1117
 
1118
									#設置執行錯誤識別
1119
									$result["status"]="false";
1120
 
1121
									#設置執行錯誤
1122
									$result["error"]=$record;
1123
 
1124
									#回傳結果
1125
									return $result;
1126
 
1127
									}#if end
1128
								*/
1129
 
1130
								}#if end
1131
 
1132
							#如果回傳結果含有 exit 元素
1133
							if(isset($call_user_func["exit"])){
1134
 
1135
								/*
1136
								#debug
1137
								#函式說明:
1138
								#撰寫log
1139
								#回傳結果:
1140
								#$result["status"],狀態,"true"或"false".
1141
								#$result["error"],錯誤訊息陣列.
1142
								#$result["function"],當前函式的名稱.
1143
								#$result["argu"],使用的參數.
1144
								#$result["content"],要寫入log的內容字串.
1145
								#必填參數:
1146
								#$conf["path"],字串,log檔案的路徑與名稱.
1147
								$conf["logs::record"]["path"]=$conf["sock"].".log";
1148
								#$conf["content"],any,要寫的內容,若內容不為字串則會用var_dump的格式寫入.
1149
								$conf["logs::record"]["content"]=$call_user_func["exit"];
1150
								#$conf["fileArgu"],字串,php變數__FILE__的內容,亦即該檔案在檔案系統的絕對路徑
1151
								$conf["logs::record"]["fileArgu"]=__FILE__;
1152
								#可省略參數:
1153
								#$conf["rewrite"],預設為"false",接續寫入;反之"true"代表重新寫入.
1154
								#$conf["rewrite"]="false";
1155
								#$conf["returnOnly"],預設為"false",會寫入到log檔案.若為"true"則不會寫入log.
1156
								#$conf["returnOnly"]="true";
1157
								#參考資料:
1158
								#無.
1159
								#備註:
1160
								#無.
1161
								$record=logs::record($conf["logs::record"]);
1162
								unset($conf["logs::record"]);
183 liveuser 1163
 
3 liveuser 1164
								#如果執行失敗
1165
								if($record["status"]==="false"){
1166
 
1167
									#設置執行錯誤識別
1168
									$result["status"]="false";
1169
 
1170
									#設置執行錯誤
1171
									$result["error"]=$record;
1172
 
1173
									#回傳結果
1174
									return $result;
1175
 
1176
									}#if end
1177
								*/
1178
 
1179
								#如果是要結束daemon執行
1180
								if($call_user_func["exit"]==="true"){
1181
 
1182
									#設置daemon結束的原因
1183
									$call_user_func["exit"]="exit by funcToRunWhenIdle(".$funcToRunWhenIdle.")";
1184
 
1185
									#設置執行正常
1186
									$result["status"]="true";
1187
 
1188
									#結束執行
1189
									return $result;
1190
 
1191
									}#if end
1192
 
1193
								}#if end
1194
 
1195
							#提示正要執行的函式
1196
							echo "response:".PHP_EOL.$funcToRunWhenIdle." Executed.".PHP_EOL;
1197
 
1198
							}#foreach end
1199
 
1200
						}#if end
1201
 
1202
					#等待下個要求
1203
					continue;
1204
 
1205
					}#if end
1206
 
1207
				#有偵測到讀寫的動作
1208
				else{
1209
 
1210
					#針對每個 sock 陣列
1211
					foreach($read as $readStream){
1212
 
1213
						#如果元素是 listen 的 socket
1214
						if($readStream === $socket){
1215
 
1216
							#當等待別人連線時,若有人連線進來.
1217
							$conn = stream_socket_accept($socket);
1218
 
1219
							#取得 meta data
1220
							#$stream_meta_data=stream_get_meta_data($conn);
220 liveuser 1221
 
3 liveuser 1222
							#debug
1223
							#var_dump(__LINE__,$stream_meta_data);
1224
 
1225
							#印出有連線進來的訊息
1226
							echo "received a connection".PHP_EOL;
1227
 
1228
							#初始化取得的內容
1229
							$request="";
1230
 
1231
							#初始化要回應的內容
1232
							$res=array();
1233
 
1234
							#取得 request 的時間
1235
							$last_req_time=time();
1236
 
1237
							#當有要求時
1238
							while(!feof($conn)){
1239
 
1240
								#讀取要求
1241
								$tmp=fgets($conn, 1024);
1242
 
1243
								#如果讀到 PHP_EOL
1244
								if($tmp===PHP_EOL){
1245
 
1246
									#結束讀取要求
1247
									break;	
1248
 
1249
									}#if end
183 liveuser 1250
 
3 liveuser 1251
								#串接回應
1252
								$request=$request.$tmp;
1253
 
183 liveuser 1254
								}#while end
1255
 
3 liveuser 1256
							#印出有連線進來的訊息
1257
							echo "received content:".PHP_EOL.$request.PHP_EOL;
1258
 
1259
							#parse request json
1260
							$request=json_decode($request);
1261
 
1262
							#如果 parse json 失敗
1263
							if($request===false){
1264
 
1265
								#設置錯誤訊息
1266
								$res["error"]="要求格式必須為json";
1267
 
1268
								#設置執行失敗
1269
								$res["status"]="false";
1270
 
1271
								#印出回的訊息
1272
								echo "res:".print_r($res,true);
1273
 
1274
								#寫入回應的內容
1275
								fwrite($conn,json_encode($res).PHP_EOL);
1276
 
1277
								#結束回應
1278
								fwrite($conn,PHP_EOL.PHP_EOL);
1279
 
1280
								#關閉socket連線,將回應輸出.
1281
								fclose($conn);
1282
 
1283
								#等待下個要求
1284
								continue;
1285
 
1286
								}#if end
1287
 
1288
							#若無ID資訊
1289
							if(!isset($request->id)){
1290
 
1291
								#無窮迴圈
1292
								while(true){
1293
 
1294
									#set client id 設置要回應的訊息
1295
									#函式說明:
1296
									#呼叫shell執行系統命令,並取得回傳的內容.
1297
									#回傳結果:
1298
									#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
1299
									#$result["error"],錯誤訊息陣列.
1300
									#$result["function"],當前執行的函數名稱.
1301
									#$result["argu"],使用的參數.
1302
									#$result["cmd"],執行的指令內容.
1303
									#$result["fullCmd"],如果參數 $conf["inBackGround"] 為 "true" 則會回傳該值.
1304
									#$result["output"],爲執行完二元碼後的輸出陣列,若 $conf["inBackGround"] 為 "true",則為當下的輸出.
1305
									#$result["tmpFileOutput"],儲存輸出的暫存檔案名稱,若 $conf["inBackGround"] 為 "true" 則會回傳該值.
1306
									#$result["running"],是否還在執行.
1307
									#$result["pid"],pid.
1308
									#$result["statusCode"],執行結束後的代碼.
1309
									#必填參數:
1310
									#$conf["command"],字串,要執行的指令.
1311
									$conf["external::callShell"]["command"]="uuid";
1312
									#$conf["fileArgu"],字串,變數__FILE__的內容.
1313
									$conf["external::callShell"]["fileArgu"]=__FILE__;
1314
									#可省略參數:
1315
									#$conf["argu"],陣列字串,指令搭配的參數,預設為空陣列.
1316
									#$conf["argu"]=array("");
1317
									#$conf["arguIsAddr"],陣列字串,指令搭配的哪些參數為路徑,為路徑的參數會進行轉換以便符合呼叫當前函數的位置,預設不指定,若有3個參數,其中第3個參數為路徑,則表示為array("false","false","true").
1318
									#$conf["arguIsAddr"]=array();
1319
									#$conf["plainArgu"],字串陣列,哪幾個參數不要加上"",若為"true"則代表不用包;反之"false"則代表要包.
1320
									#$conf["plainArgu"]=array();
1321
									#$conf["useApostrophe"],字串陣列,如果有需要包住,則用「'」,而非「"」處理.前者為"true";後者為"false".
1322
									#$conf["useApostrophe"]=array();
1323
									#$conf["pre"],陣列,要在本指令前執行的每個指令與參數.
1324
									#$conf["pre"][$i]["cmd"],字串,要在本指令前執行的第$i+1個指令.
1325
									#$conf["pre"][$i]["param"],陣列字串,要在本指令前執行的第$i+1個指令的參數.
1326
									#$conf["enablePrintDescription"],字串,是否要印出$conf["printDescription"]的內容,"true"代表要,"false"代表不要,預設為"false".
1327
									#$conf["enablePrintDescription"]="true";
1328
									#$conf["printDescription"],字串,執行該外部程式前要印出來的的文字,預設為$conf["command"]的內容加上使用的$conf["argu"]參數.
1329
									#$conf["printDescription"]="";
1330
									#$conf["escapeshellarg"],字串,是否要啟用過濾參數,用了比較安全,但可能會出錯,"true"為啟用,"false"為不啟用,預設為"false".如果參數為"< 、<< 、> 、>> 、| 、2>&1"之一則不會過濾.
1331
									$conf["external::callShell"]["escapeshellarg"]="true";
1332
									#$conf["thereIsShellVar"],陣列字串,指令搭配的參數"argu",若含有「\'」,則取代為「"」.每個argu參數都要有對應的元素."true"代表要置換.
1333
									#$conf["thereIsShellVar"]=array();
1334
									#$conf["username"],字串,要用什麼使用者來執行,預設為執行php的使用者,該參數不適用於apache環境.
1335
									#$conf["username"]="";
1336
									#$conf["password"],字串,root的使用者密碼,預設不使用密碼,該參數不適用於apache環境.
1337
									#$conf["password"]="";
1338
									#$conf["useScript"],字串,是否要啟用Linux的script指令來記錄輸出,"true"代表要,Fedora的selinux會擋住該操作;"false"代表不要,預設為"false".
1339
									#$conf["useScript"]="";
1340
									#$conf["logFilePath"],字串,當 $conf["useScript"] 為 "true" 時,輸出的內容要暫存到哪裡,預設為 "/tmp/.qbpwcf_tmp/external/callShell/".
1341
									#$conf["logFilePath"]=".qbpwcf_tmp/external/callShell/";
1342
									#$conf["inBackGround"],字串,是否要在背景執行,且不會等待程式執行結束再執行下一個指令,"true"代表是,"false"代表不要,預設為"false",如果$conf["command"]有用「;」區隔的多個指令將會出錯.
1343
									#$conf["inBackGround"]="";
1344
									#$conf["getErr"],字串,"true"代表將錯誤輸出變成標準輸出,反之"false"為不變動.
1345
									#$conf["getErr"]="false";
1346
									#$conf["doNotRun"],字串,"true"代表不執行指令,預設為"false"會執行指令.
1347
									#$conf["doNotRun"]="false";
1348
									#參考資料:
1349
									#exec=>http://php.net/manual/en/function.exec.php
1350
									#escapeshellcmd=>http://php.net/manual/en/function.escapeshellcmd.php
1351
									#escapeshellarg=>http://php.net/manual/en/function.escapeshellarg.php
1352
									#備註:
1353
									#不是所有指令都能用apache的身份執行,目前已知java,javac指令無法執行,使用root身份可能會被selinux阻擋.
1354
									#若使用的 command、argu 參數,含有 ~ 則會被視為字串,若有需要其於 shell 中代表的家目錄位置,可用 fileAccess::tildeToPath 來進行轉換.
1355
									$callShell=external::callShell($conf["external::callShell"]);
1356
									unset($conf["external::callShell"]);
1357
 
1358
									#如果執行失敗
1359
									if($callShell["status"]==="false"){
1360
 
1361
										#設置執行失敗
1362
										$result["status"]="false";
1363
 
1364
										#設置錯誤訊息
1365
										$result["error"]=$callShell;
1366
 
1367
										#回傳結果
1368
										return $result;	
1369
 
1370
										}#if end
1371
 
1372
									#如果沒有預期的 uuid 回應
1373
									if(!isset($callShell["output"][0])){
1374
 
1375
										#設置執行失敗
1376
										$result["status"]="false";
1377
 
1378
										#設置錯誤訊息
1379
										$result["error"][]="get uuid failed!";
1380
 
1381
										#設置錯誤訊息
1382
										$result["error"][]=$callShell;
1383
 
1384
										#回傳結果
1385
										return $result;	
1386
 
1387
										}#if end
1388
 
1389
									#檢查 client id 是否已經存在
1390
									if(isset($client[$callShell["output"][0]])){
1391
 
1392
										#休息一微秒
1393
										usleep(1);
1394
 
1395
										#再次建立id試試
1396
										continue;
1397
 
1398
										}#if end
1399
 
1400
									#設置回應的id
1401
									$res["id"]=$callShell["output"][0];
1402
 
1403
									#建立id完畢
1404
									break;
1405
 
1406
									}#while end
1407
 
1408
								#儲存使用者id與最後一次來request的時間
1409
								$client[$res["id"]]=array("last_req_time"=>$last_req_time);
1410
 
1411
								#印出用戶端列表
1412
								echo "clients:".print_r($client,true);
1413
 
1414
								#設置執行正常
1415
								$res["status"]="true";
1416
 
1417
								#印出回的訊息
1418
								echo "response:".PHP_EOL.print_r($res,true);
1419
 
1420
								#寫入回應的內容
1421
								fwrite($conn,json_encode($res).PHP_EOL);
1422
 
1423
								#結束回應
1424
								fwrite($conn,PHP_EOL.PHP_EOL);
1425
 
1426
								#關閉socket連線,將回應輸出.
1427
								fclose($conn);
1428
 
1429
								#等待下個要求
1430
								continue;
1431
 
57 liveuser 1432
								}#if end
3 liveuser 1433
 
1434
							#若ID資訊不存在
1435
							if(!isset($client[$request->id])){
1436
 
1437
								#設置執行失敗
1438
								$res["status"]="false";
1439
 
1440
								#設置ID不存在的訊息
1441
								$res["error"]="ID:".$request->id." 不存在,請再要一次ID.";
1442
 
1443
								#印出回的訊息
1444
								echo "response:".PHP_EOL.print_r($res,true);
1445
 
1446
								#寫入回應的內容
1447
								fwrite($conn,json_encode($res).PHP_EOL);
1448
 
1449
								#結束回應
1450
								fwrite($conn,PHP_EOL.PHP_EOL);
1451
 
1452
								#關閉socket連線,將回應輸出.
1453
								fclose($conn);
1454
 
1455
								#等待下個要求
1456
								continue;
1457
 
1458
								}#if end
1459
 
1460
							#如果有客製化訊息
1461
							if(isset($request->custom)){
1462
 
1463
								#取代之
1464
								$request=$request->custom;
1465
 
1466
								}#if end
1467
 
1468
							#若有要執行的指令 cmd,且非客製化.
183 liveuser 1469
							if(isset($request->cmd)){
3 liveuser 1470
 
1471
								#如果是要結束連線
1472
								if($request->cmd==="quit"){
1473
 
1474
									#設置執行正常
1475
									$res["status"]="true";
1476
 
1477
									#設置訊息
1478
									$res["content"]="將關閉與您的連線";
1479
 
1480
									#寫入回應的內容
1481
									fwrite($conn,json_encode($res).PHP_EOL);
1482
 
1483
									#結束回應
1484
									fwrite($conn,PHP_EOL.PHP_EOL);
1485
 
1486
									#關閉socket連線,將回應輸出.
1487
									fclose($conn);
1488
 
1489
									#移除該用戶變數
1490
									unset($client[$index]);
183 liveuser 1491
 
3 liveuser 1492
									#計數移除了幾個用戶
1493
									$res["delCount"]++;
1494
 
1495
									#設置執行正常
1496
									$res["status"]="true";
1497
 
1498
									#印出回的訊息
1499
									echo "response:".PHP_EOL.print_r($res,true);
1500
 
1501
									#等待下個要求
1502
									continue;
1503
 
1504
									}#if end
1505
 
1506
								#如果是要結束server
1507
								if($request->cmd===$shutdownStr){
1508
 
1509
									#設置執行正常
1510
									$res["status"]="true";
1511
 
1512
									#設置訊息
1513
									$res["content"]="本服務將結束";
1514
 
1515
									#寫入回應的內容
1516
									fwrite($conn,json_encode($res).PHP_EOL);
1517
 
1518
									#結束回應
1519
									fwrite($conn,PHP_EOL.PHP_EOL);
1520
 
1521
									#關閉socket連線,將回應輸出.
1522
									fclose($conn);
1523
 
1524
									#設置執行正常
1525
									$result["status"]="true";
1526
 
1527
									#結束本程式
1528
									return $result;
1529
 
1530
									}#if end
1531
 
1532
								#涵式說明:
1533
								#呼叫shell執行系統命令,並取得回傳的內容.
1534
								#回傳的結果:
1535
								#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
1536
								#$result["error"],錯誤訊息陣列.
1537
								#$result["function"],當前執行的函數名稱.
1538
								#$result["argu"],使用的參數.
1539
								#$result["cmd"],執行的指令內容.
1540
								#$result["fullCmd"],如果參數 $conf["inBackGround"] 為 "true" 則會回傳該值.
1541
								#$result["output"],爲執行完二元碼後的輸出陣列,若 $conf["inBackGround"] 為 "true",則為當下的輸出.
1542
								#$result["tmpFileOutput"],儲存輸出的暫村檔案名稱,若 $conf["inBackGround"] 為 "true" 則會回傳該值.
1543
								#$result["running"],是否還在執行.
1544
								#$result["pid"],pid
1545
								#必填的參數
1546
								#$conf["command"],字串,要執行的指令與.
1547
								$conf["external::callShell"]["command"]=$request->cmd;
1548
								#$conf["fileArgu"],字串,變數__FILE__的內容.
57 liveuser 1549
								$conf["external::callShell"]["fileArgu"]=$conf["fileArgu"];
3 liveuser 1550
								#可省略參數:
1551
 
1552
								#如果有指定參數
1553
								if(isset($request->param)){
1554
 
1555
									#$conf["argu"],陣列字串,指令搭配的參數,預設為空陣列.
1556
									$conf["external::callShell"]["argu"]=$request->param;
1557
 
1558
									}#if end
1559
 
1560
								#$conf["arguIsAddr"],陣列字串,指令搭配的哪些參數為路徑,為路徑的參數會進行轉換以便符合呼叫當前函數的位置,預設不指定,若有3個參數,其中第3個參數為路徑,則表示為array("false","false","true").
1561
								#$conf["arguIsAddr"]=array();	
1562
								#$conf["pre"],陣列,要在本指令前執行的每個指令與參數.
1563
								#$conf["pre"][$i]["cmd"],字串,要在本指令前執行的第$i+1個指令.
1564
								#$conf["pre"][$i]["param"],陣列字串,要在本指令前執行的第$i+1個指令的參數.
1565
								#$conf["enablePrintDescription"],字串,是否要印出$conf["printDescription"]的內容,"true"代表要,"false"代表不要,預設為"false".
1566
								#$conf["enablePrintDescription"]="true";
1567
								#$conf["printDescription"],字串,執行該外部程式前要印出來的的文字,預設為$conf["command"]的內容.
1568
								#$conf["printDescription"]="";
1569
 
1570
								#如果有參數
1571
								if(isset($request->param)){
1572
 
1573
									#如果有識別是否已經 escaped 參數
1574
									if(isset($request->escaped)){
1575
 
1576
										#設置預設要 escape
1577
										$needEscaped="true";
1578
 
1579
										#如果已經 ecaped
1580
										if($request->escaped){
1581
 
1582
											#設置不用 escape
1583
											$needEscaped="false";
1584
 
1585
											}#if end
1586
 
1587
										#$conf["escapeshellarg"],字串,是否要啟用過濾參數,用了比較安全,但可能會出錯,"true"為啟用,"false"為不啟用,預設為"false".
1588
										$conf["external::callShell"]["escapeshellarg"]=$needEscaped;
1589
 
1590
										}#if end
1591
 
1592
									}#if end
1593
 
1594
								#如果有設置要用特定的使用者身份執行
1595
								if(isset($request->user) && isset($request->password)){
1596
 
1597
									#$conf["username"],字串,要用什麼使用者來執行,預設為執行php的使用者,該參數不適用於apache環境.
1598
									$conf["external::callShell"]["username"]=$request->user;
1599
 
1600
									#$conf["password"],字串,與$conf["username"]搭配的使用者密碼,預設不使用密碼,該參數不適用於apache環境.
1601
									$conf["external::callShell"]["password"]=$request->password;
1602
 
1603
									}#if end
1604
 
1605
								#$conf["useScript"],字串,是否要啟用Linux的script指令來記錄輸出,"true"代表要,Fedora的selinux會擋住該操作;"false"代表不要,預設為"false".
1606
								#$conf["useScript"]="";
1607
								#$conf["logFilePath"],字串,當 $conf["useScript"] 為 "true" 時,輸出的內容要暫存到哪裡,預設為 "/tmp/.qbpwcf_tmp/external/callShell/".
1608
								#$conf["logFilePath"]=".qbpwcf_tmp/external/callShell/";
1609
								#$conf["inBackGround"],字串,是否要在背景執行,且不會等待程式執行結束再執行下一個指令,"true"代表是,"false"代表不要,預設為"false",如果$conf["command"]有用「;」區隔的多個指令將會出錯.
1610
								#$conf["inBackGround"]="";
1611
								#備註:
1612
								#不是所有指令都能用apache的身份執行,目前已知java,javac指令無法執行,使用root身份可能會被selinux阻擋.
1613
								#參考資料:
1614
								#exec=>http://php.net/manual/en/function.exec.php
1615
								#escapeshellcmd=>http://php.net/manual/en/function.escapeshellcmd.php
1616
								#escapeshellarg=>http://php.net/manual/en/function.escapeshellarg.php
1617
								$callShell=external::callShell($conf["external::callShell"]);
1618
								unset($conf["external::callShell"]);
1619
 
1620
								#設置要回覆的內容
1621
								$res=$callShell;
1622
 
1623
								#印出回的訊息
1624
								echo "response:".PHP_EOL.print_r($res,true);
1625
 
1626
								#寫入回應的內容
1627
								fwrite($conn,json_encode($res).PHP_EOL);
1628
 
1629
								#結束回應
1630
								fwrite($conn,PHP_EOL.PHP_EOL);
1631
 
1632
								#關閉socket連線,將回應輸出.
1633
								fclose($conn);
1634
 
1635
								#更新使用者id與最後一次來request的時間
1636
								$client[$request->id]["last_req_time"]=$last_req_time;	
1637
 
1638
								#等待下個要求
1639
								continue;
1640
 
1641
								}#if end
1642
 
1643
							#設置接收到json字串資訊
1644
							$client[$request->id]["request"]=(array)($request);
1645
 
1646
							#設置用戶端的socket
1647
							$client[$request->id]["socket"]=$conn;
1648
 
1649
							#如果有要求在背景中執行指令的訊息
1650
							if(isset($request->cmdInBg)){
1651
 
1652
								#debug
1653
								#var_dump(__FUNCTION__,__LINE__,$request);
1654
 
1655
								#如果有參數
1656
								if(isset($request->param)){
1657
 
1658
									#函式說明:
1659
									#將一維陣列轉換為用特定符號間隔的字串,ex:array("1","2","3") to "a;b;c;".
1660
									#回傳的結果:
1661
									#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
1662
									#$result["function"],當前執行的function名稱
1663
									#$result["error"],錯誤訊息陣列.
1664
									#$result["content"],處理好的字串.
1665
									#$result["argu"],使用的參數.
1666
									#必填參數:
1667
									#$conf["inputArray"],字串陣列,要轉成字串的一維陣列.
1668
									$conf["arrays::arrayToString"]["inputArray"]=$request->param;
1669
									#可省略參數:
1670
									#$conf["spiltSymbol"],字串,用來區隔字串的符號,預設為;
1671
									$conf["arrays::arrayToString"]["spiltSymbol"]=" ";
1672
									#$conf["skipEnd"],字串,結尾是否不要加上符號,預設為"false",要加上符號,"true"代表不要加上符號。
1673
									$conf["arrays::arrayToString"]["skipEnd"]="true";
1674
									#$conf["spiltSymbolAtStart"],字串,是否要在開頭加上spiltSymbol,預設為"false",代表不要;反之為“true”.
1675
									$conf["arrays::arrayToString"]["spiltSymbolAtStart"]="true";
1676
									#參考資料:
1677
									#無.
1678
									#備註:
1679
									#無.
1680
									$arrayToString=arrays::arrayToString($conf["arrays::arrayToString"]);
1681
									unset($conf["arrays::arrayToString"]);
1682
 
1683
									#如果執行失敗
1684
									if($arrayToString["status"]==="false"){
183 liveuser 1685
 
3 liveuser 1686
										#設置執行失敗
1687
										$result["status"]="false";
1688
 
1689
										#設置錯誤訊息
1690
										$result["error"]=$arrayToString;
1691
 
1692
										#回傳結果
1693
										return $result;
1694
 
1695
										}#if end
1696
 
1697
									#串接參數
1698
									$request->cmdInBg=$request->cmdInBg.$arrayToString["content"];
1699
 
1700
									}#if end
1701
 
1702
								#函式說明:
1703
								#透過proc來多執行序運作.
1704
								#回傳結果:
1705
								#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
1706
								#$reuslt["error"],執行不正常結束的錯訊息陣列.
1707
								#$result["function"],當前執行的函式名稱.
1708
								#$result["argu"],使用的參數.
1709
								#$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"代表程序的資訊.
1710
								#必填參數:
1711
								#$conf["cmds"],字串陣列,每個元素代表要執行的指令與參數.
1712
								$conf["threads::proc"]["cmds"]=array($request->cmdInBg);
1713
								#可省略參數:
1714
								#$conf["wait"],字串,是否需要等待所有程序結束,預設為"true"要等待;反之為"false"不要等待.
1715
								$conf["threads::proc"]["wait"]="false";
1716
								#$conf["workingDir"],字串陣列,個別程式執行時的家目錄,預設不指定.
1717
								#$conf["workingDir"]=array("path");
1718
								#$conf["envs"],2維字串陣列,每個元素代表個別程式執行時的指定環境變數,key變數名稱;value為變數內容.預設為array("QBPWCF" => "Quick Build PHP Website Componment base on Fedora Linux");
1719
								#$conf["envs"]=array(array("key"=>"value"));
1720
								#$conf["executeBy"],字串陣列,每個元素代表個別指令要用什麼程式執行,預設為"bash".
1721
								#$conf["executeBy"]=array("bash");
1722
								#參考資料:
1723
								#https://www.php.net/manual/en/function.proc-open.php
1724
								#https://www.php.net/manual/en/function.proc-get-status.php
1725
								#備註:
1726
								#若需要取得當下的執行狀況,請使用 self::proc_update 來更新.
1727
								$proc=threads::proc($conf["threads::proc"]);
1728
								unset($conf["threads::proc"]);
1729
 
1730
								#如果執行失敗
1731
								if($proc["status"]==="false"){
183 liveuser 1732
 
3 liveuser 1733
									#設置執行失敗
1734
									$result["status"]="false";
1735
 
1736
									#設置錯誤訊息
1737
									$result["error"]=$proc;
1738
 
1739
									#回傳結果
1740
									return $result;
1741
 
1742
									}#if end
1743
 
1744
								#函式說明:
1745
								#使用 linux 的 uuid 指令來產生 uuid 字串
1746
								#回傳結果:
1747
								#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
1748
								#$result["error"],錯誤訊息.
1749
								#$result["function"],當前執行的函式名稱.
1750
								#$result["content"],uuid.
1751
								#必填參數:
1752
								#無.
1753
								#可省略參數:
1754
								#無.
1755
								#參考資料:
1756
								#無.
1757
								#備註:
1758
								#無.
1759
								$uuid=cmd::uuid();
1760
 
1761
								#如果執行失敗
1762
								if($uuid["status"]==="false"){
1763
 
1764
									#設置執行失敗
1765
									$result["status"]="false";
1766
 
1767
									#設置錯誤訊息
1768
									$result["error"]=$uuid;
1769
 
1770
									#回傳結果
1771
									return $result;
1772
 
1773
									}#if end
1774
 
1775
								#取得 uuid
1776
								$uuid=$uuid["content"];
1777
 
1778
								#儲存到 server side 的 procs
1779
								$result["serverCache"]["serverSide"]["procs"][$uuid]=$proc;
1780
 
1781
								#設置最後的檢查時間為當下
1782
								$result["serverCache"]["serverSide"]["procs"][$uuid]["latestAccessTime"]=time();
1783
 
1784
								#設置要回覆的內容
1785
								$res=array("status"=>"true","content"=>$uuid);
1786
 
1787
								#印出回的訊息
1788
								echo "response:".PHP_EOL.print_r($res,true);
1789
 
1790
								#寫入回應的內容
1791
								fwrite($conn,json_encode($res).PHP_EOL);
1792
 
1793
								#結束回應
1794
								fwrite($conn,PHP_EOL.PHP_EOL);
1795
 
1796
								#關閉socket連線,將回應輸出.
1797
								fclose($conn);
1798
 
1799
								#更新使用者id與最後一次來request的時間
1800
								$client[$request->id]["last_req_time"]=$last_req_time;
1801
 
1802
								#等待下個要求
1803
								continue;
1804
 
1805
								}#if end
1806
 
1807
							#如果要查詢程序執行的狀況
1808
							if(isset($request->QueryProcByUUID)){
1809
 
1810
								#如果沒有 proc 資訊
1811
								if(!isset($result["serverCache"]["serverSide"]["procs"])){
1812
 
1813
									#設置要回覆的內容
1814
									$res=array("status"=>"true","content"=>"");
1815
 
1816
									#印出回的訊息
1817
									echo "response:".PHP_EOL.print_r($res,true);
1818
 
1819
									#寫入回應的內容
1820
									fwrite($conn,json_encode($res).PHP_EOL);
1821
 
1822
									#結束回應
1823
									fwrite($conn,PHP_EOL.PHP_EOL);
1824
 
1825
									#關閉socket連線,將回應輸出.
1826
									fclose($conn);
1827
 
1828
									#更新使用者id與最後一次來request的時間
1829
									$client[$request->id]["last_req_time"]=$last_req_time;
1830
 
1831
									#等待下個要求
1832
									continue;
1833
 
1834
									}#if end
1835
 
1836
								#函式說明:
1837
								#更新透過proc執行的多程序資訊.
1838
								#回傳結果:
1839
								#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
1840
								#$reuslt["error"],執行不正常結束的錯訊息陣列.
1841
								#$result["function"],當前執行的函式名稱.
1842
								#$result["argu"],使用的參數.
1843
								#$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"代表程序的資訊.
1844
								#必填參數:
1845
								#$conf["procs"],陣列,運行self::proc後回傳的content.
1846
								$conf["threads::proc_update"]["procs"]=$result["serverCache"]["serverSide"]["procs"][$request->QueryProcByUUID]["content"];
1847
								#可省略參數:
1848
								#無.
1849
								#參考資料:
1850
								#無.
1851
								#備註:
1852
								#無.
1853
								$proc_update=threads::proc_update($conf["threads::proc_update"]);
1854
								unset($conf["threads::proc_update"]);
1855
 
1856
								#如果執行失敗
1857
								if($proc_update["status"]==="false"){
1858
 
1859
									#設置執行失敗
1860
									$result["status"]="false";
1861
 
1862
									#設置錯誤訊息
1863
									$result["error"]=$proc_update;
1864
 
1865
									#回傳結果
1866
									return $result;
1867
 
1868
									}#if end
1869
 
1870
								#更新 serverSide 的 proc cache
1871
								$result["serverCache"]["serverSide"]["procs"][$request->QueryProcByUUID]["content"]=$proc_update["content"];
1872
 
1873
								#設置最後檢查的時間
1874
								$result["serverCache"]["serverSide"]["procs"][$request->QueryProcByUUID]["latestAccessTime"]=time();
1875
 
1876
								#印出子程序的資訊
1877
								echo "proc info:".PHP_EOL.print_r($proc_update["content"][0],true);
1878
 
1879
								#初始化要回傳的內容
1880
								$res=array();
1881
 
1882
								#設置 pid
1883
								$res["pid"]=$proc_update["content"][0]["proc_get_status"]["pid"];
1884
 
1885
								#設置輸入的內容
1886
								$res["input"]=$proc_update["content"][0]["input"];
1887
 
1888
								#預設設置已經結束執行
1889
								$res["running"]="false";
1890
 
1891
								#如果尚在執行
1892
								if($proc_update["content"][0]["statusCode"]==="?"){
1893
 
1894
									#設置正在執行
1895
									$res["running"]="true";
1896
 
1897
									}#if end
1898
 
1899
								#如果已經結束執行
1900
								if($res["running"]==="false"){
1901
 
1902
									#設置執行後得到的標準輸出
1903
									$res["output"]=$proc_update["content"][0]["content"];
1904
 
1905
									#設置執行後得到的錯誤輸出
1906
									$res["error"]=$proc_update["content"][0]["error"];
1907
 
1908
									}#if end
1909
 
1910
								#設置回應正常
1911
								$res["status"]="true";
1912
 
1913
								#印出回的訊息
1914
								echo "response:".PHP_EOL.print_r($res,true);
1915
 
1916
								#寫入回應的內容
1917
								fwrite($conn,json_encode($res).PHP_EOL);
1918
 
1919
								#結束回應
1920
								fwrite($conn,PHP_EOL.PHP_EOL);
1921
 
1922
								#關閉socket連線,將回應輸出.
1923
								fclose($conn);
1924
 
1925
								#更新使用者id與最後一次來request的時間
1926
								$client[$request->id]["last_req_time"]=$last_req_time;
1927
 
1928
								#等待下個要求
1929
								continue;
1930
 
1931
								}#if end
1932
 
1933
							#debug
1934
							#var_dump(__LINE__,$conn,$client[$request->id]);
1935
 
1936
							#如果存在 addOnProcessFunc
1937
							if(isset($conf["addOnProcessFunc"])){
1938
 
1939
								#針對每個 addOnProcessFunc
1940
								foreach($conf["addOnProcessFunc"] as $addOnProcessFunc){
1941
 
1942
									#如果有設置 infoToFunction
1943
									if(isset($conf["infoToFunction"])){
1944
 
1945
										#設置info
1946
										$client[$request->id]["info"]=&$conf["infoToFunction"];
1947
 
1948
										}#if end
1949
 
1950
									#設置client cache
1951
									$client[$request->id]["clientCache"]=&$clientCache;
1952
 
1953
									#呼叫 $addOnProcessFunc 函式,參數用 $client[$request->id], 取得執行後的回應.
1954
									eval("\$call_user_func=".$addOnProcessFunc."(\$client[\$request->id]);");
1955
 
1956
									/* debug
1957
 
1958
									#函式說明:
1959
									#撰寫log
1960
									#回傳結果:
1961
									#$result["status"],狀態,"true"或"false".
1962
									#$result["error"],錯誤訊息陣列.
1963
									#$result["function"],當前函式的名稱.
1964
									#$result["argu"],使用的參數.
1965
									#$result["content"],要寫入log的內容字串.
1966
									#必填參數:
1967
									#$conf["path"],字串,log檔案的路徑與名稱.
1968
									$conf["logs::record"]["path"]=$conf["sock"].".log";
1969
									#$conf["content"],any,要寫的內容,若內容不為字串則會用var_dump的格式寫入.
1970
									$conf["logs::record"]["content"]=$call_user_func;
1971
									#$conf["fileArgu"],字串,php變數__FILE__的內容,亦即該檔案在檔案系統的絕對路徑
1972
									$conf["logs::record"]["fileArgu"]=__FILE__;
1973
									#可省略參數:
1974
									#$conf["rewrite"],預設為"false",接續寫入;反之"true"代表重新寫入.
1975
									#$conf["rewrite"]="false";
1976
									#$conf["returnOnly"],預設為"false",會寫入到log檔案.若為"true"則不會寫入log.
1977
									#$conf["returnOnly"]="true";
1978
									#參考資料:
1979
									#無.
1980
									#備註:
1981
									#無.
1982
									$record=logs::record($conf["logs::record"]);
1983
									unset($conf["logs::record"]);
1984
 
1985
									#如果執行失敗
1986
									if($record["status"]==="false"){
1987
 
1988
										#設置執行錯誤識別
1989
										$result["status"]="false";
1990
 
1991
										#設置執行錯誤
1992
										$result["error"]=$record;
1993
 
1994
										#回傳結果
1995
										return $result;
1996
 
1997
										}#if end
1998
 
1999
									*/
2000
 
2001
									#如果回應不是 array
2002
									if(gettype($call_user_func)!=="array"){
2003
 
2004
										#設置執行失敗
2005
										$result["status"]="false";
2006
 
2007
										#設置錯誤訊息
2008
										$result["error"][]=$call_user_func;
2009
 
2010
										#設置錯誤訊息
2011
										$result["error"][]=$conf;
2012
 
2013
										#印出error資訊
2014
										echo "error:".print_r($result,true);
2015
 
2016
										#回應錯誤訊息給用戶
2017
										fwrite($conn,json_encode($result).PHP_EOL);
2018
 
2019
										#結束回應
2020
										fwrite($conn,PHP_EOL.PHP_EOL);
2021
 
2022
										#關閉socket連線,將回應輸出.
2023
										fclose($conn);
2024
 
2025
										#回傳結果
2026
										return $result;
2027
 
2028
										}#if end
2029
 
2030
									#檢查回應的格式
2031
									#函式說明:
2032
									#檢查必填與可省略的參數,可省略參數可指定預設要給與什麼數值內容。
2033
									#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
2034
									#$reuslt["error"],執行不正常結束的錯訊息陣列.
2035
									#$result["function"],當前執行的函式名稱.
2036
									#$result["argu"],設置給予的參數.
2037
									#$result["passed"],識別要檢查的全體變數是否存在以及型態是否正確的變數,"true"代表檢查全部通過;"false"代表檢查不通過
2038
									#$result[$shouldBeCheckedVarName]["varExist"],所檢查的變數是否存在,"false"代表不存在;"true"代表存在
2039
									#$result[$shouldBeCheckedVarName]["varType"],所檢查的變數型態是否正確,"false"代表錯誤;"true"代表正確
2040
									#$result[$shouldBeCheckedVarName]["error"],每個參數設定的錯誤訊息
2041
									#$result["shouldNotBeEmpty"],不應該為空字串或控陣列的變數.
2042
									#$result["argu"],字串陣列,目前輸入的參數名稱陣列.
2043
									#$result["legalVarName"],字串陣列,合法可用的參數名稱陣列.
2044
									#$result["notNeedVar"],字串陣列,多餘的參數名稱.
2045
									#必填寫的參數:
2046
									#$conf["varInput"],陣列變數,要檢查的陣列變數,請在要檢查的參數前面加上&,這樣變動的結果才能被套用。
2047
									$conf["variableCheck::checkArguments"]["varInput"]=&$call_user_func;	
2048
									#$conf["referenceVarKey"],字串,$conf參數後面的key值,用於移除不要的參考陣列.
2049
									$conf["variableCheck::checkArguments"]["referenceVarKey"]="variableCheck::checkArguments";
2050
									#可以省略的參數:
2051
									#$conf["mustBeFilledVariableName"],爲必填參數的變數名稱陣列,形態爲陣列變數,元素數量需要跟"mustBeFilledVariableType"參數的元素數量一致,例如: $conf["mustBeFilledVariableName"] = array("id","account","password");
2052
									$conf["variableCheck::checkArguments"]["mustBeFilledVariableName"]=array("status");
2053
									#$conf["mustBeFilledVariableType"],爲必填參數的變數陣列應該爲何種變數形態,形態爲陣列,元素數量需要跟"mustBeFilledVariableName"參數的元素數量一致,例如: $conf["mustBeFilledVariableType"] = array("string",integer,"double","resource","object"); , null代表不指定變數形態.
2054
									$conf["variableCheck::checkArguments"]["mustBeFilledVariableType"]=array("string");
2055
									#$conf["canBeEmptyString"],字串,必填變數內容如果是空字串就不能算是有設置的話,請設為"false",預設爲"true",可以為空字串.
2056
									$conf["variableCheck::checkArguments"]["canBeEmptyString"]="false";
2057
									#$conf["canNotBeEmpty"],字串陣列,哪些必填參數的內容不得為空字串或空陣列,僅當$conf["canBeEmptyString"]為"true"時會生效.
2058
									#$conf["canNotBeEmpty"]=array();
2059
									#$conf["canBeEmpty"],字串陣列,哪些必填參數的內容可為空字串或空陣列,僅當$conf["canBeEmptyString"]為"false"時會生效.
2060
									#$conf["canBeEmpty"]=array();
2061
									#$conf["skipableVariableCanNotBeEmpty"],字串陣列,哪些可省略參數不可以為空字串或空陣列.
2062
									#$conf["variableCheck::checkArguments"]["skipableVariableCanNotBeEmpty"]=array("function","continue");
2063
									#$conf["skipableVariableName"],陣列字串,爲可省略參數的變數名稱陣列,形態爲陣列變數,例如: $conf["skipableVariableName"] = array("id","account","password");
2064
									$conf["variableCheck::checkArguments"]["skipableVariableName"]=array("function","continue","content","cache","argu","error");
2065
									#$conf["skipableVariableType"],陣列字串,爲可省略參數的變數名稱陣列,形態爲陣列變數,例如: $conf["skipableVariableType"] = array("string",integer,"double"); 
2066
									$conf["variableCheck::checkArguments"]["skipableVariableType"]=array("string","string",null,"array","array","array");
2067
									#$conf["skipableVarDefaultValue"],字串陣列,每個不存在的可省略變數要初始化為什麼,null與代表不指定,若預設值是參數之一,請將$conf["mustBeFilledVar"]改成"\$conf["\mustBeFilledVar\"]".
2068
									$conf["variableCheck::checkArguments"]["skipableVarDefaultValue"]=array($addOnProcessFunc,"true",null,null,null,null);
2069
									#$conf["disallowAllSkipableVarIsEmpty"],字串,是否允許每個可省略參數都為空字串,預設為"true"允許,反之為"false".
2070
									#$conf["disallowAllSkipableVarIsEmpty"]="";
2071
									#$conf["disallowAllSkipableVarIsEmptyArray"],字串,是否允許每個可省略參數都為空陣列,預設為"true"允許,反之為"false".
2072
									#$conf["disallowAllSkipableVarIsEmptyArray"]="";
2073
									#$conf["arrayCountEqualCheck"],字串陣列,為檢查哪些陣列參數的元素數量要一樣,$conf["arrayCountEqualCheck"][$i]=array()為第$i組key為哪些的變數其元素數量要相等.
2074
									#$conf["arrayCountEqualCheck"][]=array();
2075
									#參考資料來源:
2076
									#array_keys=>http://php.net/manual/en/function.array-keys.php
2077
									$checkArguments=variableCheck::checkArguments($conf["variableCheck::checkArguments"]);
2078
									unset($conf["variableCheck::checkArguments"]);
2079
 
2080
									#如果檢查參數失敗
2081
									if($checkArguments["status"]==="false"){
2082
 
2083
										#設置執行失敗
2084
										$result["status"]="false";
2085
 
2086
										#設置錯誤訊息
2087
										$result["error"]=$checkArguments;
2088
 
2089
										#印出error資訊
2090
										echo "error:".print_r($result,true);
2091
 
2092
										#回應錯誤訊息給用戶
2093
										fwrite($conn,json_encode($result).PHP_EOL);
2094
 
2095
										#結束回應
2096
										fwrite($conn,PHP_EOL.PHP_EOL);
2097
 
2098
										#關閉socket連線,將回應輸出.
2099
										fclose($conn);
2100
 
2101
										#回傳結果
2102
										return $result;
2103
 
2104
										}#if end
2105
 
2106
									#如果檢查參數不通過
2107
									if($checkArguments["passed"]==="false"){
2108
 
2109
										#設置執行失敗
2110
										$result["status"]="false";
2111
 
2112
										#設置錯誤訊息
2113
										$result["error"]=$checkArguments;
2114
 
2115
										#印出error資訊
2116
										echo "error:".print_r($result,true);
2117
 
2118
										#回應錯誤訊息給用戶
2119
										fwrite($conn,json_encode($result).PHP_EOL);
2120
 
2121
										#結束回應
2122
										fwrite($conn,PHP_EOL.PHP_EOL);
2123
 
2124
										#關閉socket連線,將回應輸出.
2125
										fclose($conn);
2126
 
2127
										#回傳結果
2128
										return $result;
2129
 
2130
										}#if end
2131
 
2132
									#如果回應不正常
2133
									if($call_user_func["status"]==="false"){
2134
 
2135
										#設置執行失敗
2136
										$result["status"]="false";
2137
 
2138
										#設置錯誤訊息
2139
										$result["error"][]=$call_user_func;
2140
 
2141
										#設置錯誤訊息
2142
										$result["error"][]=$conf;
2143
 
2144
										#印出error資訊
2145
										echo "error:".print_r($result,true);
2146
 
2147
										#回應錯誤訊息給用戶
2148
										fwrite($conn,json_encode($result).PHP_EOL);
2149
 
2150
										#結束回應
2151
										fwrite($conn,PHP_EOL.PHP_EOL);
2152
 
2153
										#關閉socket連線,將回應輸出.
2154
										fclose($conn);
2155
 
2156
										#回傳結果
2157
										return $result;
2158
 
2159
										}#if end
2160
 
2161
									#如果回應有 content 元素
2162
									if(isset($call_user_func["content"])){
2163
 
2164
										#用收到 content 元素內容來更新 $client[id]["request"]
2165
										$client[$request->id]["request"]=$call_user_func["content"];
2166
 
2167
										}#if end
2168
 
2169
									#如果回傳 cache 元素
2170
									if(isset($call_user_func["cache"])){
2171
 
2172
										#用收到 cache 元素內容來更新 server side 的 cache
2173
										$result["serverCache"]["clientSide"]["addOnProcessFunc"][$addOnProcessFunc]=&$call_user_func["cache"];
2174
 
2175
										}#if end
2176
 
2177
									#如果回應不要往後面執行
2178
									if($call_user_func["continue"]==="false"){
2179
 
2180
										#結束 foreach
2181
										break;
2182
 
2183
										}#if end
2184
 
2185
									}#foreach end
2186
 
2187
								}#if end
2188
 
2189
							#執行到這代表是要保持連線
2190
 
2191
							#設置執行正常
2192
							$res["status"]="true";
2193
 
2194
							#印出回的訊息
2195
							echo "response:".PHP_EOL.print_r($res,true);
2196
 
2197
							#debug
2198
							#var_dump(__LINE__,$conn,get_resource_type($conn));
2199
 
2200
							#如果資源形態沒有異常(用戶關閉連線後,會有resource type變成"Unknown"的結果)
2201
							if(get_resource_type($conn)!=="Unknown"){
2202
 
2203
								#函式說明:
2204
								#用fwrite寫入到resource,可以指定每個寫入字串的結尾方式.
2205
								#回傳結果:
2206
								#$result["status"],執行是否正常,"true"為正常,"false"為不正常.
2207
								#$result["error"],錯誤訊息陣列.
2208
								#$result["function"],當前執行的函數名稱.
2209
								#$result["argu"],使用的參數.
2210
								#$result["is_writable"],參數stream是否為可寫入的resource,"true"代表可寫入;"false"代表不可寫入.
2211
								#必填參數:
2212
								#$conf["stream"],resource,寫入的目標.
2213
								$conf["sock::fwrite"]["stream"]=&$conn;
2214
								#$conf["data"],字串陣列,要寫入的內容,每個元素代表每段要寫入的內容.
2215
								$conf["sock::fwrite"]["data"]=array(json_encode($res).PHP_EOL);
2216
								#可省略參數:
2217
								#$conf["msgEndType"],字串,訊息結尾要怎麼寫,預設為"none",代表不做處理;"EOL"代表結尾要用PHP_EOL;"HTTP/1.1"代表"data"參數最多為2個,分別為header跟body,結尾方式為兩個PHP_EOL.
2218
								$conf["sock::fwrite"]["msgEndType"]="HTTP/1.1";
2219
								#$conf["autoClose"],字串,寫入結束後是否要關閉resource,預設為"false"代表保持開着;反之為"true".
2220
								$conf["sock::fwrite"]["autoClose"]="true";
2221
								#參考資料:
2222
								#https://stackoverflow.com/questions/5294305/how-to-check-if-a-php-stream-resource-is-readable-or-writable#5294425
2223
								#https://www.php.net/manual/en/function.stream-get-meta-data.php
2224
								#https://www.php.net/manual/en/function.is-writable.php
2225
								#https://www.php.net/manual/en/function.socket-get-status.php
2226
								#備註:
2227
								#無.
2228
								$fwrite=sock::fwrite($conf["sock::fwrite"]);
2229
								unset($conf["sock::fwrite"]);
2230
 
2231
								#如果執行失敗
2232
								if($fwrite["status"]==="false"){
2233
 
2234
									#如果有 is_writable
2235
									if(isset($fwrite["is_writable"])){
2236
 
2237
										#如果有 is_writable
2238
										if($fwrite["is_writable"]==="true"){
2239
 
2240
											#設置執行失敗
2241
											$result["status"]="false";
2242
 
2243
											#設置錯誤訊息
2244
											$result["error"]=$fwrite;
2245
 
2246
											#印出error資訊
2247
											echo "error:".print_r($result,true);
2248
 
2249
											#結束並回傳1給shell
2250
											exit(1);
2251
 
2252
											}#if end
2253
 
2254
										}#if end
2255
 
2256
									#反之
2257
									else{
2258
 
2259
										#設置執行失敗
2260
										$result["status"]="false";
2261
 
2262
										#設置錯誤訊息
2263
										$result["error"]=$fwrite;
2264
 
2265
										#印出error資訊
2266
										echo "error:".print_r($result,true);
2267
 
2268
										#結束並回傳1給shell
2269
										exit(1);
2270
 
2271
										}#else end
2272
 
2273
									}#if end
2274
 
2275
								}#if end
2276
 
2277
							#更新使用者id與最後一次來request的時間
183 liveuser 2278
							$client[$request->id]["last_req_time"]=$last_req_time;
3 liveuser 2279
 
2280
							#印出用戶端列表
183 liveuser 2281
							echo "clients:".print_r($client,true);
3 liveuser 2282
 
2283
							#等待下個要求
2284
							continue;
2285
 
2286
							}#if end
2287
 
2288
						#socket 陣列不是我們建立的 socket
2289
						else{
2290
 
2291
							#顯示 socket 的狀態
2292
							var_dump("socket_get_status".socket_get_status($conn));
2293
 
2294
							}#else end
2295
 
2296
						}#foreach end
2297
 
2298
					}#else end
2299
 
2300
				}#while end
2301
 
2302
			#關閉 unix domain socket
2303
			fclose($socket);
2304
 
2305
			}#else end
2306
 
2307
		}#function unixDomainSockServer end
2308
 
2309
	/*
2310
	#函式說明:
2311
	#連線到 unixDomainSockServer 提供的 unix domain socket.
2312
	#回傳結果:
2313
	#$result["status"],"true"代表執行正常;"false"代表執行不正常.
2314
	#$result["error"],錯誤訊息陣列.
2315
	#$result["function"],當前執行的函式名稱.
2316
	#$result["content"],取得的回應,讀到EOL,才會結束.
2317
	#必填參數:
2318
	#$conf["sock"],字串,要連線的unix domain socket.
2319
	$conf["sock"]="";
2320
	#可省略參數:
2321
	#$conf["id"],字串,取得的id,若無此值,則會得到新的數值.
2322
	#$conf["id"]="";
2323
	#$conf["cmd"],字串,要執行的指令,當$conf["id"]參數合法時,才會執行.
2324
	#$conf["cmd"]="";
2325
	#$conf["param"],參數陣列.
2326
	#$conf["param"]=array();
2327
	#$conf["escaped"],字串,param參數是否已經escaped了,預設為"false",反之為"true".
2328
	#$conf["escaped"]="true";
2329
	#$conf["custom"],陣列,要客制化傳輸的內容,會覆蓋以上除了$conf["id"]以外的可省略參數.
2330
	#$conf["custom"]=array();
2331
	#$conf["raw"],字串,要直接傳送的字串內容,會忽略其他可省略參數.
2332
	#$conf["raw"]="";
2333
	#參考資料:
2334
	#http://php.net/manual/en/function.stream-socket-client.php
2335
	#http://php.net/manual/en/function.stream-get-contents.php
2336
	#備註:
2337
	#無.
2338
	*/
2339
	public static function unixDomainSockClient(&$conf){
2340
 
2341
		#初始化要回傳的結果
2342
		$result=array();
2343
 
2344
		#取得當前執行的函數名稱
2345
		$result["function"]=__FUNCTION__;
2346
 
2347
		#如果沒有參數
2348
		if(func_num_args()==0){
2349
 
2350
			#設置執行失敗
2351
			$result["status"]="false";
2352
 
2353
			#設置執行錯誤訊息
2354
			$result["error"]="函數".$result["function"]."需要參數";
2355
 
2356
			#回傳結果
2357
			return $result;
2358
 
2359
			}#if end
2360
 
2361
		#取得參數
2362
		$result["argu"]=$conf;
2363
 
2364
		#如果 $conf 不為陣列
2365
		if(gettype($conf)!="array"){
2366
 
2367
			#設置執行失敗
2368
			$result["status"]="false";
2369
 
2370
			#設置執行錯誤訊息
2371
			$result["error"][]="\$conf變數須為陣列形態";
2372
 
2373
			#如果傳入的參數為 null
2374
			if($conf==null){
2375
 
2376
				#設置執行錯誤訊息
2377
				$result["error"][]="\$conf變數不得為null,請檢查函數「".$result["function"]."」的參數設置有無正確!";
2378
 
2379
				}#if end
2380
 
2381
			#回傳結果
2382
			return $result;
2383
 
2384
			}#if end
2385
 
2386
		#檢查參數
2387
		#函式說明:
2388
		#檢查必填與可省略的參數,可省略參數可指定預設要給與什麼數值內容。
2389
		#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
2390
		#$reuslt["error"],執行不正常結束的錯訊息陣列.
2391
		#$result["function"],當前執行的函式名稱.
2392
		#$result["argu"],設置給予的參數.
2393
		#$result["passed"],識別要檢查的全體變數是否存在以及型態是否正確的變數,"true"代表檢查全部通過;"false"代表檢查不通過
2394
		#$result[$shouldBeCheckedVarName]["varExist"],所檢查的變數是否存在,"false"代表不存在;"true"代表存在
2395
		#$result[$shouldBeCheckedVarName]["varType"],所檢查的變數型態是否正確,"false"代表錯誤;"true"代表正確
2396
		#$result[$shouldBeCheckedVarName]["error"],每個參數設定的錯誤訊息
2397
		#$result["shouldNotBeEmpty"],不應該為空字串或控陣列的變數.
2398
		#$result["argu"],字串陣列,目前輸入的參數名稱陣列.
2399
		#$result["legalVarName"],字串陣列,合法可用的參數名稱陣列.
2400
		#$result["notNeedVar"],字串陣列,多餘的參數名稱.
2401
		#必填寫的參數:
2402
		#$conf["varInput"],陣列變數,要檢查的陣列變數,請在要檢查的參數前面加上&,這樣變動的結果才能被套用。
2403
		$conf["variableCheck::checkArguments"]["varInput"]=&$conf;	
2404
		#$conf["referenceVarKey"],字串,$conf參數後面的key值,用於移除不要的參考陣列.
2405
		$conf["variableCheck::checkArguments"]["referenceVarKey"]="variableCheck::checkArguments";
2406
		#可以省略的參數:
2407
		#$conf["mustBeFilledVariableName"],爲必填參數的變數名稱陣列,形態爲陣列變數,元素數量需要跟"mustBeFilledVariableType"參數的元素數量一致,例如: $conf["mustBeFilledVariableName"] = array("id","account","password");
2408
		$conf["variableCheck::checkArguments"]["mustBeFilledVariableName"]=array("sock");
2409
		#$conf["mustBeFilledVariableType"],爲必填參數的變數陣列應該爲何種變數形態,形態爲陣列,元素數量需要跟"mustBeFilledVariableName"參數的元素數量一致,例如: $conf["mustBeFilledVariableType"] = array("string",integer,"double","resource","object"); , null代表不指定變數形態.
2410
		$conf["variableCheck::checkArguments"]["mustBeFilledVariableType"]=array("string");
2411
		#$conf["canBeEmptyString"],字串,必填變數內容如果是空字串就不能算是有設置的話,請設為"false",預設爲"true",可以為空字串.
2412
		#$conf["canBeEmptyString"]="false";
2413
		#$conf["canNotBeEmpty"],字串陣列,哪些必填參數的內容不得為空字串或空陣列,僅當$conf["canBeEmptyString"]為"true"時會生效.
2414
		#$conf["canNotBeEmpty"]=array();
2415
		#$conf["canBeEmpty"],字串陣列,哪些必填參數的內容可為空字串或空陣列,僅當$conf["canBeEmptyString"]為"false"時會生效.
2416
		#$conf["canBeEmpty"]=array();
2417
		#$conf["skipableVariableCanNotBeEmpty"],字串陣列,哪些可省略參數不可以為空字串或空陣列.
2418
		$conf["variableCheck::checkArguments"]["skipableVariableCanNotBeEmpty"]=array("id","cmd","param","escaped","custom");
2419
		#$conf["skipableVariableName"],陣列字串,爲可省略參數的變數名稱陣列,形態爲陣列變數,例如: $conf["skipableVariableName"] = array("id","account","password");
2420
		$conf["variableCheck::checkArguments"]["skipableVariableName"]=array("id","cmd","param","escaped","custom","raw");
2421
		#$conf["skipableVariableType"],陣列字串,爲可省略參數的變數名稱陣列,形態爲陣列變數,例如: $conf["skipableVariableType"] = array("string",integer,"double"); 
2422
		$conf["variableCheck::checkArguments"]["skipableVariableType"]=array("string","string","array","string","array","string");
2423
		#$conf["skipableVarDefaultValue"],字串陣列,每個不存在的可省略變數要初始化為什麼,null與代表不指定,若預設值是參數之一,請將$conf["mustBeFilledVar"]改成"\$conf["\mustBeFilledVar\"]".
2424
		$conf["variableCheck::checkArguments"]["skipableVarDefaultValue"]=array(null,null,null,"false",null,null);
2425
		#$conf["disallowAllSkipableVarIsEmpty"],字串,是否允許每個可省略參數都為空字串,預設為"true"允許,反之為"false".
2426
		#$conf["disallowAllSkipableVarIsEmpty"]="";
2427
		#$conf["disallowAllSkipableVarIsEmptyArray"],字串,是否允許每個可省略參數都為空陣列,預設為"true"允許,反之為"false".
2428
		#$conf["disallowAllSkipableVarIsEmptyArray"]="";
2429
		#$conf["arrayCountEqualCheck"],字串陣列,為檢查哪些陣列參數的元素數量要一樣,$conf["arrayCountEqualCheck"][$i]=array()為第$i組key為哪些的變數其元素數量要相等.
2430
		#$conf["arrayCountEqualCheck"][]=array();
2431
		#參考資料來源:
2432
		#array_keys=>http://php.net/manual/en/function.array-keys.php
2433
		$checkArguments=variableCheck::checkArguments($conf["variableCheck::checkArguments"]);
2434
		unset($conf["variableCheck::checkArguments"]);
2435
 
2436
		#如果檢查參數失敗
2437
		if($checkArguments["status"]==="false"){
2438
 
2439
			#設置執行失敗
2440
			$result["status"]="false";
2441
 
2442
			#設置錯誤訊息
2443
			$result["error"]=$checkArguments;
2444
 
2445
			#回傳結果
2446
			return $result;
2447
 
2448
			}#if end
2449
 
2450
		#如果檢查參數不通過
2451
		if($checkArguments["passed"]==="false"){
2452
 
2453
			#設置執行失敗
2454
			$result["status"]="false";
2455
 
2456
			#設置錯誤訊息
2457
			$result["error"]=$checkArguments;
2458
 
2459
			#回傳結果
2460
			return $result;
2461
 
2462
			}#if end
2463
 
2464
		#檢查 unix socket 檔案 $conf["sock"] 是否存在.
2465
		#函式說明:
2466
		#檢查多個檔案與資料夾是否存在.
2467
		#回傳的結果:
2468
		#$result["status"],執行正常與否,"true"代表正常,"false"代表不正常.
2469
		#$result["error"],錯誤訊息陣列.
2470
		#$resutl["function"],當前執行的涵式名稱.
2471
		#$result["argu"],使用的參數.
2472
		#$result["allExist"],所有檔案皆存在的識別,"true"代表皆存在,"false"代表沒有全部都存在.
2473
		#$result["varName"][$i],爲第$i個資料夾或檔案的路徑與名稱。
2474
		#$result["varNameFullPath"][$i],爲第$i個資料夾或檔案的完整檔案系統路徑與名稱,如果不存在則代表路徑是網址.
2475
		#$result["varNameWebPath"][$i],為第$i個資料夾或檔案的網址
2476
		#$result["varExist"][$i],爲第$i個資料夾或檔案是否存在,"true"代表存在,"false"代表不存在。
2477
		#必填參數:
2478
		#$conf["fileArray"],陣列字串,要檢查是否存在的檔案有哪些,須爲一維陣列數值。
2479
		$conf["variableCheck::checkArguments"]["fileArray"]=array($conf["sock"]);
2480
		#$conf["fileArgu"],字串,php變數__FILE__的內容,亦即該檔案在檔案系統的絕對路徑
2481
		$conf["variableCheck::checkArguments"]["fileArgu"]=__FILE__;
2482
		#可省略參數:
2483
		#$conf["disableWebSearch"],"字串",是否取消「當檔案找不到時,改用catchWebContent類別的wget函數來檢查檔案是否存在於網路上」的功能,"false"不取消,若要取消該功能請設為"true",若抓到的內容為空字串則會視為檔案不存在,預設為"true".
2484
		#$conf["disableWebSearch"]="false";
2485
		#$conf["userDir"],字串,網頁是否置放於家目錄底下,"true"為是,"false"為不是,預設為"true".
2486
		$conf["variableCheck::checkArguments"]["userDir"]="false";
2487
		#$conf["web"],字串,檔案是放在web就是"true",反之為檔案系統"false",預設為"true".
2488
		$conf["variableCheck::checkArguments"]["web"]="false";
2489
		#參考資料:
2490
		#http://php.net/manual/en/function.file-exists.php
2491
		#http://php.net/manual/en/control-structures.foreach.php
2492
		#備註:
2493
		#函數file_exists檢查的路徑為檔案系統的路徑
2494
		#$result["varName"][$i]結果未實作
2495
		$checkMultiFileExist=fileAccess::checkMultiFileExist($conf["variableCheck::checkArguments"]);
2496
		unset($conf["variableCheck::checkArguments"]);
2497
 
2498
		#如果檢查失敗
2499
		if($checkMultiFileExist["status"]==="false"){
2500
 
2501
			#設置執行失敗
2502
			$result["status"]="false";
2503
 
2504
			#設置錯誤訊息
2505
			$result["error"]=$checkMultiFileExist;
2506
 
2507
			#回傳結果
2508
			return $result;
2509
 
2510
			}#if end
2511
 
2512
		#如果檢查失敗
2513
		if($checkMultiFileExist["allExist"]==="false"){
2514
 
2515
			#設置執行失敗
2516
			$result["status"]="false";
2517
 
2518
			#設置錯誤訊息
2519
			$result["error"]=$checkMultiFileExist;
2520
 
2521
			#回傳結果
2522
			return $result;
2523
 
2524
			}#if end
2525
 
2526
		#初始化取得的回應
2527
		$result["content"]="";
2528
 
2529
		#debug
2530
		#var_dump(__LINE__,"before connect");
2531
 
2532
		#嘗試30秒內連線到 unix domain socket
2533
		$fp=@stream_socket_client("unix://".$conf["sock"], $errno, $errstr, 30, STREAM_CLIENT_ASYNC_CONNECT );
2534
 
2535
		#如果開啟 unix domain socket 失敗
2536
		if(!$fp){
2537
 
2538
			#設置執行錯誤識別
2539
			$result["status"]="false";
2540
 
2541
			#設置錯誤訊息
2542
			$result["error"]=$errstr." (".$errno.")";
2543
 
2544
			#回傳結果
2545
			return $result;
2546
 
2547
			}#if end
2548
 
2549
		#反之開啟 unix domain socket 成功,且沒有raw參數存在
2550
		else if(!isset($conf["raw"])){
2551
 
2552
			#初始化要傳送的要求
2553
			$req=array();
2554
 
2555
			#如果有設置 $conf["id"]
2556
			if(isset($conf["id"])){
2557
 
2558
				#設置識別自己的id
2559
				$req["id"]=$conf["id"];
2560
 
2561
				}#if end
2562
 
2563
			#如果有設置 $conf["cmd"]
2564
			if(isset($conf["cmd"])){
2565
 
2566
				#設置要執行的指令
2567
				$req["cmd"]=$conf["cmd"];
2568
 
2569
				}#if end
2570
 
2571
			#如果有設置 $conf["param"]
2572
			if(isset($conf["param"])){
2573
 
2574
				#設置要執行的指令參數
2575
				$req["param"]=$conf["param"];
2576
 
2577
				#設置參數是否已經escaped
2578
				$req["escaped"]=$conf["escaped"];
2579
 
2580
				}#if end
2581
 
2582
			#如果有設置 $conf["custom"]
2583
			if(isset($conf["custom"])){
2584
 
2585
				#用 $conf["custom"] 來取代 $req
2586
				$req=$conf["custom"];
2587
 
2588
				#如果有設置 $conf["id"]
2589
				if(isset($conf["id"])){
2590
 
2591
					#設置識別自己的id
2592
					$req["id"]=$conf["id"];
2593
 
2594
					}#if end
2595
 
2596
				}#if end
2597
 
2598
			#debug
2599
			#var_dump(__LINE__,"before write ".json_encode($req));
2600
 
2601
			#傳送要求
2602
			fwrite($fp,json_encode($req).PHP_EOL);
2603
 
2604
			#結束要求
2605
			fwrite($fp,PHP_EOL.PHP_EOL);
2606
 
2607
			#如果回應為空	
2608
			while(strlen($result["content"])<2){
2609
 
2610
				#當有回應時
2611
				while(!feof($fp)){
2612
 
2613
					#讀取回應
2614
					$tmp=fgets($fp, 1024);
2615
 
2616
					#debug
2617
					#var_dump($tmp);
2618
 
2619
					#debug
2620
					#var_dump(__LINE__,"got ".$tmp);
2621
 
2622
					#如果讀到 PHP_EOL
2623
					if($tmp===PHP_EOL){
2624
 
2625
						#結束讀取回應
2626
						break 2;
2627
 
2628
						}#if end
2629
 
2630
					#串接回應
2631
					$result["content"]=$result["content"].$tmp;
2632
 
2633
					}#while end
2634
 
2635
				}#while end
2636
 
2637
			#關閉 socket
2638
			fclose($fp);
2639
 
2640
			}#else end
2641
 
2642
		#反之有有raw參數存在
2643
		else{
2644
 
2645
			#傳送要求
2646
			fwrite($fp,trim($conf["raw"]).PHP_EOL);
2647
 
2648
			#當有回應時
2649
			while(!feof($fp)){
2650
 
2651
				#讀取回應
2652
				$tmp=fgets($fp, 1024);
2653
 
2654
				#debug
2655
				#var_dump($tmp);
2656
 
2657
				#debug
2658
				#var_dump(__LINE__,"got ".$tmp);
2659
 
2660
				#如果讀到 PHP_EOL
2661
				if($tmp===PHP_EOL){
2662
 
2663
					#結束讀取回應
2664
					break;	
2665
 
2666
					}#if end
2667
 
2668
				#串接回應
2669
				$result["content"]=$result["content"].$tmp;
2670
 
2671
				}#while end
2672
 
2673
			#關閉 socket
2674
			fclose($fp);	
2675
 
2676
			}#else end
2677
 
2678
		#設置執行正常
2679
		$result["status"]="true";
2680
 
2681
		#回傳結果
2682
		return $result;
2683
 
2684
		}#function unixDomainSockClient end
2685
 
2686
	/*
2687
	#函式說明:
2688
	#連線到 usr/bin/qbpwcf-usock.php 產生的  unix domain socket,運行指定的指令.
2689
	#回傳結果:
2690
	#$result["status"],"true"代表執行正常;"false"代表執行不正常.
2691
	#$result["error"],錯誤訊息陣列.
2692
	#$result["function"],當前執行的函式名稱.
2693
	#$result["argu"],使用的參數.
121 liveuser 2694
	#$result["content"],執行完指令的結果,回傳的格式為external::callShell的回傳結果.
3 liveuser 2695
	#必填參數:
2696
	#$conf["fileArgu"],字串,變數__FILE__的內容.
2697
	$conf["fileArgu"]=__FILE__;
2698
	#$conf["command"],字串,要執行的指令名稱.
2699
	$conf["command"]="";
2700
	#可省略參數:
2701
	#$conf["sock"],字串,要連線的 usr/bin/qbpwcf-sock.php(sock::unixDomainSockServer) 所產生的 unix domain socket 路徑與名稱,預設為 qbpwcf_usock_path.
2702
	#$conf["sock"]=qbpwcf_usock_path;
2703
	#$conf["argu"],陣列字串,指令搭配的參數,預設為空陣列.
2704
	#$conf["argu"]=array();
2705
	#$conf["commandIncludeArgu"],字串,是否command含有參數,預設為"false"代表沒有;反之為"true".
2706
	#$conf["commandIncludeArgu"]="false";
2707
	#$conf["commandInBg"],字串,是否要將程序放在背景執行,再取得相關資訊,預設為"false"代表不要;反之為"true".
2708
	#$conf["commandInBg"]="false";
2709
	#參考資料:
2710
	#無.
2711
	#備註:
2712
	#無.
2713
	*/
2714
	public static function execAnyCmdByQBPWCFunixSocket(&$conf){
2715
 
2716
		#初始化要回傳的結果
2717
		$result=array();
2718
 
2719
		#取得當前執行的函數名稱
2720
		$result["function"]=__FUNCTION__;
2721
 
2722
		#如果沒有參數
2723
		if(func_num_args()==0){
2724
 
2725
			#設置執行失敗
2726
			$result["status"]="false";
2727
 
2728
			#設置執行錯誤訊息
2729
			$result["error"]="函數".$result["function"]."需要參數";
2730
 
2731
			#回傳結果
2732
			return $result;
2733
 
2734
			}#if end
2735
 
2736
		#取得參數
2737
		$result["argu"]=$conf;
2738
 
2739
		#如果 $conf 不為陣列
2740
		if(gettype($conf)!="array"){
2741
 
2742
			#設置執行失敗
2743
			$result["status"]="false";
2744
 
2745
			#設置執行錯誤訊息
2746
			$result["error"][]="\$conf變數須為陣列形態";
2747
 
2748
			#如果傳入的參數為 null
2749
			if($conf==null){
2750
 
2751
				#設置執行錯誤訊息
2752
				$result["error"][]="\$conf變數不得為null,請檢查函數「".$result["function"]."」的參數設置有無正確!";
2753
 
2754
				}#if end
2755
 
2756
			#回傳結果
2757
			return $result;
2758
 
2759
			}#if end
2760
 
2761
		#檢查參數
2762
		#函式說明:
2763
		#檢查必填與可省略的參數,可省略參數可指定預設要給與什麼數值內容。
2764
		#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
2765
		#$reuslt["error"],執行不正常結束的錯訊息陣列.
2766
		#$result["function"],當前執行的函式名稱.
2767
		#$result["argu"],設置給予的參數.
2768
		#$result["passed"],識別要檢查的全體變數是否存在以及型態是否正確的變數,"true"代表檢查全部通過;"false"代表檢查不通過
2769
		#$result[$shouldBeCheckedVarName]["varExist"],所檢查的變數是否存在,"false"代表不存在;"true"代表存在
2770
		#$result[$shouldBeCheckedVarName]["varType"],所檢查的變數型態是否正確,"false"代表錯誤;"true"代表正確
2771
		#$result[$shouldBeCheckedVarName]["error"],每個參數設定的錯誤訊息
2772
		#$result["shouldNotBeEmpty"],不應該為空字串或控陣列的變數.
2773
		#$result["argu"],字串陣列,目前輸入的參數名稱陣列.
2774
		#$result["legalVarName"],字串陣列,合法可用的參數名稱陣列.
2775
		#$result["notNeedVar"],字串陣列,多餘的參數名稱.
2776
		#必填寫的參數:
2777
		#$conf["varInput"],陣列變數,要檢查的陣列變數,請在要檢查的參數前面加上&,這樣變動的結果才能被套用。
2778
		$conf["variableCheck::checkArguments"]["varInput"]=&$conf;	
2779
		#$conf["referenceVarKey"],字串,$conf參數後面的key值,用於移除不要的參考陣列.
2780
		$conf["variableCheck::checkArguments"]["referenceVarKey"]="variableCheck::checkArguments";
2781
		#可以省略的參數:
2782
		#$conf["mustBeFilledVariableName"],爲必填參數的變數名稱陣列,形態爲陣列變數,元素數量需要跟"mustBeFilledVariableType"參數的元素數量一致,例如: $conf["mustBeFilledVariableName"] = array("id","account","password");
2783
		$conf["variableCheck::checkArguments"]["mustBeFilledVariableName"]=array("fileArgu","command");
2784
		#$conf["mustBeFilledVariableType"],爲必填參數的變數陣列應該爲何種變數形態,形態爲陣列,元素數量需要跟"mustBeFilledVariableName"參數的元素數量一致,例如: $conf["mustBeFilledVariableType"] = array("string",integer,"double","resource","object"); , null代表不指定變數形態.
2785
		$conf["variableCheck::checkArguments"]["mustBeFilledVariableType"]=array("string","string");
2786
		#$conf["canBeEmptyString"],字串,必填變數內容如果是空字串就不能算是有設置的話,請設為"false",預設爲"true",可以為空字串.
2787
		#$conf["canBeEmptyString"]="false";
2788
		#$conf["canNotBeEmpty"],字串陣列,哪些必填參數的內容不得為空字串或空陣列,僅當$conf["canBeEmptyString"]為"true"時會生效.
2789
		#$conf["canNotBeEmpty"]=array();
2790
		#$conf["canBeEmpty"],字串陣列,哪些必填參數的內容可為空字串或空陣列,僅當$conf["canBeEmptyString"]為"false"時會生效.
2791
		#$conf["canBeEmpty"]=array();
2792
		#$conf["skipableVariableCanNotBeEmpty"],字串陣列,哪些可省略參數不可以為空字串或空陣列.
2793
		$conf["variableCheck::checkArguments"]["skipableVariableCanNotBeEmpty"]=array("sock");
2794
		#$conf["skipableVariableName"],陣列字串,爲可省略參數的變數名稱陣列,形態爲陣列變數,例如: $conf["skipableVariableName"] = array("id","account","password");
2795
		$conf["variableCheck::checkArguments"]["skipableVariableName"]=array("sock","argu","commandIncludeArgu","commandInBg");
2796
		#$conf["skipableVariableType"],陣列字串,爲可省略參數的變數名稱陣列,形態爲陣列變數,例如: $conf["skipableVariableType"] = array("string",integer,"double"); 
2797
		$conf["variableCheck::checkArguments"]["skipableVariableType"]=array("string","array","string","string");
2798
		#$conf["skipableVarDefaultValue"],字串陣列,每個不存在的可省略變數要初始化為什麼,null與代表不指定,若預設值是參數之一,請將$conf["mustBeFilledVar"]改成"\$conf["\mustBeFilledVar\"]".
2799
		$conf["variableCheck::checkArguments"]["skipableVarDefaultValue"]=array(qbpwcf_usock_path,array(),"false","false");
2800
		#$conf["disallowAllSkipableVarIsEmpty"],字串,是否允許每個可省略參數都為空字串,預設為"true"允許,反之為"false".
2801
		#$conf["disallowAllSkipableVarIsEmpty"]="";
2802
		#$conf["disallowAllSkipableVarIsEmptyArray"],字串,是否允許每個可省略參數都為空陣列,預設為"true"允許,反之為"false".
2803
		#$conf["disallowAllSkipableVarIsEmptyArray"]="";
2804
		#$conf["arrayCountEqualCheck"],字串陣列,為檢查哪些陣列參數的元素數量要一樣,$conf["arrayCountEqualCheck"][$i]=array()為第$i組key為哪些的變數其元素數量要相等.
2805
		#$conf["arrayCountEqualCheck"][]=array();
2806
		#參考資料來源:
2807
		#array_keys=>http://php.net/manual/en/function.array-keys.php
2808
		$checkArguments=variableCheck::checkArguments($conf["variableCheck::checkArguments"]);
2809
		unset($conf["variableCheck::checkArguments"]);
2810
 
2811
		#如果檢查參數失敗
2812
		if($checkArguments["status"]==="false"){
2813
 
2814
			#設置執行失敗
2815
			$result["status"]="false";
2816
 
2817
			#設置錯誤訊息
2818
			$result["error"]=$checkArguments;
2819
 
2820
			#回傳結果
2821
			return $result;
2822
 
2823
			}#if end
2824
 
2825
		#如果檢查參數不通過
2826
		if($checkArguments["passed"]==="false"){
2827
 
2828
			#設置執行失敗
2829
			$result["status"]="false";
2830
 
2831
			#設置錯誤訊息
2832
			$result["error"]=$checkArguments;
2833
 
2834
			#回傳結果
2835
			return $result;
2836
 
2837
			}#if end
2838
 
2839
		#如果指令已經包含參數了
2840
		if($conf["commandIncludeArgu"]==="true"){
2841
 
2842
			#函式說明:
2843
			#將指令字串解析成陣列,方便給予 external::callShell 使用 
2844
			#回傳結果:
2845
			#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
2846
			#$reuslt["error"],執行不正常結束的錯訊息陣列.
2847
			#$result["function"],當前執行的函式名稱.
2848
			#$result["content"],解析好的指令陣列.
2849
			#$result["cmd"],解析好的指令名稱.
2850
			#$result["argus"],解析好的參數陣列.
2851
			#$result["argu"],所使用的參數.
2852
			#必填參數
2853
			#$conf["cmdStr"],字串,要解析的指令字串
2854
			$conf["cmd::parseCmdString"]["cmdStr"]=$conf["command"];
2855
			#可省略參數:
2856
			#無.
2857
			#參考資料:
2858
			#無.
2859
			#備註:
2860
			#無.
2861
			$parseCmdString=cmd::parseCmdString($conf["cmd::parseCmdString"]);
2862
			unset($conf["cmd::parseCmdString"]);
2863
 
2864
			#debug
220 liveuser 2865
			#var_dump(__FUNCTION__,__LINE__,$parseCmdString);exit;
3 liveuser 2866
 
2867
			#如果執行失敗
2868
			if($parseCmdString["status"]==="false"){
2869
 
2870
				#設置執行失敗
2871
				$result["status"]="false";
2872
 
2873
				#設置錯誤訊息
2874
				$result["error"]=$parseCmdString;
2875
 
2876
				#回傳結果
2877
				return $result;
2878
 
2879
				}#if end
2880
 
2881
			#取得解析好的指令名稱
2882
			$conf["command"]=$parseCmdString["cmd"];
2883
 
2884
			#取得解析好的參數陣列
2885
			$conf["argu"]=$parseCmdString["argus"];
2886
 
2887
			#debug
2888
			#var_dump(__LINE__,$parseCmdString);
2889
 
2890
			}#if end
2891
 
2892
		#函式說明:
2893
		#呼叫shell執行系統命令,並取得回傳的內容.
2894
		#回傳結果:
2895
		#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
2896
		#$result["error"],錯誤訊息陣列.
2897
		#$result["function"],當前執行的函數名稱.
2898
		#$result["argu"],使用的參數.
2899
		#$result["cmd"],執行的指令內容.
2900
		#$result["fullCmd"],如果參數 $conf["inBackGround"] 為 "true" 則會回傳該值.
2901
		#$result["output"],爲執行完二元碼後的輸出陣列,若 $conf["inBackGround"] 為 "true",則為當下的輸出.
2902
		#$result["tmpFileOutput"],儲存輸出的暫存檔案名稱,若 $conf["inBackGround"] 為 "true" 則會回傳該值.
2903
		#$result["running"],是否還在執行.
2904
		#$result["pid"],pid.
2905
		#$result["statusCode"],執行結束後的代碼.
2906
		#$result["escape"],陣列,儲存重新排序過且已經escape過的指令(key為"cmd")與參數(key為"argu").
2907
		#必填參數:
2908
		#$conf["command"],字串,要執行的指令.
2909
		$conf["external::callShell"]["command"]=$conf["command"];
2910
		#$conf["fileArgu"],字串,變數__FILE__的內容.
2911
		$conf["external::callShell"]["fileArgu"]=$conf["fileArgu"];
2912
		#可省略參數:
2913
		#$conf["argu"],陣列字串,指令搭配的參數,預設為空陣列.
2914
		$conf["external::callShell"]["argu"]=$conf["argu"];
2915
		#$conf["arguIsAddr"],陣列字串,指令搭配的哪些參數為路徑,為路徑的參數會進行轉換以便符合呼叫當前函數的位置,預設不指定,若有3個參數,其中第3個參數為路徑,則表示為array("false","false","true").
2916
		#$conf["arguIsAddr"]=array();
2917
		#$conf["pre"],陣列,要在本指令前執行的每個指令與參數.
2918
		#$conf["pre"][$i]["cmd"],字串,要在本指令前執行的第$i+1個指令.
2919
		#$conf["pre"][$i]["param"],陣列字串,要在本指令前執行的第$i+1個指令的參數.
2920
		#$conf["enablePrintDescription"],字串,是否要印出$conf["printDescription"]的內容,"true"代表要,"false"代表不要,預設為"false".
2921
		#$conf["enablePrintDescription"]="true";
2922
		#$conf["printDescription"],字串,執行該外部程式前要印出來的的文字,預設為$conf["command"]的內容加上使用的$conf["argu"]參數.
2923
		#$conf["printDescription"]="";
2924
		#$conf["escapeshellarg"],字串,是否要啟用過濾參數,用了比較安全,但可能會出錯,"true"為啟用,"false"為不啟用,預設為"false".如果參數為"< 、<< 、> 、>> 、| 、2>&1"之一則不會過濾.
2925
		$conf["external::callShell"]["escapeshellarg"]="true";
2926
		#$conf["thereIsShellVar"],陣列字串,指令搭配的參數"argu",若含有「\'」,則取代為「"」.每個argu參數都要有對應的元素."true"代表要置換.
2927
		#$conf["thereIsShellVar"]=array();
2928
		#$conf["username"],字串,要用什麼使用者來執行,預設為執行php的使用者,該參數不適用於apache環境.
2929
		#$conf["username"]="";
2930
		#$conf["password"],字串,root的使用者密碼,預設不使用密碼,該參數不適用於apache環境.
2931
		#$conf["password"]="";
2932
		#$conf["useScript"],字串,是否要啟用Linux的script指令來記錄輸出,"true"代表要,Fedora的selinux會擋住該操作;"false"代表不要,預設為"false".
2933
		#$conf["useScript"]="";
2934
		#$conf["logFilePath"],字串,當 $conf["useScript"] 為 "true" 時,輸出的內容要暫存到哪裡,預設為 "/tmp/.qbpwcf_tmp/external/callShell/".
2935
		#$conf["logFilePath"]=".qbpwcf_tmp/external/callShell/";
2936
		#$conf["inBackGround"],字串,是否要在背景執行,且不會等待程式執行結束再執行下一個指令,"true"代表是,"false"代表不要,預設為"false",如果$conf["command"]有用「;」區隔的多個指令將會出錯.
2937
		#$conf["inBackGround"]="";
2938
		#$conf["getErr"],字串,"true"代表將錯誤輸出變成標準輸出,反之"false"為不變動.
2939
		#$conf["getErr"]="false";
2940
		#$conf["doNotRun"],字串,"true"代表不執行指令,預設為"false"會執行指令.
2941
		$conf["external::callShell"]["doNotRun"]="true";
2942
		#參考資料:
2943
		#exec=>http://php.net/manual/en/function.exec.php
2944
		#escapeshellcmd=>http://php.net/manual/en/function.escapeshellcmd.php
2945
		#escapeshellarg=>http://php.net/manual/en/function.escapeshellarg.php
2946
		#備註:
2947
		#不是所有指令都能用apache的身份執行,目前已知java,javac指令無法執行,使用root身份可能會被selinux阻擋.
2948
		#若使用的 command、argu 參數,含有 ~ 則會被視為字串,若有需要其於 shell 中代表的家目錄位置,可用 fileAccess::tildeToPath 來進行轉換.
2949
		$callShell=external::callShell($conf["external::callShell"]);
2950
		unset($conf["external::callShell"]);
2951
 
2952
		#debug
2953
		#var_dump(__LINE__,$callShell);
2954
 
2955
		#如果檢查參數作業出錯
2956
		if($callShell["status"]=="false"){
2957
 
2958
			#設置執行錯誤識別
2959
			$result["status"]="false";
2960
 
2961
			#設置錯誤訊息
2962
			$result["error"]=$callShell;
2963
 
2964
			#回傳結果
2965
			return $result;
2966
 
2967
			}#if end
2968
 
2969
		#函式說明:
2970
		#連線到 unixDomainSockServer 提供的 unix domain socket.
2971
		#回傳結果:
2972
		#$result["status"],"true"代表執行正常;"false"代表執行不正常.
2973
		#$result["error"],錯誤訊息陣列.
2974
		#$result["function"],當前執行的函式名稱.
2975
		#$result["content"],取得的回應.
2976
		#必填參數:
2977
		#$conf["sock"],字串,要連線的unix domain socket.
2978
		$conf["sock::unixDomainSockClient"]["sock"]=$conf["sock"];
2979
		#可省略參數:
2980
		#$conf["id"],字串,取得的id,若無此值,則會得到新的數值.
2981
		#$conf["id"]="";
2982
		#$conf["cmd"],字串,要執行的指令,當$conf["id"]參數合法時,才會執行.
2983
		$conf["sock::unixDomainSockClient"]["cmd"]=$callShell["escape"]["cmd"];
2984
		#$conf["param"],參數陣列.
2985
		$conf["sock::unixDomainSockClient"]["param"]=$callShell["escape"]["argu"];
2986
		#$conf["escaped"],字串,param參數是否已經escaped了,預設為"false",反之為"true".
2987
		$conf["sock::unixDomainSockClient"]["escaped"]="true";
2988
		#$conf["custom"],陣列,要客制化傳輸的內容,會覆蓋以上除了$conf["id"]以外的可省略參數.
2989
 
2990
		#如果要在背景執行指令
2991
		if($conf["commandInBg"]==="true" && isset($conf["sock::unixDomainSockClient"]["cmd"]) ){
2992
 
2993
			#設定要在背景執行的指令
2994
			$conf["sock::unixDomainSockClient"]["custom"]["cmdInBg"]=$conf["sock::unixDomainSockClient"]["cmd"];
2995
 
2996
			#設定要在背景執行的指令
2997
			$conf["sock::unixDomainSockClient"]["custom"]["param"]=$conf["sock::unixDomainSockClient"]["param"];
2998
 
2999
			#移除不要的參數
3000
			unset($conf["sock::unixDomainSockClient"]["cmd"]);
3001
 
3002
			#移除不要的參數
3003
			unset($conf["sock::unixDomainSockClient"]["param"]);
3004
 
3005
			#保存 custom 參數
3006
			$custom=$conf["sock::unixDomainSockClient"]["custom"];
3007
 
3008
			#debug
3009
			#var_dump(__LINE__,$custom);
3010
 
3011
			}#if end
3012
 
3013
		#$conf["raw"],字串,要直接傳送的字串內容,會忽略其他可省略參數.
3014
		#$conf["raw"]="";
3015
		#參考資料:
3016
		#http://php.net/manual/en/function.stream-socket-client.php
3017
		#http://php.net/manual/en/function.stream-get-contents.php
3018
		#備註:
3019
		#無.
3020
		$paramsOfUnixDomainSockClient=$conf["sock::unixDomainSockClient"];
3021
		$unixDomainSockClient=sock::unixDomainSockClient($paramsOfUnixDomainSockClient);
3022
		unset($paramsOfUnixDomainSockClient);
3023
 
3024
		#如果執行失敗
3025
		if($unixDomainSockClient["status"]==="false"){
3026
 
3027
			#設置執行錯誤識別
3028
			$result["status"]="false";
3029
 
3030
			#設置錯誤訊息
3031
			$result["error"]=$unixDomainSockClient;
3032
 
3033
			#回傳結果
3034
			return $result;
3035
 
3036
			}#if end
3037
 
3038
		#debug
3039
		#var_dump(__LINE__,$unixDomainSockClient);
3040
 
3041
		#如果不是 json 字串
3042
		if(json_validate(trim($unixDomainSockClient["content"]))==="false"){
3043
 
3044
			#設置執行錯誤識別
3045
			$result["status"]="false";
3046
 
3047
			#設置錯誤訊息
3048
			$result["error"][]=trim($unixDomainSockClient["content"])." is not json string!";
3049
 
3050
			#設置錯誤訊息
3051
			$result["error"][]=$unixDomainSockClient;
3052
 
3053
			#回傳結果
3054
			return $result;
3055
 
3056
			}#if end
3057
 
3058
		#取得json回應
3059
		$jsonRes=json_decode(trim($unixDomainSockClient["content"]));
3060
 
3061
		#debug
3062
		#var_dump(__LINE__,$jsonRes);
3063
 
3064
		#如果執行失敗
3065
		if($jsonRes===null){
3066
 
3067
			#設置執行錯誤識別
3068
			$result["status"]="false";
3069
 
3070
			#設置錯誤訊息
3071
			$result["error"]=$unixDomainSockClient;
3072
 
3073
			#回傳結果
3074
			return $result;
3075
 
3076
			}#if end
3077
 
3078
		#如果沒有產生新id
3079
		if(!isset($jsonRes->id)){
3080
 
3081
			#設置執行錯誤識別
3082
			$result["status"]="false";
3083
 
3084
			#設置錯誤訊息
3085
			$result["error"]=$unixDomainSockClient;
3086
 
3087
			#回傳結果
3088
			return $result;
3089
 
3090
			}#if end
3091
 
3092
		#用新的id再傳送一次要求給 qbpwcf_usock_path
3093
		$paramsOfUnixDomainSockClient=$conf["sock::unixDomainSockClient"];
3094
		$paramsOfUnixDomainSockClient["id"]=$jsonRes->id;
3095
		#var_dump(__LINE__,$paramsOfUnixDomainSockClient);
3096
		$unixDomainSockClient=sock::unixDomainSockClient($paramsOfUnixDomainSockClient);
3097
		unset($paramsOfUnixDomainSockClient);
3098
 
3099
		#如果執行失敗
3100
		if($unixDomainSockClient["status"]==="false"){
3101
 
3102
			#設置執行錯誤識別
3103
			$result["status"]="false";
3104
 
3105
			#設置錯誤訊息
3106
			$result["error"]=$unixDomainSockClient;
3107
 
3108
			#回傳結果
3109
			return $result;
3110
 
3111
			}#if end
3112
 
3113
		#debug
3114
		#var_dump(__LINE__,$unixDomainSockClient["content"]);
3115
 
3116
		#如果輸出非 json 
3117
		if(json_validate(trim($unixDomainSockClient["content"]))===false){
3118
 
3119
			#設置錯誤識別
3120
			$result["status"]="false";
3121
 
3122
			#設置錯誤訊息
3123
			$result["error"][]="got not json output";
3124
 
3125
			#設置錯誤訊息
3126
			$result["error"][]=json_last_error().":".json_last_error_msg();
3127
 
3128
			#回傳結果
3129
			return $result;
3130
 
3131
			}#if end
3132
 
3133
		#取得json回應
3134
		$jsonRes=(array)json_decode($unixDomainSockClient["content"]);
3135
 
3136
		#如果執行失敗
3137
		if($jsonRes===null){
3138
 
3139
			#設置執行錯誤識別
3140
			$result["status"]="false";
3141
 
3142
			#設置錯誤訊息
3143
			$result["error"]=$unixDomainSockClient;
3144
 
3145
			#回傳結果
3146
			return $result;
3147
 
3148
			}#if end
3149
 
3150
		#如果執行指令失敗
3151
		if($jsonRes["status"]==="false"){
3152
 
3153
			#設置執行錯誤識別
3154
			$result["status"]="false";
3155
 
3156
			#設置錯誤訊息
3157
			$result["error"]=$jsonRes["error"];
3158
 
3159
			#回傳結果
3160
			return $result;
3161
 
3162
			}#if end
3163
 
3164
		#執行正常
3165
		$result["status"]="true";
3166
 
3167
		#設置執行的結果
3168
		$result["content"]=$jsonRes;
3169
 
3170
		#回傳結果
3171
		return $result;
3172
 
3173
		}#public function execAnyCmdByQBPWCFunixSocket end
3174
 
3175
	/*
3176
	#函式說明:
3177
	#詢問透過 sock::unixDomainSockServer 執行的程序狀況
3178
	#回傳結果:
3179
	#$result["status"],"true"代表執行正常;"false"代表執行不正常.
3180
	#$result["error"],錯誤訊息陣列.
3181
	#$result["function"],當前執行的函式名稱.
3182
	#$result["argu"],使用的參數.
3183
	#$result["content"],陣列,程序的資訊.
3184
	#$result["content"]["pid"],字串,程序的pid.
3185
	#$result["content"]["running"],字串,是否正常執行中.
3186
	#$result["content"]["statusCode"],字串,回傳給 shell 的代碼.
3187
	#$result["content"]["input"],字串,輸入的內容.
3188
	#$result["content"]["output"],字串,標準輸出的內容.
3189
	#$result["content"]["error"],字串,錯誤輸出的內容.
3190
	#必填參數:
3191
	#$conf["uuid"],字串,proc的uuid.
3192
	$conf["uuid"]="";
3193
	#可省略參數:
3194
	#$conf["sock"],字串,要連線的 usr/bin/qbpwcf-sock.php(sock::unixDomainSockServer) 所產生的 unix domain socket 路徑與名稱,預設為 qbpwcf_usock_path.
3195
	#$conf["sock"]=qbpwcf_usock_path;
3196
	#參考資料:
3197
	#無.
3198
	#備註:
3199
	#無.
3200
	*/
3201
	public static function getProcInfo(&$conf){
3202
 
3203
		#初始化要回傳的結果
3204
		$result=array();
3205
 
3206
		#取得當前執行的函數名稱
3207
		$result["function"]=__FUNCTION__;
3208
 
3209
		#如果沒有參數
3210
		if(func_num_args()==0){
3211
 
3212
			#設置執行失敗
3213
			$result["status"]="false";
3214
 
3215
			#設置執行錯誤訊息
3216
			$result["error"]="函數".$result["function"]."需要參數";
3217
 
3218
			#回傳結果
3219
			return $result;
3220
 
3221
			}#if end
3222
 
3223
		#取得參數
3224
		$result["argu"]=$conf;
3225
 
3226
		#如果 $conf 不為陣列
3227
		if(gettype($conf)!="array"){
3228
 
3229
			#設置執行失敗
3230
			$result["status"]="false";
3231
 
3232
			#設置執行錯誤訊息
3233
			$result["error"][]="\$conf變數須為陣列形態";
3234
 
3235
			#如果傳入的參數為 null
3236
			if($conf==null){
3237
 
3238
				#設置執行錯誤訊息
3239
				$result["error"][]="\$conf變數不得為null,請檢查函數「".$result["function"]."」的參數設置有無正確!";
3240
 
3241
				}#if end
3242
 
3243
			#回傳結果
3244
			return $result;
3245
 
3246
			}#if end
3247
 
3248
		#檢查參數
3249
		#函式說明:
3250
		#檢查必填與可省略的參數,可省略參數可指定預設要給與什麼數值內容。
3251
		#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
3252
		#$reuslt["error"],執行不正常結束的錯訊息陣列.
3253
		#$result["function"],當前執行的函式名稱.
3254
		#$result["argu"],設置給予的參數.
3255
		#$result["passed"],識別要檢查的全體變數是否存在以及型態是否正確的變數,"true"代表檢查全部通過;"false"代表檢查不通過
3256
		#$result[$shouldBeCheckedVarName]["varExist"],所檢查的變數是否存在,"false"代表不存在;"true"代表存在
3257
		#$result[$shouldBeCheckedVarName]["varType"],所檢查的變數型態是否正確,"false"代表錯誤;"true"代表正確
3258
		#$result[$shouldBeCheckedVarName]["error"],每個參數設定的錯誤訊息
3259
		#$result["shouldNotBeEmpty"],不應該為空字串或控陣列的變數.
3260
		#$result["argu"],字串陣列,目前輸入的參數名稱陣列.
3261
		#$result["legalVarName"],字串陣列,合法可用的參數名稱陣列.
3262
		#$result["notNeedVar"],字串陣列,多餘的參數名稱.
3263
		#必填寫的參數:
3264
		#$conf["varInput"],陣列變數,要檢查的陣列變數,請在要檢查的參數前面加上&,這樣變動的結果才能被套用。
3265
		$conf["variableCheck::checkArguments"]["varInput"]=&$conf;	
3266
		#$conf["referenceVarKey"],字串,$conf參數後面的key值,用於移除不要的參考陣列.
3267
		$conf["variableCheck::checkArguments"]["referenceVarKey"]="variableCheck::checkArguments";
3268
		#可以省略的參數:
3269
		#$conf["mustBeFilledVariableName"],爲必填參數的變數名稱陣列,形態爲陣列變數,元素數量需要跟"mustBeFilledVariableType"參數的元素數量一致,例如: $conf["mustBeFilledVariableName"] = array("id","account","password");
3270
		$conf["variableCheck::checkArguments"]["mustBeFilledVariableName"]=array("uuid");
3271
		#$conf["mustBeFilledVariableType"],爲必填參數的變數陣列應該爲何種變數形態,形態爲陣列,元素數量需要跟"mustBeFilledVariableName"參數的元素數量一致,例如: $conf["mustBeFilledVariableType"] = array("string",integer,"double","resource","object"); , null代表不指定變數形態.
3272
		$conf["variableCheck::checkArguments"]["mustBeFilledVariableType"]=array("string");
3273
		#$conf["canBeEmptyString"],字串,必填變數內容如果是空字串就不能算是有設置的話,請設為"false",預設爲"true",可以為空字串.
3274
		#$conf["canBeEmptyString"]="false";
3275
		#$conf["canNotBeEmpty"],字串陣列,哪些必填參數的內容不得為空字串或空陣列,僅當$conf["canBeEmptyString"]為"true"時會生效.
3276
		#$conf["canNotBeEmpty"]=array();
3277
		#$conf["canBeEmpty"],字串陣列,哪些必填參數的內容可為空字串或空陣列,僅當$conf["canBeEmptyString"]為"false"時會生效.
3278
		#$conf["canBeEmpty"]=array();
3279
		#$conf["skipableVariableCanNotBeEmpty"],字串陣列,哪些可省略參數不可以為空字串或空陣列.
3280
		$conf["variableCheck::checkArguments"]["skipableVariableCanNotBeEmpty"]=array("sock");
3281
		#$conf["skipableVariableName"],陣列字串,爲可省略參數的變數名稱陣列,形態爲陣列變數,例如: $conf["skipableVariableName"] = array("id","account","password");
3282
		$conf["variableCheck::checkArguments"]["skipableVariableName"]=array("sock");
3283
		#$conf["skipableVariableType"],陣列字串,爲可省略參數的變數名稱陣列,形態爲陣列變數,例如: $conf["skipableVariableType"] = array("string",integer,"double"); 
3284
		$conf["variableCheck::checkArguments"]["skipableVariableType"]=array("string");
3285
		#$conf["skipableVarDefaultValue"],字串陣列,每個不存在的可省略變數要初始化為什麼,null與代表不指定,若預設值是參數之一,請將$conf["mustBeFilledVar"]改成"\$conf["\mustBeFilledVar\"]".
3286
		$conf["variableCheck::checkArguments"]["skipableVarDefaultValue"]=array(qbpwcf_usock_path);
3287
		#$conf["disallowAllSkipableVarIsEmpty"],字串,是否允許每個可省略參數都為空字串,預設為"true"允許,反之為"false".
3288
		#$conf["disallowAllSkipableVarIsEmpty"]="";
3289
		#$conf["disallowAllSkipableVarIsEmptyArray"],字串,是否允許每個可省略參數都為空陣列,預設為"true"允許,反之為"false".
3290
		#$conf["disallowAllSkipableVarIsEmptyArray"]="";
3291
		#$conf["arrayCountEqualCheck"],字串陣列,為檢查哪些陣列參數的元素數量要一樣,$conf["arrayCountEqualCheck"][$i]=array()為第$i組key為哪些的變數其元素數量要相等.
3292
		#$conf["arrayCountEqualCheck"][]=array();
3293
		#參考資料來源:
3294
		#array_keys=>http://php.net/manual/en/function.array-keys.php
3295
		$checkArguments=variableCheck::checkArguments($conf["variableCheck::checkArguments"]);
3296
		unset($conf["variableCheck::checkArguments"]);
3297
 
3298
		#如果檢查參數失敗
3299
		if($checkArguments["status"]==="false"){
3300
 
3301
			#設置執行失敗
3302
			$result["status"]="false";
3303
 
3304
			#設置錯誤訊息
3305
			$result["error"]=$checkArguments;
3306
 
3307
			#回傳結果
3308
			return $result;
3309
 
3310
			}#if end
3311
 
3312
		#如果檢查參數不通過
3313
		if($checkArguments["passed"]==="false"){
3314
 
3315
			#設置執行失敗
3316
			$result["status"]="false";
3317
 
3318
			#設置錯誤訊息
3319
			$result["error"]=$checkArguments;
3320
 
3321
			#回傳結果
3322
			return $result;
3323
 
3324
			}#if end
3325
 
3326
		函式說明:
3327
		#連線到 unixDomainSockServer 提供的 unix domain socket.
3328
		#回傳結果:
3329
		#$result["status"],"true"代表執行正常;"false"代表執行不正常.
3330
		#$result["error"],錯誤訊息陣列.
3331
		#$result["function"],當前執行的函式名稱.
3332
		#$result["content"],取得的回應.
3333
		#必填參數:
3334
		#$conf["sock"],字串,要連線的unix domain socket.
3335
		$conf["sock::unixDomainSockClient"]["sock"]=$conf["sock"];
3336
		#可省略參數:
3337
		#$conf["id"],字串,取得的id,若無此值,則會得到新的數值.
3338
		#$conf["id"]="";
3339
		#$conf["cmd"],字串,要執行的指令,當$conf["id"]參數合法時,才會執行.
3340
		#$conf["cmd"]="";
3341
		#$conf["param"],參數陣列.
3342
		#$conf["param"]=array();
3343
		#$conf["escaped"],字串,param參數是否已經escaped了,預設為"false",反之為"true".
3344
		#$conf["escaped"]="true";
3345
		#$conf["custom"],陣列,要客制化傳輸的內容,會覆蓋以上除了$conf["id"]以外的可省略參數.
3346
		$conf["sock::unixDomainSockClient"]["custom"]=array("QueryProcByUUID"=>$conf["uuid"]);
3347
		#$conf["raw"],字串,要直接傳送的字串內容,會忽略其他可省略參數.
3348
		#$conf["raw"]="";
3349
		#參考資料:
3350
		#http://php.net/manual/en/function.stream-socket-client.php
3351
		#http://php.net/manual/en/function.stream-get-contents.php
3352
		#備註:
3353
		#無.
3354
		$paramsOfUnixDomainSockClient=$conf["sock::unixDomainSockClient"];
3355
		$unixDomainSockClient=sock::unixDomainSockClient($paramsOfUnixDomainSockClient);
3356
		unset($paramsOfUnixDomainSockClient);
3357
 
3358
		#如果執行失敗
3359
		if($unixDomainSockClient["status"]==="false"){
3360
 
3361
			#設置執行錯誤識別
3362
			$result["status"]="false";
3363
 
3364
			#設置錯誤訊息
3365
			$result["error"]=$unixDomainSockClient;
3366
 
3367
			#回傳結果
3368
			return $result;
3369
 
3370
			}#if end
3371
 
3372
		#debug
3373
		#var_dump(__LINE__,$unixDomainSockClient);
3374
 
3375
		#如果不是 json 字串
3376
		if(json_validate(trim($unixDomainSockClient["content"]))==="false"){
3377
 
3378
			#設置執行錯誤識別
3379
			$result["status"]="false";
3380
 
3381
			#設置錯誤訊息
3382
			$result["error"][]=trim($unixDomainSockClient["content"])." is not json string!";
3383
 
3384
			#設置錯誤訊息
3385
			$result["error"][]=$unixDomainSockClient;
3386
 
3387
			#回傳結果
3388
			return $result;
3389
 
3390
			}#if end
3391
 
3392
		#取得json回應
3393
		$jsonRes=json_decode(trim($unixDomainSockClient["content"]));
3394
 
3395
		#debug
3396
		#var_dump(__LINE__,$jsonRes);
3397
 
3398
		#如果執行失敗
3399
		if($jsonRes===null){
3400
 
3401
			#設置執行錯誤識別
3402
			$result["status"]="false";
3403
 
3404
			#設置錯誤訊息
3405
			$result["error"]=$unixDomainSockClient;
3406
 
3407
			#回傳結果
3408
			return $result;
3409
 
3410
			}#if end
3411
 
3412
		#如果沒有產生新id
3413
		if(!isset($jsonRes->id)){
3414
 
3415
			#設置執行錯誤識別
3416
			$result["status"]="false";
3417
 
3418
			#設置錯誤訊息
3419
			$result["error"]=$unixDomainSockClient;
3420
 
3421
			#回傳結果
3422
			return $result;
3423
 
3424
			}#if end
3425
 
3426
		#用新的id再傳送一次要求給 qbpwcf_usock_path
3427
		$paramsOfUnixDomainSockClient=$conf["sock::unixDomainSockClient"];
3428
		$paramsOfUnixDomainSockClient["id"]=$jsonRes->id;
3429
		$unixDomainSockClient=sock::unixDomainSockClient($paramsOfUnixDomainSockClient);
3430
		unset($paramsOfUnixDomainSockClient);
3431
 
3432
		#如果執行失敗
3433
		if($unixDomainSockClient["status"]==="false"){
3434
 
3435
			#設置執行錯誤識別
3436
			$result["status"]="false";
3437
 
3438
			#設置錯誤訊息
3439
			$result["error"]=$unixDomainSockClient;
3440
 
3441
			#回傳結果
3442
			return $result;
3443
 
3444
			}#if end
3445
 
3446
		#debug
3447
		#var_dump(__LINE__,$unixDomainSockClient["content"]);
3448
 
3449
		#如果輸出非 json 
3450
		if(json_validate(trim($unixDomainSockClient["content"]))===false){
3451
 
3452
			#設置錯誤識別
3453
			$result["status"]="false";
3454
 
3455
			#設置錯誤訊息
3456
			$result["error"][]="got not json output";
3457
 
3458
			#設置錯誤訊息
3459
			$result["error"][]=json_last_error().":".json_last_error_msg();
3460
 
3461
			#設置原始訊息
3462
			$result["error"][]="ori res:".$unixDomainSockClient["content"];
3463
 
3464
			#回傳結果
3465
			return $result;
3466
 
3467
			}#if end
3468
 
3469
		#取得json回應
3470
		$jsonRes=(array)json_decode($unixDomainSockClient["content"]);
3471
 
3472
		#如果執行失敗
3473
		if($jsonRes===null){
3474
 
3475
			#設置執行錯誤識別
3476
			$result["status"]="false";
3477
 
3478
			#設置錯誤訊息
3479
			$result["error"]=$unixDomainSockClient;
3480
 
3481
			#回傳結果
3482
			return $result;
3483
 
3484
			}#if end
3485
 
3486
		#如果執行指令失敗
3487
		if($jsonRes["status"]==="false"){
3488
 
3489
			#設置執行錯誤識別
3490
			$result["status"]="false";
3491
 
3492
			#設置錯誤訊息
3493
			$result["error"]=$jsonRes["error"];
3494
 
3495
			#回傳結果
3496
			return $result;
3497
 
3498
			}#if end
3499
 
3500
		#移除不需要的元素
3501
		unset($jsonRes["status"]);
3502
 
3503
		#執行正常
3504
		$result["status"]="true";
3505
 
3506
		#$result["content"],陣列,程序的資訊.
3507
		#$result["content"]["pid"],字串,程序的pid.
3508
		#$result["content"]["running"],字串,是否正常執行中.
3509
		#$result["content"]["statusCode"],字串,回傳給 shell 的代碼.
3510
		#$result["content"]["input"],字串,輸入的內容.
3511
		#$result["content"]["output"],字串,標準輸出的內容.
3512
		#$result["content"]["error"],字串,錯誤輸出的內容.
3513
 
3514
		#初始執行的結果
3515
		$result["content"]=$jsonRes;
3516
 
3517
		#回傳結果
3518
		return $result;
3519
 
3520
		}#function getProcInfo end
3521
 
3522
	/*
3523
	#函式說明:
3524
	#傳送 raw 訊息到  unix domain socket.
3525
	#回傳結果:
3526
	#$result["status"],"true"代表執行正常;"false"代表執行不正常.
3527
	#$result["error"],錯誤訊息陣列.
3528
	#$result["function"],當前執行的函式名稱.
3529
	#$result["argu"],使用的參數.
3530
	#$result["content"],得到的回應.
3531
	#必填參數:
3532
	#$conf["msg"],字串,要傳送的訊息.
3533
	$conf["msg"]="";
3534
	#$conf["sock"],字串,要連線的的 unix domain socket 路徑與名稱
3535
	#$conf["sock"]="";
3536
	#可省略參數:
3537
	#無.
3538
	#參考資料:
3539
	#無.
3540
	#備註:
3541
	#無.
3542
	*/
3543
	public static function sendRawMsgUnixSocket(&$conf){
3544
 
3545
		#初始化要回傳的結果
3546
		$result=array();
3547
 
3548
		#取得當前執行的函數名稱
3549
		$result["function"]=__FUNCTION__;
3550
 
3551
		#如果沒有參數
3552
		if(func_num_args()==0){
3553
 
3554
			#設置執行失敗
3555
			$result["status"]="false";
3556
 
3557
			#設置執行錯誤訊息
3558
			$result["error"]="函數".$result["function"]."需要參數";
3559
 
3560
			#回傳結果
3561
			return $result;
3562
 
3563
			}#if end
3564
 
3565
		#取得參數
3566
		$result["argu"]=$conf;
3567
 
3568
		#如果 $conf 不為陣列
3569
		if(gettype($conf)!="array"){
3570
 
3571
			#設置執行失敗
3572
			$result["status"]="false";
3573
 
3574
			#設置執行錯誤訊息
3575
			$result["error"][]="\$conf變數須為陣列形態";
3576
 
3577
			#如果傳入的參數為 null
3578
			if($conf==null){
3579
 
3580
				#設置執行錯誤訊息
3581
				$result["error"][]="\$conf變數不得為null,請檢查函數「".$result["function"]."」的參數設置有無正確!";
3582
 
3583
				}#if end
3584
 
3585
			#回傳結果
3586
			return $result;
3587
 
3588
			}#if end
3589
 
3590
		#函式說明:
3591
		#檢查必填與可省略的參數,可省略參數可指定預設要給與什麼數值內容.
3592
		#回傳結果:
3593
		#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
3594
		#$result["error"],執行不正常結束的錯訊息陣列.
3595
		#$result["simpleError"],簡單表示的錯誤訊息.
3596
		#$result["function"],當前執行的函式名稱.
3597
		#$result["argu"],設置給予的參數.
3598
		#$result["passed"],識別要檢查的全體變數是否存在以及型態是否正確的變數,"true"代表檢查全部通過;"false"代表檢查不通過
3599
		#$result[$shouldBeCheckedVarName]["varExist"],所檢查的變數是否存在,"false"代表不存在;"true"代表存在
3600
		#$result[$shouldBeCheckedVarName]["varType"],所檢查的變數型態是否正確,"false"代表錯誤;"true"代表正確
3601
		#$result[$shouldBeCheckedVarName]["error"],每個參數設定的錯誤訊息
3602
		#$result["shouldNotBeEmpty"],不應該為空字串或控陣列的變數.
3603
		#$result["argu"],字串陣列,目前輸入的參數名稱陣列.
3604
		#$result["legalVarName"],字串陣列,合法可用的參數名稱陣列.
3605
		#$result["notNeedVar"],字串陣列,多餘的參數名稱.
3606
		#必填參數:
3607
		#$conf["varInput"],陣列變數,要檢查的陣列變數,請在要檢查的參數前面加上&,這樣變動的結果才能被套用。
3608
		$conf["variableCheck::checkArguments"]["varInput"]=&$conf;
3609
		#$conf["referenceVarKey"],字串,$conf參數後面的key值,用於移除不要的參考陣列.
3610
		$conf["variableCheck::checkArguments"]["referenceVarKey"]="variableCheck::checkArguments";
3611
		#可省略參數:
3612
		#$conf["mustBeFilledVariableName"],爲必填參數的變數名稱陣列,形態爲陣列變數,元素數量需要跟"mustBeFilledVariableType"參數的元素數量一致,例如: $conf["mustBeFilledVariableName"] = array("id","account","password");
3613
		$conf["variableCheck::checkArguments"]["mustBeFilledVariableName"]=array("msg","sock");
3614
		#$conf["mustBeFilledVariableType"],爲必填參數的變數陣列應該爲何種變數形態,形態爲陣列,元素數量需要跟"mustBeFilledVariableName"參數的元素數量一致,例如: $conf["mustBeFilledVariableType"] = array("string",integer,"double","resource","object"); , null代表不指定變數形態.
3615
		$conf["variableCheck::checkArguments"]["mustBeFilledVariableType"]=array("string","string");
3616
		#$conf["canBeEmptyString"],字串,必填變數內容如果是空字串就不能算是有設置的話,請設為"false",預設爲"true",可以為空字串.
3617
		#$conf["canBeEmptyString"]="false";
3618
		#$conf["canNotBeEmpty"],字串陣列,哪些必填參數的內容不得為空字串或空陣列,僅當$conf["canBeEmptyString"]為"true"時會生效.
3619
		#$conf["canNotBeEmpty"]=array();
3620
		#$conf["canBeEmpty"],字串陣列,哪些必填參數的內容可為空字串或空陣列,僅當$conf["canBeEmptyString"]為"false"時會生效.
3621
		#$conf["canBeEmpty"]=array();
3622
		#$conf["skipableVariableCanNotBeEmpty"],字串陣列,哪些可省略參數不可以為空字串或空陣列.
3623
		#$conf["variableCheck::checkArguments"]["skipableVariableCanNotBeEmpty"]=array("sock");
3624
		#$conf["skipableVariableName"],陣列字串,爲可省略參數的變數名稱陣列,形態爲陣列變數,例如: $conf["skipableVariableName"] = array("id","account","password");
3625
		#$conf["variableCheck::checkArguments"]["skipableVariableName"]=array("sock");
3626
		#$conf["skipableVariableType"],陣列字串,爲可省略參數的變數名稱陣列,形態爲陣列變數,例如: $conf["skipableVariableType"] = array("string",integer,"double");
3627
		#$conf["variableCheck::checkArguments"]["skipableVariableType"]=array("string");
3628
		#$conf["skipableVarDefaultValue"],字串陣列,每個不存在的可省略變數要初始化為什麼,null與代表不指定,若預設值是參數之一,請將$conf["mustBeFilledVar"]改成"\$conf["\mustBeFilledVar\"]".
3629
		#$conf["variableCheck::checkArguments"]["skipableVarDefaultValue"]=array(qbpwcf_usock_path);
3630
		#$conf["disallowAllSkipableVarIsEmpty"],字串,是否允許每個可省略參數都為空字串,預設為"true"允許,反之為"false".
3631
		#$conf["disallowAllSkipableVarIsEmpty"]="";
3632
		#$conf["disallowAllSkipableVarIsEmptyArray"],字串,是否允許每個可省略參數都為空陣列,預設為"true"允許,反之為"false".
3633
		#$conf["disallowAllSkipableVarIsEmptyArray"]="";
3634
		#$conf["disallowAllSkipableVarNotExist"],字串,是否不允許每個可省略參數都不存在,預設為"false"代表允許,反之為"true".
3635
		#$conf["disallowAllSkipableVarNotExist"]="";
3636
		#$conf["arrayCountEqualCheck"],字串陣列,為檢查哪些陣列參數的元素數量要一樣,$conf["arrayCountEqualCheck"][$i]=array()為第$i組key為哪些的變數其元素數量要相等.
3637
		#$conf["arrayCountEqualCheck"][]=array();
3638
		#參考資料:
3639
		#array_keys=>http://php.net/manual/en/function.array-keys.php
3640
		#備註:
3641
		#無.
3642
		$checkArguments=variableCheck::checkArguments($conf["variableCheck::checkArguments"]);
3643
		unset($conf["variableCheck::checkArguments"]);
3644
 
3645
		#如果執行失敗
3646
		if($checkArguments["status"]==="false"){
3647
 
3648
			#設置執行錯誤識別
3649
			$result["status"]="false";
3650
 
3651
			#設置錯誤訊息
3652
			$result["error"]=$checkArguments["error"];
3653
 
3654
			#回傳結果
3655
			return $result;
3656
 
3657
			}#if end
3658
 
3659
		#如果檢查不通過
3660
		if($checkArguments["status"]==="false"){
3661
 
3662
			#設置執行錯誤識別
3663
			$result["status"]="false";
3664
 
3665
			#設置錯誤訊息
3666
			$result["error"]=$checkArguments["error"];
3667
 
3668
			#回傳結果
3669
			return $result;
3670
 
3671
			}#if end
3672
 
3673
		#讓存放unix domain socket的路徑存在
3674
		#函式說明:
3675
		#確保路徑存在.
3676
		#回傳結果:
3677
		#$result["status"],執行正常與否,"true"代表正常,"false"代表不正常.
3678
		#$result["error"],錯誤訊息陣列.
3679
		#$resutl["function"],當前執行的涵式名稱.
3680
		#$result["path"],建立好的路徑字串.
3681
		#$result["fileName"],檔案名稱,若 $conf["haveFileName"] 為 "true" 則會回傳.
3682
		#$result["argu"],使用的參數.
3683
		#必填參數:
3684
		#$conf["path"],要檢查的路徑
3685
		$conf["fileAccess::validatePath"]["path"]=$conf["sock"];
3686
		#$conf["fileArgu"],字串,php變數__FILE__的內容,亦即該檔案在檔案系統的絕對路徑
3687
		$conf["fileAccess::validatePath"]["fileArgu"]=__FILE__;
3688
		#可省略參數:
3689
		#$conf["haveFileName"],字串,"true"代表有$conf["path"]檔案名稱,"false"代表$conf["path"]為純路徑,預設為"false".
3690
		$conf["fileAccess::validatePath"]["haveFileName"]="true";
3691
		#$conf["dirPermission"],字串,新建資料夾的權限設定,預設爲0770,亦即擁有者,同群組者可以讀,寫,存取,其他人無法使用.
3692
		#$conf["dirPermission"]="";
3693
		#$conf["web"],是否為檔案系統,"true"為網頁路徑,"false"為網頁系統,預設為"false".
3694
		$conf["fileAccess::validatePath"]["web"]="false";
3695
		#參考資料:
3696
		#無.
3697
		#備註:
3698
		#無.
3699
		$validatePath=fileAccess::validatePath($conf["fileAccess::validatePath"]);
3700
		unset($conf["fileAccess::validatePath"]);
3701
 
3702
		#如果執行失敗
3703
		if($validatePath["status"]==="false"){
3704
 
3705
			#設置錯誤識別
3706
			$result["status"]="false";
3707
 
3708
			#設置錯誤訊息
3709
			$result["error"]=$validatePath;
3710
 
3711
			#回傳結果
3712
			return $result;
3713
 
3714
			}#if end
3715
 
3716
		#變更 working dir
3717
		$chdir=chdir($validatePath["path"]);
3718
 
3719
		#嘗試30秒內連線到 unix domain socket
3720
		$fp=stream_socket_client("unix://".$validatePath["fileName"], $errno, $errstr, 30, STREAM_CLIENT_ASYNC_CONNECT );
3721
 
3722
		#如果開啟 unix domain socket 失敗
3723
		if(!$fp){
3724
 
3725
			#設置執行錯誤識別
3726
			$result["status"]="false";
3727
 
3728
			#設置錯誤訊息
3729
			$result["error"]=$errstr." (".$errno.")";
3730
 
3731
			#回傳結果
3732
			return $result;
3733
 
3734
			}#if end
3735
 
3736
		#傳遞訊息
3737
		$fwrite=fwrite($fp,$conf["msg"]);
3738
 
3739
		#如果傳遞失敗
3740
		if($fwrite===false){
3741
 
3742
			#關閉unix domain socket
3743
			@fclose($fp);
3744
 
3745
			#設置執行失敗
3746
			$result["status"]="false";
3747
 
3748
			#設置執行錯誤訊息
3749
			$result["error"][]="傳遞訊息(".$conf["msg"].")失敗";
3750
 
3751
			#回傳結果
3752
			return $result;
3753
 
3754
			}#if end
3755
 
3756
		#設置執行正常
3757
		$result["status"]="true";
3758
 
3759
		#回傳結果
3760
		return $result;
3761
 
3762
		}#function sendRawMsgUnixSocket
3763
 
3764
	/*
3765
	#連線到 sock::unixDomainSocketServer 產生的  unix domain socket,傳送指定的訊息.
3766
	#回傳結果:
3767
	#$result["status"],"true"代表執行正常;"false"代表執行不正常.
3768
	#$result["error"],錯誤訊息陣列.
3769
	#$result["function"],當前執行的函式名稱.
3770
	#$result["argu"],使用的參數.
3771
	#$result["content"],得到的回應.
3772
	#必填參數:
3773
	#$conf["msg"],陣列,要傳送的訊息,其主$conf["msg"]["id"],是無法指定的.
3774
	$conf["msg"]=array();
3775
	#可省略參數:
3776
	#$conf["sock"],字串,要連線的 usr/bin/qbpwcf-sock.php 所產生的 unix domain socket 路徑與名稱,預設為 qbpwcf_usock_path.
3777
	#$conf["sock"]=qbpwcf_usock_path;
3778
	#參考資料:
3779
	#無.
3780
	#備註:
3781
	#無.
3782
	*/
3783
	public static function sendAnyMsgToQBPWCFunixSocket(&$conf){
3784
 
3785
		#初始化要回傳的結果
3786
		$result=array();
3787
 
3788
		#取得當前執行的函數名稱
3789
		$result["function"]=__FUNCTION__;
3790
 
3791
		#如果沒有參數
3792
		if(func_num_args()==0){
3793
 
3794
			#設置執行失敗
3795
			$result["status"]="false";
3796
 
3797
			#設置執行錯誤訊息
3798
			$result["error"]="函數".$result["function"]."需要參數";
3799
 
3800
			#回傳結果
3801
			return $result;
3802
 
3803
			}#if end
3804
 
3805
		#取得參數
3806
		$result["argu"]=$conf;
3807
 
3808
		#如果 $conf 不為陣列
3809
		if(gettype($conf)!="array"){
3810
 
3811
			#設置執行失敗
3812
			$result["status"]="false";
3813
 
3814
			#設置執行錯誤訊息
3815
			$result["error"][]="\$conf變數須為陣列形態";
3816
 
3817
			#如果傳入的參數為 null
3818
			if($conf==null){
3819
 
3820
				#設置執行錯誤訊息
3821
				$result["error"][]="\$conf變數不得為null,請檢查函數「".$result["function"]."」的參數設置有無正確!";
3822
 
3823
				}#if end
3824
 
3825
			#回傳結果
3826
			return $result;
3827
 
3828
			}#if end
3829
 
3830
		#函式說明:
3831
		#檢查必填與可省略的參數,可省略參數可指定預設要給與什麼數值內容.
3832
		#回傳結果:
3833
		#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
3834
		#$result["error"],執行不正常結束的錯訊息陣列.
3835
		#$result["simpleError"],簡單表示的錯誤訊息.
3836
		#$result["function"],當前執行的函式名稱.
3837
		#$result["argu"],設置給予的參數.
3838
		#$result["passed"],識別要檢查的全體變數是否存在以及型態是否正確的變數,"true"代表檢查全部通過;"false"代表檢查不通過
3839
		#$result[$shouldBeCheckedVarName]["varExist"],所檢查的變數是否存在,"false"代表不存在;"true"代表存在
3840
		#$result[$shouldBeCheckedVarName]["varType"],所檢查的變數型態是否正確,"false"代表錯誤;"true"代表正確
3841
		#$result[$shouldBeCheckedVarName]["error"],每個參數設定的錯誤訊息
3842
		#$result["shouldNotBeEmpty"],不應該為空字串或控陣列的變數.
3843
		#$result["argu"],字串陣列,目前輸入的參數名稱陣列.
3844
		#$result["legalVarName"],字串陣列,合法可用的參數名稱陣列.
3845
		#$result["notNeedVar"],字串陣列,多餘的參數名稱.
3846
		#必填參數:
3847
		#$conf["varInput"],陣列變數,要檢查的陣列變數,請在要檢查的參數前面加上&,這樣變動的結果才能被套用。
3848
		$conf["variableCheck::checkArguments"]["varInput"]=&$conf;
3849
		#$conf["referenceVarKey"],字串,$conf參數後面的key值,用於移除不要的參考陣列.
3850
		$conf["variableCheck::checkArguments"]["referenceVarKey"]="variableCheck::checkArguments";
3851
		#可省略參數:
3852
		#$conf["mustBeFilledVariableName"],爲必填參數的變數名稱陣列,形態爲陣列變數,元素數量需要跟"mustBeFilledVariableType"參數的元素數量一致,例如: $conf["mustBeFilledVariableName"] = array("id","account","password");
3853
		$conf["variableCheck::checkArguments"]["mustBeFilledVariableName"]=array("msg");
3854
		#$conf["mustBeFilledVariableType"],爲必填參數的變數陣列應該爲何種變數形態,形態爲陣列,元素數量需要跟"mustBeFilledVariableName"參數的元素數量一致,例如: $conf["mustBeFilledVariableType"] = array("string",integer,"double","resource","object"); , null代表不指定變數形態.
3855
		$conf["variableCheck::checkArguments"]["mustBeFilledVariableType"]=array("array");
3856
		#$conf["canBeEmptyString"],字串,必填變數內容如果是空字串就不能算是有設置的話,請設為"false",預設爲"true",可以為空字串.
3857
		#$conf["canBeEmptyString"]="false";
3858
		#$conf["canNotBeEmpty"],字串陣列,哪些必填參數的內容不得為空字串或空陣列,僅當$conf["canBeEmptyString"]為"true"時會生效.
3859
		#$conf["canNotBeEmpty"]=array();
3860
		#$conf["canBeEmpty"],字串陣列,哪些必填參數的內容可為空字串或空陣列,僅當$conf["canBeEmptyString"]為"false"時會生效.
3861
		#$conf["canBeEmpty"]=array();
3862
		#$conf["skipableVariableCanNotBeEmpty"],字串陣列,哪些可省略參數不可以為空字串或空陣列.
3863
		$conf["variableCheck::checkArguments"]["skipableVariableCanNotBeEmpty"]=array("sock");
3864
		#$conf["skipableVariableName"],陣列字串,爲可省略參數的變數名稱陣列,形態爲陣列變數,例如: $conf["skipableVariableName"] = array("id","account","password");
3865
		$conf["variableCheck::checkArguments"]["skipableVariableName"]=array("sock");
3866
		#$conf["skipableVariableType"],陣列字串,爲可省略參數的變數名稱陣列,形態爲陣列變數,例如: $conf["skipableVariableType"] = array("string",integer,"double");
3867
		$conf["variableCheck::checkArguments"]["skipableVariableType"]=array("string");
3868
		#$conf["skipableVarDefaultValue"],字串陣列,每個不存在的可省略變數要初始化為什麼,null與代表不指定,若預設值是參數之一,請將$conf["mustBeFilledVar"]改成"\$conf["\mustBeFilledVar\"]".
3869
		$conf["variableCheck::checkArguments"]["skipableVarDefaultValue"]=array(qbpwcf_usock_path);
3870
		#$conf["disallowAllSkipableVarIsEmpty"],字串,是否允許每個可省略參數都為空字串,預設為"true"允許,反之為"false".
3871
		#$conf["disallowAllSkipableVarIsEmpty"]="";
3872
		#$conf["disallowAllSkipableVarIsEmptyArray"],字串,是否允許每個可省略參數都為空陣列,預設為"true"允許,反之為"false".
3873
		#$conf["disallowAllSkipableVarIsEmptyArray"]="";
3874
		#$conf["disallowAllSkipableVarNotExist"],字串,是否不允許每個可省略參數都不存在,預設為"false"代表允許,反之為"true".
3875
		#$conf["disallowAllSkipableVarNotExist"]="";
3876
		#$conf["arrayCountEqualCheck"],字串陣列,為檢查哪些陣列參數的元素數量要一樣,$conf["arrayCountEqualCheck"][$i]=array()為第$i組key為哪些的變數其元素數量要相等.
3877
		#$conf["arrayCountEqualCheck"][]=array();
3878
		#參考資料:
3879
		#array_keys=>http://php.net/manual/en/function.array-keys.php
3880
		#備註:
3881
		#無.
3882
		$checkArguments=variableCheck::checkArguments($conf["variableCheck::checkArguments"]);
3883
		unset($conf["variableCheck::checkArguments"]);
3884
 
3885
		#如果執行失敗
3886
		if($checkArguments["status"]==="false"){
3887
 
3888
			#設置執行錯誤識別
3889
			$result["status"]="false";
3890
 
3891
			#設置錯誤訊息
3892
			$result["error"]=$checkArguments["error"];
3893
 
3894
			#回傳結果
3895
			return $result;
3896
 
3897
			}#if end
3898
 
3899
		#如果檢查不通過
3900
		if($checkArguments["status"]==="false"){
3901
 
3902
			#設置執行錯誤識別
3903
			$result["status"]="false";
3904
 
3905
			#設置錯誤訊息
3906
			$result["error"]=$checkArguments["error"];
3907
 
3908
			#回傳結果
3909
			return $result;
3910
 
3911
			}#if end
3912
 
3913
		#函式說明:
3914
		#連線到 unixDomainSockServer 提供的 unix domain socket.
3915
		#回傳結果:
3916
		#$result["status"],"true"代表執行正常;"false"代表執行不正常.
3917
		#$result["error"],錯誤訊息陣列.
3918
		#$result["function"],當前執行的函式名稱.
3919
		#$result["content"],取得的回應,讀到EOL,才會結束.
3920
		#必填參數:
3921
		#$conf["sock"],字串,要連線的unix domain socket.
3922
		$conf["sock::unixDomainSockClient"]["sock"]=$conf["sock"];
3923
		#可省略參數:
3924
		#$conf["id"],字串,取得的id,若無此值,則會得到新的數值.
3925
		#$conf["id"]="";
3926
		#$conf["cmd"],字串,要執行的指令,當$conf["id"]參數合法時,才會執行.
3927
		#$conf["cmd"]="";
3928
		#$conf["param"],參數陣列.
3929
		#$conf["param"]=array();
3930
		#$conf["escaped"],字串,param參數是否已經escaped了,預設為"false",反之為"true".
3931
		#$conf["escaped"]="true";
3932
		#$conf["custom"],陣列,要客制化傳輸的內容,會覆蓋以上除了$conf["id"]以外的可省略參數.
3933
		$conf["sock::unixDomainSockClient"]["custom"]=$conf["msg"];
3934
		#參考資料:
3935
		#http://php.net/manual/en/function.stream-socket-client.php
3936
		#http://php.net/manual/en/function.stream-get-contents.php
3937
		#備註:
3938
		#無.
3939
		$paramsOfUnixDomainSockClient=$conf["sock::unixDomainSockClient"];
3940
		$unixDomainSockClient=sock::unixDomainSockClient($conf["sock::unixDomainSockClient"]);
3941
		unset($conf["sock::unixDomainSockClient"]);
3942
 
3943
		#如果執行失敗
3944
		if($unixDomainSockClient["status"]==="false"){
3945
 
3946
			#設置執行錯誤識別
3947
			$result["status"]="false";
3948
 
3949
			#設置錯誤訊息
3950
			$result["error"]=$unixDomainSockClient;
3951
 
3952
			#回傳結果
3953
			return $result;
3954
 
3955
			}#if end
3956
 
3957
		#取得json回應
3958
		$jsonRes=json_decode($unixDomainSockClient["content"]);
3959
 
3960
		#如果執行失敗
3961
		if($jsonRes===null){
3962
 
3963
			#設置執行錯誤識別
3964
			$result["status"]="false";
3965
 
3966
			#設置錯誤訊息
3967
			$result["error"]=$unixDomainSockClient;
3968
 
3969
			#回傳結果
3970
			return $result;
3971
 
3972
			}#if end
3973
 
3974
		#如果沒有產生新id
3975
		if(!isset($jsonRes->id)){
3976
 
3977
			#設置執行錯誤識別
3978
			$result["status"]="false";
3979
 
3980
			#設置錯誤訊息
3981
			$result["error"]=$unixDomainSockClient;
3982
 
3983
			#回傳結果
3984
			return $result;
3985
 
3986
			}#if end
3987
 
3988
		#用新的id再傳送一次要求給 qbpwcf_usock_path
3989
		$paramsOfUnixDomainSockClient["id"]=$jsonRes->id;		
3990
		$unixDomainSockClient=sock::unixDomainSockClient($paramsOfUnixDomainSockClient);
3991
		unset($paramsOfUnixDomainSockClient);
3992
 
3993
		#如果執行失敗
3994
		if($unixDomainSockClient["status"]==="false"){
3995
 
3996
			#設置執行錯誤識別
3997
			$result["status"]="false";
3998
 
3999
			#設置錯誤訊息
4000
			$result["error"]=$unixDomainSockClient;
4001
 
4002
			#回傳結果
4003
			return $result;
4004
 
4005
			}#if end
4006
 
4007
		#取得回應
4008
		$result["content"]=$unixDomainSockClient["content"];
4009
 
4010
		#設置執行正常
4011
		$result["status"]="true";
4012
 
4013
		#回傳結果
4014
		return $result;
4015
 
4016
		}#function sendAnyMsgToQBPWCFunixSocket end
4017
 
4018
	/*
4019
	#函式說明:
4020
	#重複連線到 unixDomainSockServer 提供的 unix domain socket, 避免其 listen timeout, 並清除逾時的連線.
4021
	#回傳結果:
4022
	#$result["status"],"true"代表執行正常;"false"代表執行不正常.
4023
	#$result["error"],錯誤訊息陣列.
4024
	#$result["function"],當前執行的函式名稱.
4025
	#必填參數:
4026
	#$conf["sock"],字串,要連線的unix domain socket.
4027
	$conf["sock"]="";
4028
	#可省略參數:
4029
	#無.
4030
	#參考資料:
4031
	#無.
4032
	#備註:
4033
	#無.
4034
	*/
4035
	public static function keepAliveUnixDomainSockConnection(&$conf){
4036
 
4037
		#初始化要回傳的結果
4038
		$result=array();
4039
 
4040
		#取得當前執行的函數名稱
4041
		$result["function"]=__FUNCTION__;
4042
 
4043
		#如果沒有參數
4044
		if(func_num_args()==0){
4045
 
4046
			#設置執行失敗
4047
			$result["status"]="false";
4048
 
4049
			#設置執行錯誤訊息
4050
			$result["error"]="函數".$result["function"]."需要參數";
4051
 
4052
			#回傳結果
4053
			return $result;
4054
 
4055
			}#if end
4056
 
4057
		#涵式說明:
4058
		#判斷當前環境為web還是cmd
4059
		#回傳結果:
4060
		#$result,"web"或"cmd"
4061
		if(csInformation::getEnv()==="web"){
4062
 
4063
			#設置執行失敗
4064
			$result["status"]="false";
4065
 
4066
			#設置執行錯誤訊息
4067
			$result["error"][]="函數 ".$result["function"]." 僅能在命令列環境下運行!";
4068
 
4069
			#回傳結果
4070
			return $result;
4071
 
4072
			}#if end
4073
 
4074
		#取得參數
4075
		$result["argu"]=$conf;
4076
 
4077
		#如果 $conf 不為陣列
4078
		if(gettype($conf)!="array"){
4079
 
4080
			#設置執行失敗
4081
			$result["status"]="false";
4082
 
4083
			#設置執行錯誤訊息
4084
			$result["error"][]="\$conf變數須為陣列形態";
4085
 
4086
			#如果傳入的參數為 null
4087
			if($conf==null){
4088
 
4089
				#設置執行錯誤訊息
4090
				$result["error"][]="\$conf變數不得為null,請檢查函數「".$result["function"]."」的參數設置有無正確!";
4091
 
4092
				}#if end
4093
 
4094
			#回傳結果
4095
			return $result;
4096
 
4097
			}#if end
4098
 
4099
		#檢查參數
4100
		#函式說明:
4101
		#檢查必填與可省略的參數,可省略參數可指定預設要給與什麼數值內容。
4102
		#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
4103
		#$reuslt["error"],執行不正常結束的錯訊息陣列.
4104
		#$result["function"],當前執行的函式名稱.
4105
		#$result["argu"],設置給予的參數.
4106
		#$result["passed"],識別要檢查的全體變數是否存在以及型態是否正確的變數,"true"代表檢查全部通過;"false"代表檢查不通過
4107
		#$result[$shouldBeCheckedVarName]["varExist"],所檢查的變數是否存在,"false"代表不存在;"true"代表存在
4108
		#$result[$shouldBeCheckedVarName]["varType"],所檢查的變數型態是否正確,"false"代表錯誤;"true"代表正確
4109
		#$result[$shouldBeCheckedVarName]["error"],每個參數設定的錯誤訊息
4110
		#$result["shouldNotBeEmpty"],不應該為空字串或控陣列的變數.
4111
		#$result["argu"],字串陣列,目前輸入的參數名稱陣列.
4112
		#$result["legalVarName"],字串陣列,合法可用的參數名稱陣列.
4113
		#$result["notNeedVar"],字串陣列,多餘的參數名稱.
4114
		#必填寫的參數:
4115
		#$conf["varInput"],陣列變數,要檢查的陣列變數,請在要檢查的參數前面加上&,這樣變動的結果才能被套用。
4116
		$conf["variableCheck::checkArguments"]["varInput"]=&$conf;	
4117
		#$conf["referenceVarKey"],字串,$conf參數後面的key值,用於移除不要的參考陣列.
4118
		$conf["variableCheck::checkArguments"]["referenceVarKey"]="variableCheck::checkArguments";
4119
		#可以省略的參數:
4120
		#$conf["mustBeFilledVariableName"],爲必填參數的變數名稱陣列,形態爲陣列變數,元素數量需要跟"mustBeFilledVariableType"參數的元素數量一致,例如: $conf["mustBeFilledVariableName"] = array("id","account","password");
4121
		$conf["variableCheck::checkArguments"]["mustBeFilledVariableName"]=array("sock");
4122
		#$conf["mustBeFilledVariableType"],爲必填參數的變數陣列應該爲何種變數形態,形態爲陣列,元素數量需要跟"mustBeFilledVariableName"參數的元素數量一致,例如: $conf["mustBeFilledVariableType"] = array("string",integer,"double","resource","object"); , null代表不指定變數形態.
4123
		$conf["variableCheck::checkArguments"]["mustBeFilledVariableType"]=array("string");
4124
		#$conf["canBeEmptyString"],字串,必填變數內容如果是空字串就不能算是有設置的話,請設為"false",預設爲"true",可以為空字串.
4125
		#$conf["canBeEmptyString"]="false";
4126
		#$conf["canNotBeEmpty"],字串陣列,哪些必填參數的內容不得為空字串或空陣列,僅當$conf["canBeEmptyString"]為"true"時會生效.
4127
		#$conf["canNotBeEmpty"]=array();
4128
		#$conf["canBeEmpty"],字串陣列,哪些必填參數的內容可為空字串或空陣列,僅當$conf["canBeEmptyString"]為"false"時會生效.
4129
		#$conf["canBeEmpty"]=array();
4130
		#$conf["skipableVariableCanNotBeEmpty"],字串陣列,哪些可省略參數不可以為空字串或空陣列.
4131
		#$conf["variableCheck::checkArguments"]["skipableVariableCanNotBeEmpty"]=array("id","cmd","param","clear");
4132
		#$conf["skipableVariableName"],陣列字串,爲可省略參數的變數名稱陣列,形態爲陣列變數,例如: $conf["skipableVariableName"] = array("id","account","password");
4133
		#$conf["variableCheck::checkArguments"]["skipableVariableName"]=array("id","cmd","param","clear");
4134
		#$conf["skipableVariableType"],陣列字串,爲可省略參數的變數名稱陣列,形態爲陣列變數,例如: $conf["skipableVariableType"] = array("string",integer,"double"); 
4135
		#$conf["variableCheck::checkArguments"]["skipableVariableType"]=array("string","string","array","string");
4136
		#$conf["skipableVarDefaultValue"],字串陣列,每個不存在的可省略變數要初始化為什麼,null與代表不指定,若預設值是參數之一,請將$conf["mustBeFilledVar"]改成"\$conf["\mustBeFilledVar\"]".
4137
		#$conf["variableCheck::checkArguments"]["skipableVarDefaultValue"]=array();
4138
		#$conf["disallowAllSkipableVarIsEmpty"],字串,是否允許每個可省略參數都為空字串,預設為"true"允許,反之為"false".
4139
		#$conf["disallowAllSkipableVarIsEmpty"]="";
4140
		#$conf["disallowAllSkipableVarIsEmptyArray"],字串,是否允許每個可省略參數都為空陣列,預設為"true"允許,反之為"false".
4141
		#$conf["disallowAllSkipableVarIsEmptyArray"]="";
4142
		#$conf["arrayCountEqualCheck"],字串陣列,為檢查哪些陣列參數的元素數量要一樣,$conf["arrayCountEqualCheck"][$i]=array()為第$i組key為哪些的變數其元素數量要相等.
4143
		#$conf["arrayCountEqualCheck"][]=array();
4144
		#參考資料來源:
4145
		#array_keys=>http://php.net/manual/en/function.array-keys.php
4146
		$checkArguments=variableCheck::checkArguments($conf["variableCheck::checkArguments"]);
4147
		unset($conf["variableCheck::checkArguments"]);
4148
 
4149
		#如果檢查參數失敗
4150
		if($checkArguments["status"]==="false"){
4151
 
4152
			#設置執行失敗
4153
			$result["status"]="false";
4154
 
4155
			#設置錯誤訊息
4156
			$result["error"]=$checkArguments;
4157
 
4158
			#回傳結果
4159
			return $result;
4160
 
4161
			}#if end
4162
 
4163
		#如果檢查參數不通過
4164
		if($checkArguments["passed"]==="false"){
4165
 
4166
			#設置執行失敗
4167
			$result["status"]="false";
4168
 
4169
			#設置錯誤訊息
4170
			$result["error"]=$checkArguments;
4171
 
4172
			#回傳結果
4173
			return $result;
4174
 
4175
			}#if end
4176
 
4177
		#函式說明:
4178
		#連線到 unixDomainSockServer 提供的 unix domain socket.
4179
		#回傳結果:
4180
		#$result["status"],"true"代表執行正常;"false"代表執行不正常.
4181
		#$result["error"],錯誤訊息陣列.
4182
		#$result["function"],當前執行的函式名稱.
4183
		#$result["content"],取得的回應.
4184
		#必填參數:
4185
		#$conf["sock"],字串,要連線的unix domain socket.
4186
		$conf["sock::unixDomainSockClient"]["sock"]=$conf["sock"];
4187
		#可省略參數:
4188
		#$conf["id"],字串,取得的id,若無此值,則會得到新的數值.
4189
		#$conf["id"]="";
4190
		#$conf["cmd"],字串,要執行的指令.
4191
		#$conf["cmd"]="";
4192
		#$conf["param"],參數陣列.
4193
		#$conf["param"]=array();
4194
		#參考資料:
4195
		#http://php.net/manual/en/function.stream-socket-client.php
4196
		#http://php.net/manual/en/function.stream-get-contents.php
4197
		$unixDomainSockClient=sock::unixDomainSockClient($conf["sock::unixDomainSockClient"]);
4198
		unset($conf["sock::unixDomainSockClient"]);
4199
 
4200
		#建立連線失敗
4201
		if($unixDomainSockClient["status"]==="false"){
4202
 
4203
			#設置執行失敗
4204
			$result["status"]="false";
4205
 
4206
			#設置執行錯誤訊息
4207
			$result["error"]=$unixDomainSockClient;
4208
 
4209
			#回傳結果
4210
			return $result;
4211
 
4212
			}#if end
4213
 
4214
		#取得回應	
4215
		$res=$unixDomainSockClient["content"];
4216
 
4217
		#解析回應
4218
		$res=json_decode(trim($res));
4219
 
4220
		#如果解析失敗
4221
		if($res===false){
4222
 
4223
			#設置執行失敗
4224
			$result["status"]="false";
4225
 
4226
			#設置執行錯誤訊息
4227
			$result["error"][]="解析回應失敗";
4228
 
4229
			#回傳結果
4230
			return $result;
4231
 
4232
			}#if end
4233
 
4234
		#取得id	
4235
		$id=$res->id;
4236
 
4237
		#無窮迴圈
4238
		while(true){
4239
 
4240
			#函式說明:
4241
			#連線到 unixDomainSockServer 提供的 unix domain socket.
4242
			#回傳結果:
4243
			#$result["status"],"true"代表執行正常;"false"代表執行不正常.
4244
			#$result["error"],錯誤訊息陣列.
4245
			#$result["function"],當前執行的函式名稱.
4246
			#$result["content"],取得的回應.
4247
			#必填參數:
4248
			#$conf["sock"],字串,要連線的unix domain socket.
4249
			$conf["sock::unixDomainSockClient"]["sock"]=$conf["sock"];
4250
			#可省略參數:
4251
			#$conf["id"],字串,取得的id,若無此值,則會得到新的數值.
4252
			$conf["sock::unixDomainSockClient"]["id"]=$id;
4253
			#$conf["cmd"],字串,要執行的指令.
4254
			#$conf["cmd"]="";
4255
			#$conf["param"],參數陣列.
4256
			#$conf["param"]=array();
4257
			#參考資料:
4258
			#http://php.net/manual/en/function.stream-socket-client.php
4259
			#http://php.net/manual/en/function.stream-get-contents.php
4260
			$unixDomainSockClient=sock::unixDomainSockClient($conf["sock::unixDomainSockClient"]);
4261
			unset($conf["sock::unixDomainSockClient"]);
4262
 
4263
			#建立連線失敗
4264
			if($unixDomainSockClient["status"]==="false"){
4265
 
4266
				#設置執行失敗
4267
				$result["status"]="false";
4268
 
4269
				#設置執行錯誤訊息
4270
				$result["error"]=$unixDomainSockClient;
4271
 
4272
				#回傳結果
4273
				return $result;
4274
 
4275
				}#if end
4276
 
4277
			#取得回應	
4278
			$res=$unixDomainSockClient["content"];
4279
 
4280
			#解析回應
4281
			$res=json_decode($res);
4282
 
4283
			#如果解析失敗
4284
			if($res===false){
4285
 
4286
				#設置執行失敗
4287
				$result["status"]="false";
4288
 
4289
				#設置執行錯誤訊息
4290
				$result["error"][]="解析回應失敗";
4291
 
4292
				#回傳結果
4293
				return $result;
4294
 
4295
				}#if end
4296
 
4297
			#show res
4298
			var_dump($res);
4299
 
4300
			#停止執行
4301
			sleep(60);
4302
 
4303
			}#while end
4304
 
4305
		#設置執行不正常
4306
		$result["status"]="false";
4307
 
4308
		#設置錯誤訊息
4309
		$result["error"][]="程式不應該中斷";
4310
 
4311
		#回傳結果
4312
		return $reuslt;
4313
 
4314
		}#function keepAliveUnixDomainSockConnection end
4315
 
4316
	/*
4317
	#函式說明:
4318
	#tcp client
4319
	#回傳結果:
4320
	#$result["status"],"true"代表執行正常;"false"代表執行不正常.
4321
	#$result["error"],錯誤訊息陣列.
4322
	#$result["function"],當前執行的函式名稱.
4323
	#$result["argu"],使用的參數.
4324
	#$result["content"],取得的回應內容.
4325
	#必填參數:
4326
	#$conf["port"],整數,tcp server listen port.
4327
	$conf["port"]=;
4328
	#$conf["dataToSend"],字串,要傳送的資訊.
4329
	$conf["dataToSend"]="";
4330
	#可省略參數:
4331
	#$conf["ip"],整數字串,tcp serer listen ip, default is 127.0.0.1.
4332
	#$conf["ip"]="127.0.0.1";
4333
	#$conf["sec"],整數,等待回應的秒數,預設為5秒.
4334
	#$conf["sec"]=5;
4335
	#$conf["microSec"],整數,等待回應的毫秒數,預設為0毫秒
4336
	#$conf["microSec"]=0;
4337
	#參考資料:
4338
	#https://www.php.net/manual/en/sockets.examples.php
4339
	#https://www.php.net/manual/en/function.socket-get-option.php
4340
	#備註:
4341
	#無.
4342
	*/
4343
	public static function tcpClient(&$conf){
4344
 
4345
		#初始化要回傳的結果
4346
		$result=array();
4347
 
4348
		#取得當前執行的函數名稱
4349
		$result["function"]=__FUNCTION__;
4350
 
4351
		#如果沒有參數
4352
		if(func_num_args()==0){
4353
 
4354
			#設置執行失敗
4355
			$result["status"]="false";
4356
 
4357
			#設置執行錯誤訊息
4358
			$result["error"]="函數".$result["function"]."需要參數";
4359
 
4360
			#回傳結果
4361
			return $result;
4362
 
4363
			}#if end
4364
 
4365
		#涵式說明:
4366
		#判斷當前環境為web還是cmd
4367
		#回傳結果:
4368
		#$result,"web"或"cmd"
4369
		if(csInformation::getEnv()==="web"){
4370
 
4371
			#設置執行失敗
4372
			$result["status"]="false";
4373
 
4374
			#設置執行錯誤訊息
4375
			$result["error"][]="函數 ".$result["function"]." 僅能在命令列環境下運行!";
4376
 
4377
			#回傳結果
4378
			return $result;
4379
 
4380
			}#if end
4381
 
4382
		#取得參數
4383
		$result["argu"]=$conf;
4384
 
4385
		#如果 $conf 不為陣列
4386
		if(gettype($conf)!="array"){
4387
 
4388
			#設置執行失敗
4389
			$result["status"]="false";
4390
 
4391
			#設置執行錯誤訊息
4392
			$result["error"][]="\$conf變數須為陣列形態";
4393
 
4394
			#如果傳入的參數為 null
4395
			if($conf==null){
4396
 
4397
				#設置執行錯誤訊息
4398
				$result["error"][]="\$conf變數不得為null,請檢查函數「".$result["function"]."」的參數設置有無正確!";
4399
 
4400
				}#if end
4401
 
4402
			#回傳結果
4403
			return $result;
4404
 
4405
			}#if end
4406
 
4407
		#初始化取得的回應
4408
		$result["content"]="";	
4409
 
4410
		#檢查參數
4411
		#函式說明:
4412
		#檢查必填與可省略的參數,可省略參數可指定預設要給與什麼數值內容。
4413
		#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
4414
		#$reuslt["error"],執行不正常結束的錯訊息陣列.
4415
		#$result["function"],當前執行的函式名稱.
4416
		#$result["argu"],設置給予的參數.
4417
		#$result["passed"],識別要檢查的全體變數是否存在以及型態是否正確的變數,"true"代表檢查全部通過;"false"代表檢查不通過
4418
		#$result[$shouldBeCheckedVarName]["varExist"],所檢查的變數是否存在,"false"代表不存在;"true"代表存在
4419
		#$result[$shouldBeCheckedVarName]["varType"],所檢查的變數型態是否正確,"false"代表錯誤;"true"代表正確
4420
		#$result[$shouldBeCheckedVarName]["error"],每個參數設定的錯誤訊息
4421
		#$result["shouldNotBeEmpty"],不應該為空字串或控陣列的變數.
4422
		#$result["argu"],字串陣列,目前輸入的參數名稱陣列.
4423
		#$result["legalVarName"],字串陣列,合法可用的參數名稱陣列.
4424
		#$result["notNeedVar"],字串陣列,多餘的參數名稱.
4425
		#必填寫的參數:
4426
		#$conf["varInput"],陣列變數,要檢查的陣列變數,請在要檢查的參數前面加上&,這樣變動的結果才能被套用。
4427
		$conf["variableCheck::checkArguments"]["varInput"]=&$conf;	
4428
		#$conf["referenceVarKey"],字串,$conf參數後面的key值,用於移除不要的參考陣列.
4429
		$conf["variableCheck::checkArguments"]["referenceVarKey"]="variableCheck::checkArguments";
4430
		#可以省略的參數:
4431
		#$conf["mustBeFilledVariableName"],爲必填參數的變數名稱陣列,形態爲陣列變數,元素數量需要跟"mustBeFilledVariableType"參數的元素數量一致,例如: $conf["mustBeFilledVariableName"] = array("id","account","password");
4432
		$conf["variableCheck::checkArguments"]["mustBeFilledVariableName"]=array("port","dataToSend");
4433
		#$conf["mustBeFilledVariableType"],爲必填參數的變數陣列應該爲何種變數形態,形態爲陣列,元素數量需要跟"mustBeFilledVariableName"參數的元素數量一致,例如: $conf["mustBeFilledVariableType"] = array("string",integer,"double","resource","object"); , null代表不指定變數形態.
4434
		$conf["variableCheck::checkArguments"]["mustBeFilledVariableType"]=array("integer","string");
4435
		#$conf["canBeEmptyString"],字串,必填變數內容如果是空字串就不能算是有設置的話,請設為"false",預設爲"true",可以為空字串.
4436
		$conf["variableCheck::checkArguments"]["canBeEmptyString"]="false";
4437
		#$conf["canNotBeEmpty"],字串陣列,哪些必填參數的內容不得為空字串或空陣列,僅當$conf["canBeEmptyString"]為"true"時會生效.
4438
		#$conf["canNotBeEmpty"]=array();
4439
		#$conf["canBeEmpty"],字串陣列,哪些必填參數的內容可為空字串或空陣列,僅當$conf["canBeEmptyString"]為"false"時會生效.
4440
		#$conf["canBeEmpty"]=array();
4441
		#$conf["skipableVariableCanNotBeEmpty"],字串陣列,哪些可省略參數不可以為空字串或空陣列.
4442
		$conf["variableCheck::checkArguments"]["skipableVariableCanNotBeEmpty"]=array("ip");
4443
		#$conf["skipableVariableName"],陣列字串,爲可省略參數的變數名稱陣列,形態爲陣列變數,例如: $conf["skipableVariableName"] = array("id","account","password");
4444
		$conf["variableCheck::checkArguments"]["skipableVariableName"]=array("ip","sec","microSec");
4445
		#$conf["skipableVariableType"],陣列字串,爲可省略參數的變數名稱陣列,形態爲陣列變數,例如: $conf["skipableVariableType"] = array("string",integer,"double"); 
4446
		$conf["variableCheck::checkArguments"]["skipableVariableType"]=array("string","integer","integer");
4447
		#$conf["skipableVarDefaultValue"],字串陣列,每個不存在的可省略變數要初始化為什麼,null與代表不指定,若預設值是參數之一,請將$conf["mustBeFilledVar"]改成"\$conf["\mustBeFilledVar\"]".
4448
		$conf["variableCheck::checkArguments"]["skipableVarDefaultValue"]=array("127.0.0.1",5,0);
4449
		#$conf["disallowAllSkipableVarIsEmpty"],字串,是否允許每個可省略參數都為空字串,預設為"true"允許,反之為"false".
4450
		#$conf["disallowAllSkipableVarIsEmpty"]="";
4451
		#$conf["disallowAllSkipableVarIsEmptyArray"],字串,是否允許每個可省略參數都為空陣列,預設為"true"允許,反之為"false".
4452
		#$conf["disallowAllSkipableVarIsEmptyArray"]="";
4453
		#$conf["arrayCountEqualCheck"],字串陣列,為檢查哪些陣列參數的元素數量要一樣,$conf["arrayCountEqualCheck"][$i]=array()為第$i組key為哪些的變數其元素數量要相等.
4454
		#$conf["arrayCountEqualCheck"][]=array();
4455
		#參考資料來源:
4456
		#array_keys=>http://php.net/manual/en/function.array-keys.php
4457
		$checkArguments=variableCheck::checkArguments($conf["variableCheck::checkArguments"]);
4458
		unset($conf["variableCheck::checkArguments"]);
4459
 
4460
		#如果檢查參數失敗
4461
		if($checkArguments["status"]==="false"){
4462
 
4463
			#設置執行失敗
4464
			$result["status"]="false";
4465
 
4466
			#設置錯誤訊息
4467
			$result["error"]=$checkArguments;
4468
 
4469
			#回傳結果
4470
			return $result;
4471
 
4472
			}#if end
4473
 
4474
		#如果檢查參數不通過
4475
		if($checkArguments["passed"]==="false"){
4476
 
4477
			#設置執行失敗
4478
			$result["status"]="false";
4479
 
4480
			#設置錯誤訊息
4481
			$result["error"]=$checkArguments;
4482
 
4483
			#回傳結果
4484
			return $result;
4485
 
4486
			}#if end
4487
 
4488
		#建立 tcp socket client	
4489
		$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
4490
 
4491
		#設置接收資料的最長等待時間
4492
		socket_set_option($socket, SOL_SOCKET, SO_RCVTIMEO, array("sec"=>$conf["sec"],"usec"=>$conf["microSec"]));
4493
 
4494
		#如果建立 socket 失敗
4495
		if ($socket === false) {
4496
 
4497
			#設置執行失敗
4498
			$result["status"]="false";
4499
 
4500
			#設置錯誤訊息
4501
			$result["error"][]="socket_create() failed: reason: " . socket_strerror(socket_last_error());
4502
 
4503
			#回傳結果
4504
			return $result;
4505
 
4506
			}#if end 
4507
 
4508
		#連線到 tcp socket server	
4509
		$socket_connect = socket_connect($socket, $conf["ip"], $conf["port"]);
4510
 
4511
		#如果連線到 tcp socket server 失敗
4512
		if ($socket_connect === false) {
4513
 
4514
			#設置執行失敗
4515
			$result["status"]="false";
4516
 
4517
	    		#設置錯誤訊息
4518
			$result["error"][]="socket_connect() failed. Reason: ($result) " . socket_strerror(socket_last_error($socket));
4519
 
4520
			#回傳結果
4521
			return $result;
4522
 
4523
			}#if end
4524
 
4525
		#傳送訊息到 tcp server
4526
		socket_write($socket, $conf["dataToSend"].PHP_EOL, strlen($conf["dataToSend"].PHP_EOL));
4527
 
4528
		#取得回應
4529
		while ($out = socket_read($socket, 2048)) {
4530
 
4531
			#設置取得的回應
4532
			$result["content"]=$result["content"].$out;
4533
 
4534
			#debug
4535
			#echo $result["content"];
4536
 
4537
			}#while end
4538
 
4539
		#關閉socket
4540
		socket_close($socket);
4541
 
4542
		#設置處理正常
4543
		$result["status"]="true";
4544
 
4545
		#回傳結果
4546
		return $result;	
4547
 
4548
		}#function tcpClient end
4549
 
4550
	/*
4551
	#函式說明:
4552
	#udp client
4553
	#回傳結果:
4554
	#$result["status"],"true"代表執行正常;"false"代表執行不正常.
4555
	#$result["error"],錯誤訊息陣列.
4556
	#$result["function"],當前執行的函式名稱.
4557
	#$result["argu"],使用的參數.
4558
	#$result["content"],取得的回應內容字串,為每個回應的內容直接串接.
4559
	#$result["contentArray"],取得的回應字串陣列,為每個回應的內容,各別儲存成陣列中的元素.
4560
	#$result["sock"],可重複使用的socket資源.
4561
	#必填參數:
4562
	#$conf["port"],整數,target port.
4563
	$conf["port"]=;
4564
	#$conf["dataToSend"],陣列字串,要傳送的多個訊息,每個訊息傳送結束後才會讀取回應.
4565
	$conf["dataToSend"]=array("");
4566
	#可省略參數:
4567
	#$conf["ip"],整數字串,tcp serer listen ip, default is 127.0.0.1.
4568
	#$conf["ip"]="127.0.0.1";
4569
	#$conf["timeout"],整數,預設為10秒,代表接收訊息的等待時間上限.
4570
	#$conf["timeout"]=10;
4571
	#$conf["secSleepAfterSend"],整數,預設為1秒.
4572
	#$conf["secSleepAfterSend"]=1;
4573
	#$conf["closeAtEnd"],字串,預設為"true",代表函式結束後要斷開連線.
4574
	#$conf["closeAtEnd"]="true";
4575
	#$conf["sock"],resource,要重複使用的socket資源,預設不指定.
4576
	#$conf["sock"]=;
4577
	#參考資料:
4578
	#https://www.php.net/manual/en/sockets.examples.php
4579
	#備註:
4580
	#無.
4581
	*/
4582
	public static function udpClient(&$conf){
4583
 
4584
		#初始化要回傳的結果
4585
		$result=array();
4586
 
4587
		#取得當前執行的函數名稱
4588
		$result["function"]=__FUNCTION__;
4589
 
4590
		#如果沒有參數
4591
		if(func_num_args()==0){
4592
 
4593
			#設置執行失敗
4594
			$result["status"]="false";
4595
 
4596
			#設置執行錯誤訊息
4597
			$result["error"]="函數".$result["function"]."需要參數";
4598
 
4599
			#回傳結果
4600
			return $result;
4601
 
4602
			}#if end
4603
 
4604
		#涵式說明:
4605
		#判斷當前環境為web還是cmd
4606
		#回傳結果:
4607
		#$result,"web"或"cmd"
4608
		if(csInformation::getEnv()==="web"){
4609
 
4610
			#設置執行失敗
4611
			$result["status"]="false";
4612
 
4613
			#設置執行錯誤訊息
4614
			$result["error"][]="函數 ".$result["function"]." 僅能在命令列環境下運行!";
4615
 
4616
			#回傳結果
4617
			return $result;
4618
 
4619
			}#if end
4620
 
4621
		#取得參數
4622
		$result["argu"]=$conf;
4623
 
4624
		#如果 $conf 不為陣列
4625
		if(gettype($conf)!="array"){
4626
 
4627
			#設置執行失敗
4628
			$result["status"]="false";
4629
 
4630
			#設置執行錯誤訊息
4631
			$result["error"][]="\$conf變數須為陣列形態";
4632
 
4633
			#如果傳入的參數為 null
4634
			if($conf==null){
4635
 
4636
				#設置執行錯誤訊息
4637
				$result["error"][]="\$conf變數不得為null,請檢查函數「".$result["function"]."」的參數設置有無正確!";
4638
 
4639
				}#if end
4640
 
4641
			#回傳結果
4642
			return $result;
4643
 
4644
			}#if end
4645
 
4646
		#初始化取得的回應
4647
		$result["content"]="";	
4648
 
4649
		#檢查參數
4650
		#函式說明:
4651
		#檢查必填與可省略的參數,可省略參數可指定預設要給與什麼數值內容。
4652
		#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
4653
		#$reuslt["error"],執行不正常結束的錯訊息陣列.
4654
		#$result["function"],當前執行的函式名稱.
4655
		#$result["argu"],設置給予的參數.
4656
		#$result["passed"],識別要檢查的全體變數是否存在以及型態是否正確的變數,"true"代表檢查全部通過;"false"代表檢查不通過
4657
		#$result[$shouldBeCheckedVarName]["varExist"],所檢查的變數是否存在,"false"代表不存在;"true"代表存在
4658
		#$result[$shouldBeCheckedVarName]["varType"],所檢查的變數型態是否正確,"false"代表錯誤;"true"代表正確
4659
		#$result[$shouldBeCheckedVarName]["error"],每個參數設定的錯誤訊息
4660
		#$result["shouldNotBeEmpty"],不應該為空字串或控陣列的變數.
4661
		#$result["argu"],字串陣列,目前輸入的參數名稱陣列.
4662
		#$result["legalVarName"],字串陣列,合法可用的參數名稱陣列.
4663
		#$result["notNeedVar"],字串陣列,多餘的參數名稱.
4664
		#必填寫的參數:
4665
		#$conf["varInput"],陣列變數,要檢查的陣列變數,請在要檢查的參數前面加上&,這樣變動的結果才能被套用。
4666
		$conf["variableCheck::checkArguments"]["varInput"]=&$conf;	
4667
		#$conf["referenceVarKey"],字串,$conf參數後面的key值,用於移除不要的參考陣列.
4668
		$conf["variableCheck::checkArguments"]["referenceVarKey"]="variableCheck::checkArguments";
4669
		#可以省略的參數:
4670
		#$conf["mustBeFilledVariableName"],爲必填參數的變數名稱陣列,形態爲陣列變數,元素數量需要跟"mustBeFilledVariableType"參數的元素數量一致,例如: $conf["mustBeFilledVariableName"] = array("id","account","password");
4671
		$conf["variableCheck::checkArguments"]["mustBeFilledVariableName"]=array("port","dataToSend");
4672
		#$conf["mustBeFilledVariableType"],爲必填參數的變數陣列應該爲何種變數形態,形態爲陣列,元素數量需要跟"mustBeFilledVariableName"參數的元素數量一致,例如: $conf["mustBeFilledVariableType"] = array("string",integer,"double","resource","object"); , null代表不指定變數形態.
4673
		$conf["variableCheck::checkArguments"]["mustBeFilledVariableType"]=array("integer","array");
4674
		#$conf["canBeEmptyString"],字串,必填變數內容如果是空字串就不能算是有設置的話,請設為"false",預設爲"true",可以為空字串.
4675
		$conf["variableCheck::checkArguments"]["canBeEmptyString"]="false";
4676
		#$conf["canNotBeEmpty"],字串陣列,哪些必填參數的內容不得為空字串或空陣列,僅當$conf["canBeEmptyString"]為"true"時會生效.
4677
		#$conf["canNotBeEmpty"]=array();
4678
		#$conf["canBeEmpty"],字串陣列,哪些必填參數的內容可為空字串或空陣列,僅當$conf["canBeEmptyString"]為"false"時會生效.
4679
		#$conf["canBeEmpty"]=array();
4680
		#$conf["skipableVariableCanNotBeEmpty"],字串陣列,哪些可省略參數不可以為空字串或空陣列.
4681
		$conf["variableCheck::checkArguments"]["skipableVariableCanNotBeEmpty"]=array("ip","secSleepAfterSend","closeAtEnd","timeout");
4682
		#$conf["skipableVariableName"],陣列字串,爲可省略參數的變數名稱陣列,形態爲陣列變數,例如: $conf["skipableVariableName"] = array("id","account","password");
4683
		$conf["variableCheck::checkArguments"]["skipableVariableName"]=array("ip","secSleepAfterSend","closeAtEnd","sock","timeout");
4684
		#$conf["skipableVariableType"],陣列字串,爲可省略參數的變數名稱陣列,形態爲陣列變數,例如: $conf["skipableVariableType"] = array("string",integer,"double"); 
4685
		$conf["variableCheck::checkArguments"]["skipableVariableType"]=array("string","integer","string","object","integer");
4686
		#$conf["skipableVarDefaultValue"],字串陣列,每個不存在的可省略變數要初始化為什麼,null與代表不指定,若預設值是參數之一,請將$conf["mustBeFilledVar"]改成"\$conf["\mustBeFilledVar\"]".
4687
		$conf["variableCheck::checkArguments"]["skipableVarDefaultValue"]=array("127.0.0.1",1,"false",null,10);
4688
		#$conf["disallowAllSkipableVarIsEmpty"],字串,是否允許每個可省略參數都為空字串,預設為"true"允許,反之為"false".
4689
		#$conf["disallowAllSkipableVarIsEmpty"]="";
4690
		#$conf["disallowAllSkipableVarIsEmptyArray"],字串,是否允許每個可省略參數都為空陣列,預設為"true"允許,反之為"false".
4691
		#$conf["disallowAllSkipableVarIsEmptyArray"]="";
4692
		#$conf["arrayCountEqualCheck"],字串陣列,為檢查哪些陣列參數的元素數量要一樣,$conf["arrayCountEqualCheck"][$i]=array()為第$i組key為哪些的變數其元素數量要相等.
4693
		#$conf["arrayCountEqualCheck"][]=array();
4694
		#參考資料來源:
4695
		#array_keys=>http://php.net/manual/en/function.array-keys.php
4696
		$checkArguments=variableCheck::checkArguments($conf["variableCheck::checkArguments"]);
4697
		unset($conf["variableCheck::checkArguments"]);
4698
 
4699
		#如果檢查參數失敗
4700
		if($checkArguments["status"]==="false"){
4701
 
4702
			#設置執行失敗
4703
			$result["status"]="false";
4704
 
4705
			#設置錯誤訊息
4706
			$result["error"]=$checkArguments;
4707
 
4708
			#回傳結果
4709
			return $result;
4710
 
4711
			}#if end
4712
 
4713
		#如果檢查參數不通過
4714
		if($checkArguments["passed"]==="false"){
4715
 
4716
			#設置執行失敗
4717
			$result["status"]="false";
4718
 
4719
			#設置錯誤訊息
4720
			$result["error"]=$checkArguments;
4721
 
4722
			#回傳結果
4723
			return $result;
4724
 
4725
			}#if end
4726
 
4727
		#如果沒有指定要用既有的 socket 
4728
		if(!isset($conf["sock"])){
4729
 
4730
			#建立 udp socket client	
4731
			$socket = socket_create(AF_INET, SOCK_DGRAM, SOL_UDP);
4732
 
4733
			#設置 timeout 為 $conf["timeout"] 秒
4734
			$timeout = array('sec'=>$conf["timeout"],'usec'=>0);
4735
 			socket_set_option($socket,SOL_SOCKET,SO_RCVTIMEO,$timeout);
4736
 
4737
 			#如果建立 socket 失敗
4738
			if ($socket === false) {
4739
 
4740
				#設置執行失敗
4741
				$result["status"]="false";
4742
 
4743
				#設置錯誤訊息
4744
				$result["error"][]="socket_create() failed: reason: " . socket_strerror(socket_last_error());
4745
 
4746
				#回傳結果
4747
				return $result;
4748
 
4749
				}#if end 
4750
 
4751
			#連線到 udp socket server	
4752
			$socket_connect = socket_connect($socket, $conf["ip"], $conf["port"]);
4753
 
4754
			#如果連線到 udp socket server 失敗
4755
			if ($socket_connect === false) {
4756
 
4757
				#設置執行失敗
4758
				$result["status"]="false";
4759
 
4760
				#設置錯誤訊息
4761
				$result["error"][]="socket_connect() failed. Reason: ($result) " . socket_strerror(socket_last_error($socket));
4762
 
4763
				#回傳結果
4764
				return $result;
4765
 
4766
				}#if end
4767
 
4768
			}#if end	
4769
 
4770
		#反之
4771
		else{
4772
			#取得要重複使用的socket
4773
			$socket=&$conf["sock"];
4774
 
4775
			}#else end
4776
 
4777
		#有幾個訊息就跑幾次
4778
		for($i=0;$i<count($conf["dataToSend"]);$i++){
4779
 
4780
			#傳送訊息到 tcp server
4781
			socket_write($socket, $conf["dataToSend"][$i], strlen($conf["dataToSend"][$i]));
4782
 
4783
			#取得回應
4784
			while ($out = socket_read($socket, 2048)) {
4785
 
4786
				#設置取得的回應,儲存到陣列裡面.
4787
				$result["contentArray"][]=$out;
4788
 
4789
				#設置取得的回應,儲存成字串,串接在一塊.
4790
				$result["content"]=$result["content"].$out;
4791
 
4792
				}#while end
4793
 
4794
			#如果有多個訊息要傳遞,且不是最後一個訊息
4795
			if(count($conf["dataToSend"])>1 && $i!==count($conf["dataToSend"])-1){
4796
 
4797
				#休息一下
4798
				sleep($conf["secSleepAfterSend"]);
4799
 
4800
				}#if end
4801
 
4802
			}#for end
4803
 
4804
		#如果要關閉連線
4805
		if($conf["closeAtEnd"]==="true"){
4806
 
4807
			#關閉socket
4808
			socket_close($socket);
4809
 
4810
			}#if end
4811
 
4812
		#取得使用的socket
4813
		$result["sock"]=$socket;	
4814
 
4815
		#設置處理正常
4816
		$result["status"]="true";
4817
 
4818
		#回傳結果
4819
		return $result;	
4820
 
4821
		}#function udpClient end
4822
 
4823
	/*
4824
	#函式說明:
4825
	#建立tcp server
4826
	#必填參數:
4827
	#$conf["port"],整數,tcp server listen port.
4828
	$conf["port"]=;
4829
	#可省略參數:
4830
	#$conf["ip"],整數字串,tcp server listen ip, default is 0.0.0.0.
4831
	#$conf["ip"]="0.0.0.0";
4832
	#$conf["processFuncs"],字串陣列,要將收到的訊息作什麼事情的函式們,預設為空陣列,裡面若是自己建立的涵式,可這樣呼叫"\qbpwcf\your function name".
4833
	#$conf["processFuncs"]=array();
4834
	#$conf["serverFuncs"],字串陣列,於idle時,server要執行的函式們,預設為空陣列.
4835
	#$conf["serverFuncs"]=array();
4836
	#$conf["welcomeMsg"],字串,是否要顯示歡迎訊息,預設為"true"代表要顯示歡迎訊息;"false"代表不要顯示歡迎訊息.
4837
	#$conf["welcomeMsg"]="true";
4838
	#$conf["socketSelectTimeountSec"],整數,代表要等候幾秒才抓取有異動的連線,預設為0代表立即抓取有異動的連線,但是會吃很多cpu.
4839
	#$conf["socketSelectTimeountSec"]=0;
4840
	#$conf["socketSelectTimeountUsec"],整數,代表要等候幾微秒才抓取有異動的連線,預設不使用.
4841
	#$conf["socketSelectTimeountUsec"]=5000;
4842
	#參考資料:
4843
	#無.
4844
	#備註:
4845
	#無.
4846
	*/
4847
	public static function tcpServer(&$conf){
4848
 
4849
		#初始化要回傳的結果
4850
		$result=array();
4851
 
4852
		#取得當前執行的函數名稱
4853
		$result["function"]=__FUNCTION__;
4854
 
4855
		#如果沒有參數
4856
		if(func_num_args()==0){
4857
 
4858
			#設置執行失敗
4859
			$result["status"]="false";
4860
 
4861
			#設置執行錯誤訊息
4862
			$result["error"]="函數".$result["function"]."需要參數";
4863
 
4864
			#回傳結果
4865
			return $result;
4866
 
4867
			}#if end
4868
 
4869
		#涵式說明:
4870
		#判斷當前環境為web還是cmd
4871
		#回傳結果:
4872
		#$result,"web"或"cmd"
4873
		if(csInformation::getEnv()==="web"){
4874
 
4875
			#設置執行失敗
4876
			$result["status"]="false";
4877
 
4878
			#設置執行錯誤訊息
4879
			$result["error"][]="函數 ".$result["function"]." 僅能在命令列環境下運行!";
4880
 
4881
			#回傳結果
4882
			return $result;
4883
 
4884
			}#if end
4885
 
4886
		#取得參數
4887
		$result["argu"]=$conf;
4888
 
4889
		#如果 $conf 不為陣列
4890
		if(gettype($conf)!="array"){
4891
 
4892
			#設置執行失敗
4893
			$result["status"]="false";
4894
 
4895
			#設置執行錯誤訊息
4896
			$result["error"][]="\$conf變數須為陣列形態";
4897
 
4898
			#如果傳入的參數為 null
4899
			if($conf==null){
4900
 
4901
				#設置執行錯誤訊息
4902
				$result["error"][]="\$conf變數不得為null,請檢查函數「".$result["function"]."」的參數設置有無正確!";
4903
 
4904
				}#if end
4905
 
4906
			#回傳結果
4907
			return $result;
4908
 
4909
			}#if end
4910
 
4911
		#檢查參數
4912
		#函式說明:
4913
		#檢查必填與可省略的參數,可省略參數可指定預設要給與什麼數值內容。
4914
		#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
4915
		#$reuslt["error"],執行不正常結束的錯訊息陣列.
4916
		#$result["function"],當前執行的函式名稱.
4917
		#$result["argu"],設置給予的參數.
4918
		#$result["passed"],識別要檢查的全體變數是否存在以及型態是否正確的變數,"true"代表檢查全部通過;"false"代表檢查不通過
4919
		#$result[$shouldBeCheckedVarName]["varExist"],所檢查的變數是否存在,"false"代表不存在;"true"代表存在
4920
		#$result[$shouldBeCheckedVarName]["varType"],所檢查的變數型態是否正確,"false"代表錯誤;"true"代表正確
4921
		#$result[$shouldBeCheckedVarName]["error"],每個參數設定的錯誤訊息
4922
		#$result["shouldNotBeEmpty"],不應該為空字串或控陣列的變數.
4923
		#$result["argu"],字串陣列,目前輸入的參數名稱陣列.
4924
		#$result["legalVarName"],字串陣列,合法可用的參數名稱陣列.
4925
		#$result["notNeedVar"],字串陣列,多餘的參數名稱.
4926
		#必填寫的參數:
4927
		#$conf["varInput"],陣列變數,要檢查的陣列變數,請在要檢查的參數前面加上&,這樣變動的結果才能被套用。
4928
		$conf["variableCheck::checkArguments"]["varInput"]=&$conf;	
4929
		#$conf["referenceVarKey"],字串,$conf參數後面的key值,用於移除不要的參考陣列.
4930
		$conf["variableCheck::checkArguments"]["referenceVarKey"]="variableCheck::checkArguments";
4931
		#可以省略的參數:
4932
		#$conf["mustBeFilledVariableName"],爲必填參數的變數名稱陣列,形態爲陣列變數,元素數量需要跟"mustBeFilledVariableType"參數的元素數量一致,例如: $conf["mustBeFilledVariableName"] = array("id","account","password");
4933
		$conf["variableCheck::checkArguments"]["mustBeFilledVariableName"]=array("port");
4934
		#$conf["mustBeFilledVariableType"],爲必填參數的變數陣列應該爲何種變數形態,形態爲陣列,元素數量需要跟"mustBeFilledVariableName"參數的元素數量一致,例如: $conf["mustBeFilledVariableType"] = array("string",integer,"double","resource","object"); , null代表不指定變數形態.
4935
		$conf["variableCheck::checkArguments"]["mustBeFilledVariableType"]=array("integer");
4936
		#$conf["canBeEmptyString"],字串,必填變數內容如果是空字串就不能算是有設置的話,請設為"false",預設爲"true",可以為空字串.
4937
		#$conf["canBeEmptyString"]="false";
4938
		#$conf["canNotBeEmpty"],字串陣列,哪些必填參數的內容不得為空字串或空陣列,僅當$conf["canBeEmptyString"]為"true"時會生效.
4939
		#$conf["canNotBeEmpty"]=array();
4940
		#$conf["canBeEmpty"],字串陣列,哪些必填參數的內容可為空字串或空陣列,僅當$conf["canBeEmptyString"]為"false"時會生效.
4941
		#$conf["canBeEmpty"]=array();
4942
		#$conf["skipableVariableCanNotBeEmpty"],字串陣列,哪些可省略參數不可以為空字串或空陣列.
4943
		$conf["variableCheck::checkArguments"]["skipableVariableCanNotBeEmpty"]=array("ip","welcomeMsg");
4944
		#$conf["skipableVariableName"],陣列字串,爲可省略參數的變數名稱陣列,形態爲陣列變數,例如: $conf["skipableVariableName"] = array("id","account","password");
4945
		$conf["variableCheck::checkArguments"]["skipableVariableName"]=array("ip","processFuncs","welcomeMsg","socketSelectTimeountSec","socketSelectTimeountUsec","serverFuncs");
4946
		#$conf["skipableVariableType"],陣列字串,爲可省略參數的變數名稱陣列,形態爲陣列變數,例如: $conf["skipableVariableType"] = array("string",integer,"double"); 
4947
		$conf["variableCheck::checkArguments"]["skipableVariableType"]=array("string","array","string","integer","integer","array");
4948
		#$conf["skipableVarDefaultValue"],字串陣列,每個不存在的可省略變數要初始化為什麼,null與代表不指定,若預設值是參數之一,請將$conf["mustBeFilledVar"]改成"\$conf["\mustBeFilledVar\"]".
4949
		$conf["variableCheck::checkArguments"]["skipableVarDefaultValue"]=array("0.0.0.0",array(),"true",0,null,null);
4950
		#$conf["disallowAllSkipableVarIsEmpty"],字串,是否允許每個可省略參數都為空字串,預設為"true"允許,反之為"false".
4951
		#$conf["disallowAllSkipableVarIsEmpty"]="";
4952
		#$conf["disallowAllSkipableVarIsEmptyArray"],字串,是否允許每個可省略參數都為空陣列,預設為"true"允許,反之為"false".
4953
		#$conf["disallowAllSkipableVarIsEmptyArray"]="";
4954
		#$conf["arrayCountEqualCheck"],字串陣列,為檢查哪些陣列參數的元素數量要一樣,$conf["arrayCountEqualCheck"][$i]=array()為第$i組key為哪些的變數其元素數量要相等.
4955
		#$conf["arrayCountEqualCheck"][]=array();
4956
		#參考資料來源:
4957
		#array_keys=>http://php.net/manual/en/function.array-keys.php
4958
		$checkArguments=variableCheck::checkArguments($conf["variableCheck::checkArguments"]);
4959
		unset($conf["variableCheck::checkArguments"]);
4960
 
4961
		#如果檢查參數失敗
4962
		if($checkArguments["status"]==="false"){
4963
 
4964
			#設置執行失敗
4965
			$result["status"]="false";
4966
 
4967
			#設置錯誤訊息
4968
			$result["error"]=$checkArguments;
4969
 
4970
			#回傳結果
4971
			return $result;
4972
 
4973
			}#if end
4974
 
4975
		#如果檢查參數不通過
4976
		if($checkArguments["passed"]==="false"){
4977
 
4978
			#設置執行失敗
4979
			$result["status"]="false";
4980
 
4981
			#設置錯誤訊息
4982
			$result["error"]=$checkArguments;
4983
 
4984
			#回傳結果
4985
			return $result;
4986
 
4987
			}#if end
4988
 
4989
		#程式不會 timeout
4990
		set_time_limit(0);
4991
 
4992
		#Turn on implicit output flushing so we see what we're getting as it comes in.
4993
		ob_implicit_flush();
4994
 
4995
		#set listen ip and port
4996
		$address = $conf["ip"];
4997
 
4998
		#set listen port
4999
		$port = $conf["port"];
5000
 
5001
		//如果建立 socket 失敗
5002
		if (($sock = socket_create(AF_INET, SOCK_STREAM, SOL_TCP)) === false) {
5003
 
5004
		    	echo "socket_create() failed: reason: " . socket_strerror(socket_last_error()) . PHP_EOL;
5005
 
5006
			}#if end
5007
 
5008
		//如果 bind socket 失敗
5009
		if (socket_bind($sock, $address, $port) === false) {
5010
 
5011
		    	echo "socket_bind() failed: reason: " . socket_strerror(socket_last_error($sock)) . PHP_EOL;
5012
 
5013
			}#if end
5014
 
5015
		//如果 socket listen 超過 5 秒仍未成功
5016
		if (socket_listen($sock, 5) === false) {
5017
 
5018
		    	echo "socket_listen() failed: reason: " . socket_strerror(socket_last_error($sock)) . PHP_EOL;
5019
 
5020
			}#if end
5021
 
5022
		// create a list of all the clients that will be connected to us..
5023
    		// add the listening socket to this list
5024
    		$clients = array("serverSock"=>$sock);
5025
 
5026
		#無窮迴圈
5027
		do {
5028
			#each resource
5029
			foreach($clients as $rk=>$csock){
5030
 
5031
				#if not socket resource
5032
				if(get_resource_type($csock)!=="Socket"){
5033
 
5034
					#delete
5035
					unset($clients[$rk]);
5036
 
5037
					}#if end
5038
 
5039
				}#foreach end
5040
 
5041
			#found server sock
5042
			$serverSock=false;
5043
 
5044
			#each resource
5045
			foreach($clients as $rk=>$csock){
5046
 
5047
				#if not socket resource
5048
				if($rk==="serverSock"){
5049
 
5050
					#found server sock
5051
					$serverSock=true;
5052
 
5053
					}#if end
5054
 
5055
				}#if end
5056
 
5057
			#not found server sock
5058
			if(!$serverSock){
5059
 
5060
				#end
5061
				exit;
5062
 
5063
				}#if end
5064
 
5065
			#for socket select
5066
			$read   = $clients;
5067
			$write  = NULL;
5068
			$except = NULL;
5069
 
5070
			#如果沒設定微妙
5071
			if(!isset($conf["socketSelectTimeountUsec"])){			
5072
 
5073
				#get interesting socket	
5074
				$num_changed_sockets = socket_select($read, $write, $except, $conf["socketSelectTimeountSec"]);
5075
 
5076
				}#if end
5077
 
5078
			#反之有設定微妙
5079
			else{
5080
 
5081
				#get interesting socket
5082
				$num_changed_sockets = socket_select($read, $write, $except, $conf["socketSelectTimeountSec"], $conf["socketSelectTimeountUsec"]);
5083
 
5084
				}#else end
5085
 
5086
			#socket_select failed
5087
			if ($num_changed_sockets === false) {
5088
 
5089
				#NOTICE to server
5090
				echo "socket_select failed".PHP_EOL;
5091
 
5092
				} 
5093
 
5094
			#At least at one of the sockets something interesting happened
5095
			else if ($num_changed_sockets > 0) {
5096
 
5097
				/* debug		
5098
				echo "At least at one of the sockets something interesting happened".PHP_EOL;
5099
				echo "\$read:".PHP_EOL;var_dump($read);
5100
				echo "\$write:".PHP_EOL;var_dump($write);
5101
				echo "\$except:".PHP_EOL;var_dump($except);
5102
				*/
5103
 
5104
				// check if there is a client trying to connect
5105
				if (in_array($sock, $read)) {
5106
 
5107
					#accept the client, and add him to the $clients array
5108
				   	$clients[] = $newsock = socket_accept($sock);
5109
 
5110
				   	#如果要顯示歡迎訊息
5111
					if($conf["welcomeMsg"]==="true"){
5112
 
5113
				   		#send the client a welcome message
5114
				   		socket_write($newsock, "Welcome to QBPWCF tcpServer".PHP_EOL.
5115
				   		"There are ".(count($clients) - 1)." client(s) connected to the server".PHP_EOL);
5116
 
5117
				   		}#if end
5118
 
5119
					#嘗試取得遠端的ip與port
5120
					#參考資料:https://www.php.net/manual/en/function.socket-getpeername.php
5121
				 	@socket_getpeername($newsock, $ip);
5122
 
5123
					#如果有抓到 $ip
5124
					if(isset($ip)){
5125
 
5126
						#提示有新的使用者
5127
						echo "New client connected: ".$ip.PHP_EOL;
5128
 
5129
						}#if end
5130
 
5131
					// remove the listening socket from the clients-with-data array
5132
					$key = array_search($sock, $read);
5133
					unset($read[$key]);
5134
 
5135
					}
5136
 
5137
				#message received
5138
				else{
5139
 
5140
					// loop through all the clients that have data to read from
5141
					foreach ($read as $read_sock) {
5142
 
5143
						// read until newline or 1024 bytes
5144
						// socket_read while show errors when the client is disconnected, so silence the error messages
5145
						$data = @socket_read($read_sock, 1024, PHP_NORMAL_READ);
5146
 
5147
						// check if the client is disconnected
5148
						if ($data === false) 
5149
						{
5150
							// remove client for $clients array
5151
							$key = array_search($read_sock, $clients);
5152
							unset($clients[$key]);
5153
							echo "client disconnected.".PHP_EOL;
5154
 
5155
							// continue to the next client to read from, if any
5156
							continue;
5157
						}
5158
 
5159
						// trim off the trailing/beginning white spaces
5160
						$data = trim($data);
5161
 
5162
						// check if there is any data after trimming off the spaces
5163
						if(!empty($data)){
5164
 
5165
							// send this to all the clients in the $clients array (except the first one, which is a listening socket)
5166
							foreach ($clients as $send_sock) {
5167
 
5168
								// if its the listening sock or the client that we got the message from, go to the next one in the list
5169
 
5170
								#如果是Server Socket	
5171
								if ($send_sock === $sock){
5172
 
5173
									#server debug
5174
									echo "reveiced:".$data.PHP_EOL;													
5175
 
5176
									#針對每個用來處理輸入字串的函式
5177
									foreach($conf["processFuncs"] as $proFunc){
5178
 
5179
										#呼叫函式,參數為輸入的字串data跟client socket, server socket, 每個 socket
5180
										#https://www.php.net/manual/en/function.call-user-func.php
5181
										$param=array("data"=>$data,"serverSock"=>$sock,"clientSock"=>$read_sock,"allSockArray"=>$clients);
5182
										$params=array();
5183
										$params[]=&$param;										
5184
										$result=call_user_func_array($proFunc,$params);						
5185
 
5186
										#如果有回傳結果
5187
										if($result!==NULL){
5188
 
5189
											#如果執行出錯
5190
											if($result["status"]==="false"){
5191
 
5192
												#印出結果
5193
												var_dump($result);
5194
 
5195
												}
5196
 
5197
											}
5198
 
5199
										}
5200
									}
5201
 
5202
								/*
5203
								#如果是Sender Socket
5204
								else if ($send_sock === $read_sock){
5205
 
5206
									continue;
5207
 
5208
									}
5209
								*/						   
5210
 
5211
								/*
5212
								#msg to others/broadcast
5213
								else{
5214
 
5215
						    			// write the message to the client -- add a newline character to the end of the message
5216
						    			socket_write($send_sock, $data.PHP_EOL);
5217
 
5218
									}//end of broadcast
5219
								*/						   
5220
 
5221
								} //foreach end
5222
 
5223
							}#if end
5224
 
5225
						} // end of reading foreach
5226
 
5227
					}#msg received end
5228
 
5229
				}#something happen end
5230
 
5231
			#反之沒有用戶插手
5232
			else{
5233
				#提示idle
5234
				#echo "idle:".time().PHP_EOL;
5235
 
5236
				#如果沒有設置 $conf["serverFuncs"]
5237
				if(!isset($conf["serverFuncs"])){
5238
 
5239
					#設置為空陣列
5240
					$conf["serverFuncs"]=array();
5241
 
5242
					}#if end
5243
 
5244
				#針對每個用來處理輸入字串的函式
5245
				foreach($conf["serverFuncs"] as $proFunc){
5246
 
5247
					#呼叫函式,參數為輸入的字串data跟client socket, server socket, 每個 socket
5248
					#https://www.php.net/manual/en/function.call-user-func.php
5249
					$result=call_user_func_array($proFunc,array());						
5250
 
5251
					#如果有回傳結果
5252
					if($result!==NULL){
5253
 
5254
						#如果執行出錯
5255
						if($result["status"]==="false"){
5256
 
5257
							#印出結果
5258
							var_dump($result);
5259
 
5260
							}//if end
5261
 
5262
						}//if end
5263
 
5264
					}//foreach end
5265
 
5266
				}#else end
5267
 
5268
			} while (true);
5269
 
5270
		#關閉listen的socket
5271
		socket_close($sock);
5272
 
5273
		}
5274
		#function tcpServer end
5275
 
5276
	/*
5277
	#函式說明:
5278
	#建立 udp server
5279
	#必填參數:
5280
	#$conf["port"],整數,udp server listen port.
5281
	$conf["port"]=;
5282
	#可省略參數:
5283
	#$conf["ip"],整數字串,udp serer listen ip, default is 0.0.0.0.
5284
	#$conf["ip"]="0.0.0.0";
5285
	#$conf["processFuncs"],字串陣列,要將收到的訊息作什麼事情的函式們,預設為空陣列.
5286
	#$conf["processFuncs"]=array();
5287
	#$conf["welcomeMsg"],字串,是否要顯示歡迎訊息,預設為"true"代表要顯示歡迎訊息;"false"代表不要顯示歡迎訊息.
5288
	#$conf["welcomeMsg"]="true";
5289
	#$conf["socketSelectTimeountSec"],整數,代表要等候幾秒才抓取有異動的連線,預設為0代表立即抓取有異動的連線,但是會吃很多cpu.
5290
	#$conf["socketSelectTimeountSec"]=0;
5291
	#$conf["socketSelectTimeountUsec"],整數,代表要等候幾微秒才抓取有異動的連線,預設不使用.
5292
	#$conf["socketSelectTimeountUsec"]=5000;
5293
	#參考資料:
5294
	#https://www.jianshu.com/p/097463d08664
5295
	#備註:
5296
	#無.
5297
	*/
5298
	public static function udpServer(&$conf){
5299
 
5300
		#初始化要回傳的結果
5301
		$result=array();
5302
 
5303
		#取得當前執行的函數名稱
5304
		$result["function"]=__FUNCTION__;
5305
 
5306
		#如果沒有參數
5307
		if(func_num_args()==0){
5308
 
5309
			#設置執行失敗
5310
			$result["status"]="false";
5311
 
5312
			#設置執行錯誤訊息
5313
			$result["error"]="函數".$result["function"]."需要參數";
5314
 
5315
			#回傳結果
5316
			return $result;
5317
 
5318
			}#if end
5319
 
5320
		#涵式說明:
5321
		#判斷當前環境為web還是cmd
5322
		#回傳結果:
5323
		#$result,"web"或"cmd"
5324
		if(csInformation::getEnv()==="web"){
5325
 
5326
			#設置執行失敗
5327
			$result["status"]="false";
5328
 
5329
			#設置執行錯誤訊息
5330
			$result["error"][]="函數 ".$result["function"]." 僅能在命令列環境下運行!";
5331
 
5332
			#回傳結果
5333
			return $result;
5334
 
5335
			}#if end
5336
 
5337
		#取得參數
5338
		$result["argu"]=$conf;
5339
 
5340
		#如果 $conf 不為陣列
5341
		if(gettype($conf)!="array"){
5342
 
5343
			#設置執行失敗
5344
			$result["status"]="false";
5345
 
5346
			#設置執行錯誤訊息
5347
			$result["error"][]="\$conf變數須為陣列形態";
5348
 
5349
			#如果傳入的參數為 null
5350
			if($conf==null){
5351
 
5352
				#設置執行錯誤訊息
5353
				$result["error"][]="\$conf變數不得為null,請檢查函數「".$result["function"]."」的參數設置有無正確!";
5354
 
5355
				}#if end
5356
 
5357
			#回傳結果
5358
			return $result;
5359
 
5360
			}#if end
5361
 
5362
		#檢查參數
5363
		#函式說明:
5364
		#檢查必填與可省略的參數,可省略參數可指定預設要給與什麼數值內容。
5365
		#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
5366
		#$reuslt["error"],執行不正常結束的錯訊息陣列.
5367
		#$result["function"],當前執行的函式名稱.
5368
		#$result["argu"],設置給予的參數.
5369
		#$result["passed"],識別要檢查的全體變數是否存在以及型態是否正確的變數,"true"代表檢查全部通過;"false"代表檢查不通過
5370
		#$result[$shouldBeCheckedVarName]["varExist"],所檢查的變數是否存在,"false"代表不存在;"true"代表存在
5371
		#$result[$shouldBeCheckedVarName]["varType"],所檢查的變數型態是否正確,"false"代表錯誤;"true"代表正確
5372
		#$result[$shouldBeCheckedVarName]["error"],每個參數設定的錯誤訊息
5373
		#$result["shouldNotBeEmpty"],不應該為空字串或控陣列的變數.
5374
		#$result["argu"],字串陣列,目前輸入的參數名稱陣列.
5375
		#$result["legalVarName"],字串陣列,合法可用的參數名稱陣列.
5376
		#$result["notNeedVar"],字串陣列,多餘的參數名稱.
5377
		#必填寫的參數:
5378
		#$conf["varInput"],陣列變數,要檢查的陣列變數,請在要檢查的參數前面加上&,這樣變動的結果才能被套用。
5379
		$conf["variableCheck::checkArguments"]["varInput"]=&$conf;	
5380
		#$conf["referenceVarKey"],字串,$conf參數後面的key值,用於移除不要的參考陣列.
5381
		$conf["variableCheck::checkArguments"]["referenceVarKey"]="variableCheck::checkArguments";
5382
		#可以省略的參數:
5383
		#$conf["mustBeFilledVariableName"],爲必填參數的變數名稱陣列,形態爲陣列變數,元素數量需要跟"mustBeFilledVariableType"參數的元素數量一致,例如: $conf["mustBeFilledVariableName"] = array("id","account","password");
5384
		$conf["variableCheck::checkArguments"]["mustBeFilledVariableName"]=array("port");
5385
		#$conf["mustBeFilledVariableType"],爲必填參數的變數陣列應該爲何種變數形態,形態爲陣列,元素數量需要跟"mustBeFilledVariableName"參數的元素數量一致,例如: $conf["mustBeFilledVariableType"] = array("string",integer,"double","resource","object"); , null代表不指定變數形態.
5386
		$conf["variableCheck::checkArguments"]["mustBeFilledVariableType"]=array("integer");
5387
		#$conf["canBeEmptyString"],字串,必填變數內容如果是空字串就不能算是有設置的話,請設為"false",預設爲"true",可以為空字串.
5388
		#$conf["canBeEmptyString"]="false";
5389
		#$conf["canNotBeEmpty"],字串陣列,哪些必填參數的內容不得為空字串或空陣列,僅當$conf["canBeEmptyString"]為"true"時會生效.
5390
		#$conf["canNotBeEmpty"]=array();
5391
		#$conf["canBeEmpty"],字串陣列,哪些必填參數的內容可為空字串或空陣列,僅當$conf["canBeEmptyString"]為"false"時會生效.
5392
		#$conf["canBeEmpty"]=array();
5393
		#$conf["skipableVariableCanNotBeEmpty"],字串陣列,哪些可省略參數不可以為空字串或空陣列.
5394
		$conf["variableCheck::checkArguments"]["skipableVariableCanNotBeEmpty"]=array("ip","welcomeMsg","socketSelectTimeountUsec");
5395
		#$conf["skipableVariableName"],陣列字串,爲可省略參數的變數名稱陣列,形態爲陣列變數,例如: $conf["skipableVariableName"] = array("id","account","password");
5396
		$conf["variableCheck::checkArguments"]["skipableVariableName"]=array("ip","processFuncs","welcomeMsg","socketSelectTimeountSec","socketSelectTimeountUsec");
5397
		#$conf["skipableVariableType"],陣列字串,爲可省略參數的變數名稱陣列,形態爲陣列變數,例如: $conf["skipableVariableType"] = array("string",integer,"double"); 
5398
		$conf["variableCheck::checkArguments"]["skipableVariableType"]=array("string","array","string","integer","integer");
5399
		#$conf["skipableVarDefaultValue"],字串陣列,每個不存在的可省略變數要初始化為什麼,null與代表不指定,若預設值是參數之一,請將$conf["mustBeFilledVar"]改成"\$conf["\mustBeFilledVar\"]".
5400
		$conf["variableCheck::checkArguments"]["skipableVarDefaultValue"]=array("0.0.0.0",array(),"true",0,null);
5401
		#$conf["disallowAllSkipableVarIsEmpty"],字串,是否允許每個可省略參數都為空字串,預設為"true"允許,反之為"false".
5402
		#$conf["disallowAllSkipableVarIsEmpty"]="";
5403
		#$conf["disallowAllSkipableVarIsEmptyArray"],字串,是否允許每個可省略參數都為空陣列,預設為"true"允許,反之為"false".
5404
		#$conf["disallowAllSkipableVarIsEmptyArray"]="";
5405
		#$conf["arrayCountEqualCheck"],字串陣列,為檢查哪些陣列參數的元素數量要一樣,$conf["arrayCountEqualCheck"][$i]=array()為第$i組key為哪些的變數其元素數量要相等.
5406
		#$conf["arrayCountEqualCheck"][]=array();
5407
		#參考資料來源:
5408
		#array_keys=>http://php.net/manual/en/function.array-keys.php
5409
		$checkArguments=variableCheck::checkArguments($conf["variableCheck::checkArguments"]);
5410
		unset($conf["variableCheck::checkArguments"]);
5411
 
5412
		#如果檢查參數失敗
5413
		if($checkArguments["status"]==="false"){
5414
 
5415
			#設置執行失敗
5416
			$result["status"]="false";
5417
 
5418
			#設置錯誤訊息
5419
			$result["error"]=$checkArguments;
5420
 
5421
			#回傳結果
5422
			return $result;
5423
 
5424
			}#if end
5425
 
5426
		#如果檢查參數不通過
5427
		if($checkArguments["passed"]==="false"){
5428
 
5429
			#設置執行失敗
5430
			$result["status"]="false";
5431
 
5432
			#設置錯誤訊息
5433
			$result["error"]=$checkArguments;
5434
 
5435
			#回傳結果
5436
			return $result;
5437
 
5438
			}#if end
5439
 
5440
		#Allow the script to hang around waiting for connections.
5441
		set_time_limit(0);
5442
 
5443
		#Turn on implicit output flushing so we see what we're getting as it comes in.
5444
		ob_implicit_flush();
5445
 
5446
		#set listen ip and port
5447
		$address = $conf["ip"];
5448
 
5449
		#set listen port
5450
		$port = $conf["port"];
5451
 
5452
		//如果建立 socket 失敗
5453
		if (($sock = socket_create(AF_INET, SOCK_DGRAM, SOL_UDP)) === false) {
5454
 
5455
		    	echo "socket_create() failed: reason: " . socket_strerror(socket_last_error()) . PHP_EOL;
5456
 
5457
			}#if end
5458
 
5459
		//如果 bind socket 失敗
5460
		if (socket_bind($sock, $address, $port) === false) {
5461
 
5462
		    	echo "socket_bind() failed: reason: " . socket_strerror(socket_last_error($sock)) . PHP_EOL;
5463
 
5464
			}#if end
5465
 
5466
		// create a list of all the clients that will be connected to us..
5467
    		// add the listening socket to this list
5468
    		$clients = array("serverSock"=>$sock);
5469
 
5470
		#無窮迴圈
5471
		do {
5472
			#each resource
5473
			foreach($clients as $rk=>$csock){
5474
 
5475
				#if not socket resource				
5476
				if(gettype($csock)==="boolean"){
5477
 
5478
					#delete
5479
					unset($clients[$rk]);
5480
 
5481
					}
5482
 
5483
				#if not socket resource
5484
				else if(get_resource_type($csock)!=="Socket"){
5485
 
5486
					#delete
5487
					unset($clients[$rk]);
5488
 
5489
					}									
5490
				}
5491
 
5492
			#found server sock
5493
			$serverSock=false;
5494
 
5495
			#each resource
5496
			foreach($clients as $rk=>$csock){
5497
 
5498
				#if not socket resource
5499
				if($rk==="serverSock"){
5500
 
5501
					#found server sock
5502
					$serverSock=true;
5503
 
5504
					}					
5505
				}
5506
 
5507
			#not found server sock
5508
			if(!$serverSock){
5509
 
5510
				#end
5511
				exit;
5512
 
5513
				}
5514
 
5515
			#for socket select
5516
			$read   = $clients;
5517
			$write  = NULL;
5518
			$except = NULL;
5519
 
5520
			#如果未設置 $conf["socketSelectTimeountUsec"]
5521
			if(!isset($conf["socketSelectTimeountUsec"])){
5522
 
5523
				#get interesting socket
5524
				$num_changed_sockets = socket_select($read, $write, $except, $conf["socketSelectTimeountSec"]);
5525
 
5526
				}#if end
5527
 
5528
			#反之有設置 $conf["socketSelectTimeountUsec"]
5529
			else{
5530
 
5531
				#get interesting socket
5532
				$num_changed_sockets = socket_select($read, $write, $except, $conf["socketSelectTimeountSec"], $conf["socketSelectTimeountUsec"]);
5533
 
5534
				}#else end
5535
 
5536
			#socket_select failed
5537
			if ($num_changed_sockets === false) {
5538
 
5539
				#NOTICE to server
5540
				echo "socket_select failed".PHP_EOL;
5541
 
5542
				}#if end
5543
 
5544
			#At least at one of the sockets something interesting happened
5545
			else if ($num_changed_sockets > 0) {
5546
 
5547
				// check if there is a client trying to connect
5548
				if (in_array($sock, $read)) {
5549
 
5550
					#accept the client, and add him to the $clients array
5551
				   	$receivedBytes=socket_recvfrom($sock,$data,1024,0,$remote_ip,$remote_port);	
5552
					$key=$remote_ip.":".$remote_port;
5553
					$clients[$key] = $newsock = $sock;
5554
 
5555
					#如果要顯示歡迎訊息
5556
					if($conf["welcomeMsg"]==="true"){
5557
 
5558
						# send the client a welcome message
5559
					   	socket_sendto($newsock, "Welcome to QBPWCF udpServer".PHP_EOL."There are ".(count($clients) - 1)." client(s) connected to the server".PHP_EOL, 1024, 0, $remote_ip, $remote_port);
5560
 
5561
						}#if end
5562
 
5563
					#debug
5564
					echo "client connected:".$key.PHP_EOL;
5565
					echo "client sended:".$data;
5566
					echo "all client:".PHP_EOL;
5567
					var_dump($clients);				
5568
 
5569
					#針對每個用來處理輸入字串的函式
5570
					foreach($conf["processFuncs"] as $proFunc){
5571
 
5572
						#呼叫函式,參數為輸入的字串data跟client socket, server socket, 每個 socket
5573
						#https://www.php.net/manual/en/function.call-user-func.php
5574
						$param=array("data"=>trim($data),"serverSock"=>$sock,"clientKey"=>$key,"allSockArray"=>&$clients);
5575
						$params=array();
5576
						$params[]=&$param;										
5577
						$result=call_user_func_array($proFunc,$params);						
5578
 
5579
						#如果有回傳結果
5580
						if($result!==NULL){
5581
 
5582
							#如果執行出錯
5583
							if($result["status"]==="false"){
5584
 
5585
								#印出結果
5586
								var_dump($result);
5587
 
5588
								}
5589
 
5590
							}
5591
 
5592
						}
5593
 
5594
					#debug
5595
					echo "last all client:".PHP_EOL;
5596
					var_dump($clients);
5597
 
5598
					# remove the listening socket from the clients-with-data array
5599
					$key = array_search($sock, $read);
5600
					unset($read[$key]);
5601
 
5602
					}#if end
5603
 
5604
				}#something happen end
5605
 
5606
			} while (true);
5607
 
5608
		#關閉listen的socket
5609
		socket_close($sock);
5610
 
5611
		}
5612
		#function tcpServer end
5613
 
5614
	/*
5615
	#函式說明:
5616
	#針對收到的內容,原封不動地傳回給用戶.
5617
	#必填參數:
5618
	#$conf["data"],字串,要處理的內容.
5619
	$conf["data"]="";
5620
	#$conf["clientSock"],resource socket.
5621
	$conf["clientSock"]=;
5622
	#$conf["serverSock"],resource socket.
5623
	$conf["serverSock"]=;
5624
	#$conf["allSockArray"],resource陣列.
5625
	$conf["allSockArray"]=array();
5626
	#可省略參數:
5627
	#無.
5628
	#參考資料:
5629
	#無.
5630
	#備註:
5631
	#無.
5632
	*/
5633
	public function echoService(&$conf){
5634
 
5635
		#初始化要回傳的結果
5636
		$result=array();
5637
 
5638
		#取得當前執行的函數名稱
5639
		$result["function"]=__FUNCTION__;
5640
 
5641
		#如果沒有參數
5642
		if(func_num_args()==0){
5643
 
5644
			#設置執行失敗
5645
			$result["status"]="false";
5646
 
5647
			#設置執行錯誤訊息
5648
			$result["error"]="函數".$result["function"]."需要參數";
5649
 
5650
			#回傳結果
5651
			return $result;
5652
 
5653
			}#if end
5654
 
5655
		#涵式說明:
5656
		#判斷當前環境為web還是cmd
5657
		#回傳結果:
5658
		#$result,"web"或"cmd"
5659
		if(csInformation::getEnv()==="web"){
5660
 
5661
			#設置執行失敗
5662
			$result["status"]="false";
5663
 
5664
			#設置執行錯誤訊息
5665
			$result["error"][]="函數 ".$result["function"]." 僅能在命令列環境下運行!";
5666
 
5667
			#回傳結果
5668
			return $result;
5669
 
5670
			}#if end
5671
 
5672
		#取得參數
5673
		$result["argu"]=$conf;
5674
 
5675
		#如果 $conf 不為陣列
5676
		if(gettype($conf)!="array"){
5677
 
5678
			#設置執行失敗
5679
			$result["status"]="false";
5680
 
5681
			#設置執行錯誤訊息
5682
			$result["error"][]="\$conf變數須為陣列形態";
5683
 
5684
			#如果傳入的參數為 null
5685
			if($conf==null){
5686
 
5687
				#設置執行錯誤訊息
5688
				$result["error"][]="\$conf變數不得為null,請檢查函數「".$result["function"]."」的參數設置有無正確!";
5689
 
5690
				}#if end
5691
 
5692
			#回傳結果
5693
			return $result;
5694
 
5695
			}#if end
5696
 
5697
		#檢查參數
5698
		#函式說明:
5699
		#檢查必填與可省略的參數,可省略參數可指定預設要給與什麼數值內容。
5700
		#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
5701
		#$reuslt["error"],執行不正常結束的錯訊息陣列.
5702
		#$result["function"],當前執行的函式名稱.
5703
		#$result["argu"],設置給予的參數.
5704
		#$result["passed"],識別要檢查的全體變數是否存在以及型態是否正確的變數,"true"代表檢查全部通過;"false"代表檢查不通過
5705
		#$result[$shouldBeCheckedVarName]["varExist"],所檢查的變數是否存在,"false"代表不存在;"true"代表存在
5706
		#$result[$shouldBeCheckedVarName]["varType"],所檢查的變數型態是否正確,"false"代表錯誤;"true"代表正確
5707
		#$result[$shouldBeCheckedVarName]["error"],每個參數設定的錯誤訊息
5708
		#$result["shouldNotBeEmpty"],不應該為空字串或控陣列的變數.
5709
		#$result["argu"],字串陣列,目前輸入的參數名稱陣列.
5710
		#$result["legalVarName"],字串陣列,合法可用的參數名稱陣列.
5711
		#$result["notNeedVar"],字串陣列,多餘的參數名稱.
5712
		#必填寫的參數:
5713
		#$conf["varInput"],陣列變數,要檢查的陣列變數,請在要檢查的參數前面加上&,這樣變動的結果才能被套用。
5714
		$conf["variableCheck::checkArguments"]["varInput"]=&$conf;	
5715
		#$conf["referenceVarKey"],字串,$conf參數後面的key值,用於移除不要的參考陣列.
5716
		$conf["variableCheck::checkArguments"]["referenceVarKey"]="variableCheck::checkArguments";
5717
		#可以省略的參數:
5718
		#$conf["mustBeFilledVariableName"],爲必填參數的變數名稱陣列,形態爲陣列變數,元素數量需要跟"mustBeFilledVariableType"參數的元素數量一致,例如: $conf["mustBeFilledVariableName"] = array("id","account","password");
5719
		$conf["variableCheck::checkArguments"]["mustBeFilledVariableName"]=array("data","clientSock","serverSock","allSockArray");
5720
		#$conf["mustBeFilledVariableType"],爲必填參數的變數陣列應該爲何種變數形態,形態爲陣列,元素數量需要跟"mustBeFilledVariableName"參數的元素數量一致,例如: $conf["mustBeFilledVariableType"] = array("string",integer,"double","resource","object"); , null代表不指定變數形態.
5721
		$conf["variableCheck::checkArguments"]["mustBeFilledVariableType"]=array("string","resource","resource","array");
5722
		#$conf["canBeEmptyString"],字串,必填變數內容如果是空字串就不能算是有設置的話,請設為"false",預設爲"true",可以為空字串.
5723
		#$conf["canBeEmptyString"]="false";
5724
		#$conf["canNotBeEmpty"],字串陣列,哪些必填參數的內容不得為空字串或空陣列,僅當$conf["canBeEmptyString"]為"true"時會生效.
5725
		#$conf["canNotBeEmpty"]=array();
5726
		#$conf["canBeEmpty"],字串陣列,哪些必填參數的內容可為空字串或空陣列,僅當$conf["canBeEmptyString"]為"false"時會生效.
5727
		#$conf["canBeEmpty"]=array();
5728
		#$conf["skipableVariableCanNotBeEmpty"],字串陣列,哪些可省略參數不可以為空字串或空陣列.
5729
		#$conf["variableCheck::checkArguments"]["skipableVariableCanNotBeEmpty"]=array("ip");
5730
		#$conf["skipableVariableName"],陣列字串,爲可省略參數的變數名稱陣列,形態爲陣列變數,例如: $conf["skipableVariableName"] = array("id","account","password");
5731
		#$conf["variableCheck::checkArguments"]["skipableVariableName"]=array("ip","processFuncs");
5732
		#$conf["skipableVariableType"],陣列字串,爲可省略參數的變數名稱陣列,形態爲陣列變數,例如: $conf["skipableVariableType"] = array("string",integer,"double"); 
5733
		#$conf["variableCheck::checkArguments"]["skipableVariableType"]=array("string","array");
5734
		#$conf["skipableVarDefaultValue"],字串陣列,每個不存在的可省略變數要初始化為什麼,null與代表不指定,若預設值是參數之一,請將$conf["mustBeFilledVar"]改成"\$conf["\mustBeFilledVar\"]".
5735
		#$conf["variableCheck::checkArguments"]["skipableVarDefaultValue"]=array("0.0.0.0",array());
5736
		#$conf["disallowAllSkipableVarIsEmpty"],字串,是否允許每個可省略參數都為空字串,預設為"true"允許,反之為"false".
5737
		#$conf["disallowAllSkipableVarIsEmpty"]="";
5738
		#$conf["disallowAllSkipableVarIsEmptyArray"],字串,是否允許每個可省略參數都為空陣列,預設為"true"允許,反之為"false".
5739
		#$conf["disallowAllSkipableVarIsEmptyArray"]="";
5740
		#$conf["arrayCountEqualCheck"],字串陣列,為檢查哪些陣列參數的元素數量要一樣,$conf["arrayCountEqualCheck"][$i]=array()為第$i組key為哪些的變數其元素數量要相等.
5741
		#$conf["arrayCountEqualCheck"][]=array();
5742
		#參考資料來源:
5743
		#array_keys=>http://php.net/manual/en/function.array-keys.php
5744
		$checkArguments=variableCheck::checkArguments($conf["variableCheck::checkArguments"]);
5745
		unset($conf["variableCheck::checkArguments"]);
5746
 
5747
		#如果檢查參數失敗
5748
		if($checkArguments["status"]==="false"){
5749
 
5750
			#設置執行失敗
5751
			$result["status"]="false";
5752
 
5753
			#設置錯誤訊息
5754
			$result["error"]=$checkArguments;
5755
 
5756
			#回傳結果
5757
			return $result;
5758
 
5759
			}#if end
5760
 
5761
		#如果檢查參數不通過
5762
		if($checkArguments["passed"]==="false"){
5763
 
5764
			#設置執行失敗
5765
			$result["status"]="false";
5766
 
5767
			#設置錯誤訊息
5768
			$result["error"]=$checkArguments;
5769
 
5770
			#回傳結果
5771
			return $result;
5772
 
5773
			}#if end
5774
 
5775
		#將內容原封不動還給 client
5776
		@socket_write($conf["clientSock"], $conf["data"].PHP_EOL);
5777
 
5778
		}#function echoService end
5779
 
5780
	/*
5781
	#函式說明:
5782
	#針對收到的內容,原封不動地傳回給用戶.協定為UDP.
5783
	#回傳結果:
5784
	#無.
5785
	#必填參數:
5786
	#$conf["data"],字串,要處理的內容.
5787
	$conf["data"]="";
5788
	#$conf["clientKey"],resource socket key
5789
	$conf["clientKey"]=;
5790
	#$conf["serverSock"],resource socket.
5791
	$conf["serverSock"]=;
5792
	#$conf["allSockArray"],resource陣列.
5793
	$conf["allSockArray"]=array();
5794
	#可省略參數:
5795
	#無.
5796
	#參考資料:
5797
	#無.
5798
	#備註:
5799
	#無.
5800
	*/
5801
	public function echoServiceU(&$conf){
5802
 
5803
		#初始化要回傳的結果
5804
		$result=array();
5805
 
5806
		#取得當前執行的函數名稱
5807
		$result["function"]=__FUNCTION__;
5808
 
5809
		#如果沒有參數
5810
		if(func_num_args()==0){
5811
 
5812
			#設置執行失敗
5813
			$result["status"]="false";
5814
 
5815
			#設置執行錯誤訊息
5816
			$result["error"]="函數".$result["function"]."需要參數";
5817
 
5818
			#回傳結果
5819
			return $result;
5820
 
5821
			}#if end
5822
 
5823
		#涵式說明:
5824
		#判斷當前環境為web還是cmd
5825
		#回傳結果:
5826
		#$result,"web"或"cmd"
5827
		if(csInformation::getEnv()==="web"){
5828
 
5829
			#設置執行失敗
5830
			$result["status"]="false";
5831
 
5832
			#設置執行錯誤訊息
5833
			$result["error"][]="函數 ".$result["function"]." 僅能在命令列環境下運行!";
5834
 
5835
			#回傳結果
5836
			return $result;
5837
 
5838
			}#if end
5839
 
5840
		#取得參數
5841
		$result["argu"]=$conf;
5842
 
5843
		#如果 $conf 不為陣列
5844
		if(gettype($conf)!="array"){
5845
 
5846
			#設置執行失敗
5847
			$result["status"]="false";
5848
 
5849
			#設置執行錯誤訊息
5850
			$result["error"][]="\$conf變數須為陣列形態";
5851
 
5852
			#如果傳入的參數為 null
5853
			if($conf==null){
5854
 
5855
				#設置執行錯誤訊息
5856
				$result["error"][]="\$conf變數不得為null,請檢查函數「".$result["function"]."」的參數設置有無正確!";
5857
 
5858
				}#if end
5859
 
5860
			#回傳結果
5861
			return $result;
5862
 
5863
			}#if end
5864
 
5865
		#檢查參數
5866
		#函式說明:
5867
		#檢查必填與可省略的參數,可省略參數可指定預設要給與什麼數值內容。
5868
		#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
5869
		#$reuslt["error"],執行不正常結束的錯訊息陣列.
5870
		#$result["function"],當前執行的函式名稱.
5871
		#$result["argu"],設置給予的參數.
5872
		#$result["passed"],識別要檢查的全體變數是否存在以及型態是否正確的變數,"true"代表檢查全部通過;"false"代表檢查不通過
5873
		#$result[$shouldBeCheckedVarName]["varExist"],所檢查的變數是否存在,"false"代表不存在;"true"代表存在
5874
		#$result[$shouldBeCheckedVarName]["varType"],所檢查的變數型態是否正確,"false"代表錯誤;"true"代表正確
5875
		#$result[$shouldBeCheckedVarName]["error"],每個參數設定的錯誤訊息
5876
		#$result["shouldNotBeEmpty"],不應該為空字串或控陣列的變數.
5877
		#$result["argu"],字串陣列,目前輸入的參數名稱陣列.
5878
		#$result["legalVarName"],字串陣列,合法可用的參數名稱陣列.
5879
		#$result["notNeedVar"],字串陣列,多餘的參數名稱.
5880
		#必填寫的參數:
5881
		#$conf["varInput"],陣列變數,要檢查的陣列變數,請在要檢查的參數前面加上&,這樣變動的結果才能被套用。
5882
		$conf["variableCheck::checkArguments"]["varInput"]=&$conf;	
5883
		#$conf["referenceVarKey"],字串,$conf參數後面的key值,用於移除不要的參考陣列.
5884
		$conf["variableCheck::checkArguments"]["referenceVarKey"]="variableCheck::checkArguments";
5885
		#可以省略的參數:
5886
		#$conf["mustBeFilledVariableName"],爲必填參數的變數名稱陣列,形態爲陣列變數,元素數量需要跟"mustBeFilledVariableType"參數的元素數量一致,例如: $conf["mustBeFilledVariableName"] = array("id","account","password");
5887
		$conf["variableCheck::checkArguments"]["mustBeFilledVariableName"]=array("data","clientKey","serverSock","allSockArray");
5888
		#$conf["mustBeFilledVariableType"],爲必填參數的變數陣列應該爲何種變數形態,形態爲陣列,元素數量需要跟"mustBeFilledVariableName"參數的元素數量一致,例如: $conf["mustBeFilledVariableType"] = array("string",integer,"double","resource","object"); , null代表不指定變數形態.
5889
		$conf["variableCheck::checkArguments"]["mustBeFilledVariableType"]=array("string","string","resource","array");
5890
		#$conf["canBeEmptyString"],字串,必填變數內容如果是空字串就不能算是有設置的話,請設為"false",預設爲"true",可以為空字串.
5891
		#$conf["canBeEmptyString"]="false";
5892
		#$conf["canNotBeEmpty"],字串陣列,哪些必填參數的內容不得為空字串或空陣列,僅當$conf["canBeEmptyString"]為"true"時會生效.
5893
		#$conf["canNotBeEmpty"]=array();
5894
		#$conf["canBeEmpty"],字串陣列,哪些必填參數的內容可為空字串或空陣列,僅當$conf["canBeEmptyString"]為"false"時會生效.
5895
		#$conf["canBeEmpty"]=array();
5896
		#$conf["skipableVariableCanNotBeEmpty"],字串陣列,哪些可省略參數不可以為空字串或空陣列.
5897
		#$conf["variableCheck::checkArguments"]["skipableVariableCanNotBeEmpty"]=array("ip");
5898
		#$conf["skipableVariableName"],陣列字串,爲可省略參數的變數名稱陣列,形態爲陣列變數,例如: $conf["skipableVariableName"] = array("id","account","password");
5899
		#$conf["variableCheck::checkArguments"]["skipableVariableName"]=array("ip","processFuncs");
5900
		#$conf["skipableVariableType"],陣列字串,爲可省略參數的變數名稱陣列,形態爲陣列變數,例如: $conf["skipableVariableType"] = array("string",integer,"double"); 
5901
		#$conf["variableCheck::checkArguments"]["skipableVariableType"]=array("string","array");
5902
		#$conf["skipableVarDefaultValue"],字串陣列,每個不存在的可省略變數要初始化為什麼,null與代表不指定,若預設值是參數之一,請將$conf["mustBeFilledVar"]改成"\$conf["\mustBeFilledVar\"]".
5903
		#$conf["variableCheck::checkArguments"]["skipableVarDefaultValue"]=array("0.0.0.0",array());
5904
		#$conf["disallowAllSkipableVarIsEmpty"],字串,是否允許每個可省略參數都為空字串,預設為"true"允許,反之為"false".
5905
		#$conf["disallowAllSkipableVarIsEmpty"]="";
5906
		#$conf["disallowAllSkipableVarIsEmptyArray"],字串,是否允許每個可省略參數都為空陣列,預設為"true"允許,反之為"false".
5907
		#$conf["disallowAllSkipableVarIsEmptyArray"]="";
5908
		#$conf["arrayCountEqualCheck"],字串陣列,為檢查哪些陣列參數的元素數量要一樣,$conf["arrayCountEqualCheck"][$i]=array()為第$i組key為哪些的變數其元素數量要相等.
5909
		#$conf["arrayCountEqualCheck"][]=array();
5910
		#參考資料來源:
5911
		#array_keys=>http://php.net/manual/en/function.array-keys.php
5912
		$checkArguments=variableCheck::checkArguments($conf["variableCheck::checkArguments"]);
5913
		unset($conf["variableCheck::checkArguments"]);
5914
 
5915
		#如果檢查參數失敗
5916
		if($checkArguments["status"]==="false"){
5917
 
5918
			#設置執行失敗
5919
			$result["status"]="false";
5920
 
5921
			#設置錯誤訊息
5922
			$result["error"]=$checkArguments;
5923
 
5924
			#回傳結果
5925
			return $result;
5926
 
5927
			}#if end
5928
 
5929
		#如果檢查參數不通過
5930
		if($checkArguments["passed"]==="false"){
5931
 
5932
			#設置執行失敗
5933
			$result["status"]="false";
5934
 
5935
			#設置錯誤訊息
5936
			$result["error"]=$checkArguments;
5937
 
5938
			#回傳結果
5939
			return $result;
5940
 
5941
			}#if end
5942
 
5943
		#將內容原封不動還給 client
5944
		$strArray=explode(":",$conf["clientKey"]);
5945
		$remote_ip=$strArray[0];
5946
		$remote_port=$strArray[1];
5947
		socket_sendto($conf["serverSock"], $conf["data"].PHP_EOL, 1024, 0, $remote_ip, $remote_port);
5948
 
5949
		}#function echoServiceU end
5950
 
5951
	/*
5952
	#函式說明:
5953
	#針對收到的內容,若是"quit"則斷開用戶的連線,若是"shutdown"則關閉Server Listen的socket.
5954
	#回傳結果:
5955
	#無.
5956
	#必填參數:
5957
	#$conf["data"],字串,要處理的內容.
5958
	$conf["data"]="";
5959
	#$conf["clientSock"],resource socket.
5960
	$conf["clientSock"]=;
5961
	#$conf["serverSock"],resource socket.
5962
	$conf["serverSock"]=;
5963
	#$conf["allSockArray"],resource陣列.
5964
	$conf["allSockArray"]=array();
5965
	#可省略參數:
5966
	#無.
5967
	#參考資料:
5968
	#無.
5969
	#備註:
5970
	#無.
5971
	*/
5972
	public function endService(&$conf){
5973
 
5974
		#初始化要回傳的結果
5975
		$result=array();
5976
 
5977
		#取得當前執行的函數名稱
5978
		$result["function"]=__FUNCTION__;
5979
 
5980
		#如果沒有參數
5981
		if(func_num_args()==0){
5982
 
5983
			#設置執行失敗
5984
			$result["status"]="false";
5985
 
5986
			#設置執行錯誤訊息
5987
			$result["error"]="函數".$result["function"]."需要參數";
5988
 
5989
			#回傳結果
5990
			return $result;
5991
 
5992
			}#if end
5993
 
5994
		#涵式說明:
5995
		#判斷當前環境為web還是cmd
5996
		#回傳結果:
5997
		#$result,"web"或"cmd"
5998
		if(csInformation::getEnv()==="web"){
5999
 
6000
			#設置執行失敗
6001
			$result["status"]="false";
6002
 
6003
			#設置執行錯誤訊息
6004
			$result["error"][]="函數 ".$result["function"]." 僅能在命令列環境下運行!";
6005
 
6006
			#回傳結果
6007
			return $result;
6008
 
6009
			}#if end
6010
 
6011
		#取得參數
6012
		$result["argu"]=$conf;
6013
 
6014
		#如果 $conf 不為陣列
6015
		if(gettype($conf)!="array"){
6016
 
6017
			#設置執行失敗
6018
			$result["status"]="false";
6019
 
6020
			#設置執行錯誤訊息
6021
			$result["error"][]="\$conf變數須為陣列形態";
6022
 
6023
			#如果傳入的參數為 null
6024
			if($conf==null){
6025
 
6026
				#設置執行錯誤訊息
6027
				$result["error"][]="\$conf變數不得為null,請檢查函數「".$result["function"]."」的參數設置有無正確!";
6028
 
6029
				}#if end
6030
 
6031
			#回傳結果
6032
			return $result;
6033
 
6034
			}#if end
6035
 
6036
		#檢查參數
6037
		#函式說明:
6038
		#檢查必填與可省略的參數,可省略參數可指定預設要給與什麼數值內容。
6039
		#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
6040
		#$reuslt["error"],執行不正常結束的錯訊息陣列.
6041
		#$result["function"],當前執行的函式名稱.
6042
		#$result["argu"],設置給予的參數.
6043
		#$result["passed"],識別要檢查的全體變數是否存在以及型態是否正確的變數,"true"代表檢查全部通過;"false"代表檢查不通過
6044
		#$result[$shouldBeCheckedVarName]["varExist"],所檢查的變數是否存在,"false"代表不存在;"true"代表存在
6045
		#$result[$shouldBeCheckedVarName]["varType"],所檢查的變數型態是否正確,"false"代表錯誤;"true"代表正確
6046
		#$result[$shouldBeCheckedVarName]["error"],每個參數設定的錯誤訊息
6047
		#$result["shouldNotBeEmpty"],不應該為空字串或控陣列的變數.
6048
		#$result["argu"],字串陣列,目前輸入的參數名稱陣列.
6049
		#$result["legalVarName"],字串陣列,合法可用的參數名稱陣列.
6050
		#$result["notNeedVar"],字串陣列,多餘的參數名稱.
6051
		#必填寫的參數:
6052
		#$conf["varInput"],陣列變數,要檢查的陣列變數,請在要檢查的參數前面加上&,這樣變動的結果才能被套用。
6053
		$conf["variableCheck::checkArguments"]["varInput"]=&$conf;	
6054
		#$conf["referenceVarKey"],字串,$conf參數後面的key值,用於移除不要的參考陣列.
6055
		$conf["variableCheck::checkArguments"]["referenceVarKey"]="variableCheck::checkArguments";
6056
		#可以省略的參數:
6057
		#$conf["mustBeFilledVariableName"],爲必填參數的變數名稱陣列,形態爲陣列變數,元素數量需要跟"mustBeFilledVariableType"參數的元素數量一致,例如: $conf["mustBeFilledVariableName"] = array("id","account","password");
6058
		$conf["variableCheck::checkArguments"]["mustBeFilledVariableName"]=array("data","clientSock","serverSock","allSockArray");
6059
		#$conf["mustBeFilledVariableType"],爲必填參數的變數陣列應該爲何種變數形態,形態爲陣列,元素數量需要跟"mustBeFilledVariableName"參數的元素數量一致,例如: $conf["mustBeFilledVariableType"] = array("string",integer,"double","resource","object"); , null代表不指定變數形態.
6060
		$conf["variableCheck::checkArguments"]["mustBeFilledVariableType"]=array("string","resource","resource","array");
6061
		#$conf["canBeEmptyString"],字串,必填變數內容如果是空字串就不能算是有設置的話,請設為"false",預設爲"true",可以為空字串.
6062
		#$conf["canBeEmptyString"]="false";
6063
		#$conf["canNotBeEmpty"],字串陣列,哪些必填參數的內容不得為空字串或空陣列,僅當$conf["canBeEmptyString"]為"true"時會生效.
6064
		#$conf["canNotBeEmpty"]=array();
6065
		#$conf["canBeEmpty"],字串陣列,哪些必填參數的內容可為空字串或空陣列,僅當$conf["canBeEmptyString"]為"false"時會生效.
6066
		#$conf["canBeEmpty"]=array();
6067
		#$conf["skipableVariableCanNotBeEmpty"],字串陣列,哪些可省略參數不可以為空字串或空陣列.
6068
		#$conf["variableCheck::checkArguments"]["skipableVariableCanNotBeEmpty"]=array("ip");
6069
		#$conf["skipableVariableName"],陣列字串,爲可省略參數的變數名稱陣列,形態爲陣列變數,例如: $conf["skipableVariableName"] = array("id","account","password");
6070
		#$conf["variableCheck::checkArguments"]["skipableVariableName"]=array("ip","processFuncs");
6071
		#$conf["skipableVariableType"],陣列字串,爲可省略參數的變數名稱陣列,形態爲陣列變數,例如: $conf["skipableVariableType"] = array("string",integer,"double"); 
6072
		#$conf["variableCheck::checkArguments"]["skipableVariableType"]=array("string","array");
6073
		#$conf["skipableVarDefaultValue"],字串陣列,每個不存在的可省略變數要初始化為什麼,null與代表不指定,若預設值是參數之一,請將$conf["mustBeFilledVar"]改成"\$conf["\mustBeFilledVar\"]".
6074
		#$conf["variableCheck::checkArguments"]["skipableVarDefaultValue"]=array("0.0.0.0",array());
6075
		#$conf["disallowAllSkipableVarIsEmpty"],字串,是否允許每個可省略參數都為空字串,預設為"true"允許,反之為"false".
6076
		#$conf["disallowAllSkipableVarIsEmpty"]="";
6077
		#$conf["disallowAllSkipableVarIsEmptyArray"],字串,是否允許每個可省略參數都為空陣列,預設為"true"允許,反之為"false".
6078
		#$conf["disallowAllSkipableVarIsEmptyArray"]="";
6079
		#$conf["arrayCountEqualCheck"],字串陣列,為檢查哪些陣列參數的元素數量要一樣,$conf["arrayCountEqualCheck"][$i]=array()為第$i組key為哪些的變數其元素數量要相等.
6080
		#$conf["arrayCountEqualCheck"][]=array();
6081
		#參考資料來源:
6082
		#array_keys=>http://php.net/manual/en/function.array-keys.php
6083
		$checkArguments=variableCheck::checkArguments($conf["variableCheck::checkArguments"]);
6084
		unset($conf["variableCheck::checkArguments"]);
6085
 
6086
		#如果檢查參數失敗
6087
		if($checkArguments["status"]==="false"){
6088
 
6089
			#設置執行失敗
6090
			$result["status"]="false";
6091
 
6092
			#設置錯誤訊息
6093
			$result["error"]=$checkArguments;
6094
 
6095
			#回傳結果
6096
			return $result;
6097
 
6098
			}#if end
6099
 
6100
		#如果檢查參數不通過
6101
		if($checkArguments["passed"]==="false"){
6102
 
6103
			#設置執行失敗
6104
			$result["status"]="false";
6105
 
6106
			#設置錯誤訊息
6107
			$result["error"]=$checkArguments;
6108
 
6109
			#回傳結果
6110
			return $result;
6111
 
6112
			}#if end
6113
 
6114
		#針對輸入的內容
6115
		switch($conf["data"]){
6116
 
6117
			#如果是 "quit"
6118
			case "quit":
6119
 
6120
				#關閉與用戶之間的連線
6121
				socket_close($conf["clientSock"]);
6122
 
6123
				break;
6124
 
6125
			#如果是 "shutdown"
6126
			case "shutdown":
6127
 
6128
				#關閉 Server Listen 的 sock
6129
				socket_close($conf["serverSock"]);
6130
 
6131
				break;
6132
 
6133
			default:
6134
 
6135
			}#switch end
6136
 
6137
		}#function endService end
6138
 
6139
	/*
6140
	#函式說明:
6141
	#針對收到的內容,若是"quit"則斷開用戶的連線,若是"shutdown"則關閉Server Listen的socket,協定為UDP.
6142
	#回傳結果:
6143
	#無.
6144
	#必填參數:
6145
	#$conf["data"],字串,要處理的內容.
6146
	$conf["data"]="";
6147
	#$conf["clientKey"],resource socket key.
6148
	$conf["clientKey"]=;
6149
	#$conf["serverSock"],resource socket.
6150
	$conf["serverSock"]=;
6151
	#$conf["allSockArray"],resource陣列.
6152
	$conf["allSockArray"]=array();
6153
	#可省略參數:
6154
	#無.
6155
	#參考資料:
6156
	#無.
6157
	#備註:
6158
	#無.
6159
	*/
6160
	public function endServiceU(&$conf){
6161
 
6162
		#初始化要回傳的結果
6163
		$result=array();
6164
 
6165
		#取得當前執行的函數名稱
6166
		$result["function"]=__FUNCTION__;
6167
 
6168
		#如果沒有參數
6169
		if(func_num_args()==0){
6170
 
6171
			#設置執行失敗
6172
			$result["status"]="false";
6173
 
6174
			#設置執行錯誤訊息
6175
			$result["error"]="函數".$result["function"]."需要參數";
6176
 
6177
			#回傳結果
6178
			return $result;
6179
 
6180
			}#if end
6181
 
6182
		#涵式說明:
6183
		#判斷當前環境為web還是cmd
6184
		#回傳結果:
6185
		#$result,"web"或"cmd"
6186
		if(csInformation::getEnv()==="web"){
6187
 
6188
			#設置執行失敗
6189
			$result["status"]="false";
6190
 
6191
			#設置執行錯誤訊息
6192
			$result["error"][]="函數 ".$result["function"]." 僅能在命令列環境下運行!";
6193
 
6194
			#回傳結果
6195
			return $result;
6196
 
6197
			}#if end
6198
 
6199
		#取得參數
6200
		$result["argu"]=$conf;
6201
 
6202
		#如果 $conf 不為陣列
6203
		if(gettype($conf)!="array"){
6204
 
6205
			#設置執行失敗
6206
			$result["status"]="false";
6207
 
6208
			#設置執行錯誤訊息
6209
			$result["error"][]="\$conf變數須為陣列形態";
6210
 
6211
			#如果傳入的參數為 null
6212
			if($conf==null){
6213
 
6214
				#設置執行錯誤訊息
6215
				$result["error"][]="\$conf變數不得為null,請檢查函數「".$result["function"]."」的參數設置有無正確!";
6216
 
6217
				}#if end
6218
 
6219
			#回傳結果
6220
			return $result;
6221
 
6222
			}#if end
6223
 
6224
		#檢查參數
6225
		#函式說明:
6226
		#檢查必填與可省略的參數,可省略參數可指定預設要給與什麼數值內容。
6227
		#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
6228
		#$reuslt["error"],執行不正常結束的錯訊息陣列.
6229
		#$result["function"],當前執行的函式名稱.
6230
		#$result["argu"],設置給予的參數.
6231
		#$result["passed"],識別要檢查的全體變數是否存在以及型態是否正確的變數,"true"代表檢查全部通過;"false"代表檢查不通過
6232
		#$result[$shouldBeCheckedVarName]["varExist"],所檢查的變數是否存在,"false"代表不存在;"true"代表存在
6233
		#$result[$shouldBeCheckedVarName]["varType"],所檢查的變數型態是否正確,"false"代表錯誤;"true"代表正確
6234
		#$result[$shouldBeCheckedVarName]["error"],每個參數設定的錯誤訊息
6235
		#$result["shouldNotBeEmpty"],不應該為空字串或控陣列的變數.
6236
		#$result["argu"],字串陣列,目前輸入的參數名稱陣列.
6237
		#$result["legalVarName"],字串陣列,合法可用的參數名稱陣列.
6238
		#$result["notNeedVar"],字串陣列,多餘的參數名稱.
6239
		#必填寫的參數:
6240
		#$conf["varInput"],陣列變數,要檢查的陣列變數,請在要檢查的參數前面加上&,這樣變動的結果才能被套用。
6241
		$conf["variableCheck::checkArguments"]["varInput"]=&$conf;	
6242
		#$conf["referenceVarKey"],字串,$conf參數後面的key值,用於移除不要的參考陣列.
6243
		$conf["variableCheck::checkArguments"]["referenceVarKey"]="variableCheck::checkArguments";
6244
		#可以省略的參數:
6245
		#$conf["mustBeFilledVariableName"],爲必填參數的變數名稱陣列,形態爲陣列變數,元素數量需要跟"mustBeFilledVariableType"參數的元素數量一致,例如: $conf["mustBeFilledVariableName"] = array("id","account","password");
6246
		$conf["variableCheck::checkArguments"]["mustBeFilledVariableName"]=array("data","clientKey","serverSock","allSockArray");
6247
		#$conf["mustBeFilledVariableType"],爲必填參數的變數陣列應該爲何種變數形態,形態爲陣列,元素數量需要跟"mustBeFilledVariableName"參數的元素數量一致,例如: $conf["mustBeFilledVariableType"] = array("string",integer,"double","resource","object"); , null代表不指定變數形態.
6248
		$conf["variableCheck::checkArguments"]["mustBeFilledVariableType"]=array("string","string","resource","array");
6249
		#$conf["canBeEmptyString"],字串,必填變數內容如果是空字串就不能算是有設置的話,請設為"false",預設爲"true",可以為空字串.
6250
		#$conf["canBeEmptyString"]="false";
6251
		#$conf["canNotBeEmpty"],字串陣列,哪些必填參數的內容不得為空字串或空陣列,僅當$conf["canBeEmptyString"]為"true"時會生效.
6252
		#$conf["canNotBeEmpty"]=array();
6253
		#$conf["canBeEmpty"],字串陣列,哪些必填參數的內容可為空字串或空陣列,僅當$conf["canBeEmptyString"]為"false"時會生效.
6254
		#$conf["canBeEmpty"]=array();
6255
		#$conf["skipableVariableCanNotBeEmpty"],字串陣列,哪些可省略參數不可以為空字串或空陣列.
6256
		#$conf["variableCheck::checkArguments"]["skipableVariableCanNotBeEmpty"]=array("ip");
6257
		#$conf["skipableVariableName"],陣列字串,爲可省略參數的變數名稱陣列,形態爲陣列變數,例如: $conf["skipableVariableName"] = array("id","account","password");
6258
		#$conf["variableCheck::checkArguments"]["skipableVariableName"]=array("ip","processFuncs");
6259
		#$conf["skipableVariableType"],陣列字串,爲可省略參數的變數名稱陣列,形態爲陣列變數,例如: $conf["skipableVariableType"] = array("string",integer,"double"); 
6260
		#$conf["variableCheck::checkArguments"]["skipableVariableType"]=array("string","array");
6261
		#$conf["skipableVarDefaultValue"],字串陣列,每個不存在的可省略變數要初始化為什麼,null與代表不指定,若預設值是參數之一,請將$conf["mustBeFilledVar"]改成"\$conf["\mustBeFilledVar\"]".
6262
		#$conf["variableCheck::checkArguments"]["skipableVarDefaultValue"]=array("0.0.0.0",array());
6263
		#$conf["disallowAllSkipableVarIsEmpty"],字串,是否允許每個可省略參數都為空字串,預設為"true"允許,反之為"false".
6264
		#$conf["disallowAllSkipableVarIsEmpty"]="";
6265
		#$conf["disallowAllSkipableVarIsEmptyArray"],字串,是否允許每個可省略參數都為空陣列,預設為"true"允許,反之為"false".
6266
		#$conf["disallowAllSkipableVarIsEmptyArray"]="";
6267
		#$conf["arrayCountEqualCheck"],字串陣列,為檢查哪些陣列參數的元素數量要一樣,$conf["arrayCountEqualCheck"][$i]=array()為第$i組key為哪些的變數其元素數量要相等.
6268
		#$conf["arrayCountEqualCheck"][]=array();
6269
		#參考資料來源:
6270
		#array_keys=>http://php.net/manual/en/function.array-keys.php
6271
		$checkArguments=variableCheck::checkArguments($conf["variableCheck::checkArguments"]);
6272
		unset($conf["variableCheck::checkArguments"]);
6273
 
6274
		#如果檢查參數失敗
6275
		if($checkArguments["status"]==="false"){
6276
 
6277
			#設置執行失敗
6278
			$result["status"]="false";
6279
 
6280
			#設置錯誤訊息
6281
			$result["error"]=$checkArguments;
6282
 
6283
			#回傳結果
6284
			return $result;
6285
 
6286
			}#if end
6287
 
6288
		#如果檢查參數不通過
6289
		if($checkArguments["passed"]==="false"){
6290
 
6291
			#設置執行失敗
6292
			$result["status"]="false";
6293
 
6294
			#設置錯誤訊息
6295
			$result["error"]=$checkArguments;
6296
 
6297
			#回傳結果
6298
			return $result;
6299
 
6300
			}#if end
6301
 
6302
		#針對輸入的內容
6303
		switch($conf["data"]){
6304
 
6305
			#如果是 "quit"
6306
			case "quit":
6307
 
6308
				#從 $conf["clientKey"] 取得用戶的IP與port
6309
				$strArray=explode(":",$conf["clientKey"]);
6310
				$remote_ip=$strArray[0];
6311
				$remote_port=$strArray[1];
6312
 
6313
				#卸除儲存與用戶之間連線的socket變數
6314
				unset($conf["allSockArray"][$conf["clientKey"]]);
6315
 
6316
				break;
6317
 
6318
			#如果是 "shutdown"
6319
			case "shutdown":
6320
 
6321
				#關閉 Server Listen 的 sock
6322
				socket_close($conf["serverSock"]);
6323
 
6324
				break;
6325
 
6326
			default:
6327
 
6328
			}#switch end
6329
 
6330
		}#function endServiceU end
6331
 
6332
	/*
6333
	#函式說明:
6334
	#給予unixDomainSockServer函式的addOnProcessFunc參數用的函式,在背景執行指令.
6335
	#回傳結果:
6336
	#$result["status"],執行是否正常,"true"為正常,"false"為不正常.
6337
	#$result["error"],錯誤訊息陣列.
6338
	#$result["function"],當前執行的函數名稱.
6339
	#$result["argu"],使用的參數.
6340
	#$result["continue"],"true"代表執行到此函式為止;"false"代表允許後面的函式繼續執行.
6341
	#$result["cache"],要暫存在server端的內容.
6342
	#必填參數:
6343
	$conf["request"],json字串,key為"cmd2run"者,代表要執行的指令;key為"params"者,為要傳入的參數,一個元素代表一個參數.
6344
	#$conf["request"]="";
6345
	$conf["sock"],resource,用戶socket.
6346
	#$conf["sock"]=;
6347
	#可省略參數:
6348
	#$conf["clientCache"],陣列,讓client使用的cache.
6349
	#$conf["clientCache"]=array();
6350
	#參考資料:
6351
	#無.
6352
	#備註:
6353
	#無.
6354
	*/
6355
	public static function addOnProcessFuncForUnixDomainSockServerInRunWithAutoAddMemoryDaemon(&$conf=array()){
6356
 
6357
		#初始化要回傳的結果
6358
		$result=array();
6359
 
6360
		#取得當前執行的函數名稱
6361
		$result["function"]=__FUNCTION__;
6362
 
6363
		#取得參數
6364
		$result["argu"]=$conf;
6365
 
6366
		#允許後面的函式繼續執行
6367
		$result["continue"]="true";
6368
 
6369
		#如果 $conf 不為陣列
6370
		if(gettype($conf)!="array"){
6371
 
6372
			#設置執行失敗
6373
			$result["status"]="false";
6374
 
6375
			#設置執行錯誤訊息
6376
			$result["error"][]="\$conf變數須為陣列形態";
6377
 
6378
			#如果傳入的參數為 null
6379
			if(is_null($conf)){
6380
 
6381
				#設置執行錯誤訊息
6382
				$result["error"][]="\$conf變數不得為null,請檢查函數「".$result["function"]."」的參數設置有無正確!";
6383
 
6384
				}#if end
6385
 
6386
			#回傳結果
6387
			return $result;
6388
 
6389
			}#if end
6390
 
6391
		#函式說明:
6392
		#檢查必填與可省略的參數,可省略參數可指定預設要給與什麼數值內容.
6393
		#回傳結果:
6394
		#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
6395
		#$result["error"],執行不正常結束的錯訊息陣列.
6396
		#$result["simpleError"],簡單表示的錯誤訊息.
6397
		#$result["function"],當前執行的函式名稱.
6398
		#$result["argu"],設置給予的參數.
6399
		#$result["passed"],識別要檢查的全體變數是否存在以及型態是否正確的變數,"true"代表檢查全部通過;"false"代表檢查不通過
6400
		#$result[$shouldBeCheckedVarName]["varExist"],所檢查的變數是否存在,"false"代表不存在;"true"代表存在
6401
		#$result[$shouldBeCheckedVarName]["varType"],所檢查的變數型態是否正確,"false"代表錯誤;"true"代表正確
6402
		#$result[$shouldBeCheckedVarName]["error"],每個參數設定的錯誤訊息
6403
		#$result["shouldNotBeEmpty"],不應該為空字串或控陣列的變數.
6404
		#$result["argu"],字串陣列,目前輸入的參數名稱陣列.
6405
		#$result["legalVarName"],字串陣列,合法可用的參數名稱陣列.
6406
		#$result["notNeedVar"],字串陣列,多餘的參數名稱.
6407
		#必填參數:
6408
		#$conf["varInput"],陣列變數,要檢查的陣列變數,請在要檢查的參數前面加上&,這樣變動的結果才能被套用。
6409
		$conf["variableCheck::checkArguments"]["varInput"]=&$conf;
6410
		#$conf["referenceVarKey"],字串,$conf參數後面的key值,用於移除不要的參考陣列.
6411
		$conf["variableCheck::checkArguments"]["referenceVarKey"]="variableCheck::checkArguments";
6412
		#可省略參數:
6413
		#$conf["mustBeFilledVariableName"],爲必填參數的變數名稱陣列,形態爲陣列變數,元素數量需要跟"mustBeFilledVariableType"參數的元素數量一致,例如: $conf["mustBeFilledVariableName"] = array("id","account","password");
6414
		$conf["variableCheck::checkArguments"]["mustBeFilledVariableName"]=array("request","socket");
6415
		#$conf["mustBeFilledVariableType"],爲必填參數的變數陣列應該爲何種變數形態,形態爲陣列,元素數量需要跟"mustBeFilledVariableName"參數的元素數量一致,例如: $conf["mustBeFilledVariableType"] = array("string",integer,"double","resource","object"); , null代表不指定變數形態.
6416
		$conf["variableCheck::checkArguments"]["mustBeFilledVariableType"]=array("string","resource");
6417
		#$conf["canBeEmptyString"],字串,必填變數內容如果是空字串就不能算是有設置的話,請設為"false",預設爲"true",可以為空字串.
6418
		#$conf["canBeEmptyString"]="false";
6419
		#$conf["canNotBeEmpty"],字串陣列,哪些必填參數的內容不得為空字串或空陣列,僅當$conf["canBeEmptyString"]為"true"時會生效.
6420
		#$conf["canNotBeEmpty"]=array();
6421
		#$conf["canBeEmpty"],字串陣列,哪些必填參數的內容可為空字串或空陣列,僅當$conf["canBeEmptyString"]為"false"時會生效.
6422
		#$conf["canBeEmpty"]=array();
6423
		#$conf["skipableVariableCanNotBeEmpty"],字串陣列,哪些可省略參數不可以為空字串或空陣列.
6424
		#$conf["variableCheck::checkArguments"]["skipableVariableCanNotBeEmpty"]=array("last_req_time","info");
6425
		#$conf["skipableVariableName"],陣列字串,爲可省略參數的變數名稱陣列,形態爲陣列變數,例如: $conf["skipableVariableName"] = array("id","account","password");
6426
		$conf["variableCheck::checkArguments"]["skipableVariableName"]=array("last_req_time","info","clientCache");
6427
		#$conf["skipableVariableType"],陣列字串,爲可省略參數的變數名稱陣列,形態爲陣列變數,例如: $conf["skipableVariableType"] = array("string",integer,"double");
6428
		$conf["variableCheck::checkArguments"]["skipableVariableType"]=array("string","array","array");
6429
		#$conf["skipableVarDefaultValue"],字串陣列,每個不存在的可省略變數要初始化為什麼,null與代表不指定,若預設值是參數之一,請將$conf["mustBeFilledVar"]改成"\$conf["\mustBeFilledVar\"]".
6430
		#$conf["variableCheck::checkArguments"]["skipableVarDefaultValue"]=array($phpMaxMemInConfig,"10",null);
6431
		#$conf["disallowAllSkipableVarIsEmpty"],字串,是否允許每個可省略參數都為空字串,預設為"true"允許,反之為"false".
6432
		#$conf["disallowAllSkipableVarIsEmpty"]="";
6433
		#$conf["disallowAllSkipableVarIsEmptyArray"],字串,是否允許每個可省略參數都為空陣列,預設為"true"允許,反之為"false".
6434
		#$conf["disallowAllSkipableVarIsEmptyArray"]="";
6435
		#$conf["arrayCountEqualCheck"],字串陣列,為檢查哪些陣列參數的元素數量要一樣,$conf["arrayCountEqualCheck"][$i]=array()為第$i組key為哪些的變數其元素數量要相等.
6436
		#$conf["arrayCountEqualCheck"][]=array();
6437
		#參考資料:
6438
		#array_keys=>http://php.net/manual/en/function.array-keys.php
6439
		#備註:
6440
		#無.
6441
		$checkArguments=variableCheck::checkArguments($conf["variableCheck::checkArguments"]);
6442
		unset($conf["variableCheck::checkArguments"]);
6443
 
6444
		#debug
6445
		#var_dump(__LINE__,$checkArguments);
6446
 
6447
		#如果執行失敗
6448
		if($checkArguments["status"]==="false"){
6449
 
6450
			#設置執行失敗
6451
			$result["status"]="false";
6452
 
6453
			#設置執行錯誤訊息
6454
			$result["error"]=$checkArguments;
6455
 
6456
			#回傳結果
6457
			return $result;
6458
 
6459
			}#if end
6460
 
6461
		#如果檢查不通過
6462
		if($checkArguments["passed"]==="false"){
6463
 
6464
			#設置執行失敗
6465
			$result["status"]="false";
6466
 
6467
			#設置執行錯誤訊息
6468
			$result["error"]=$checkArguments;
6469
 
6470
			#回傳結果
6471
			return $result;
6472
 
6473
			}#if end	
6474
 
6475
		#將需求變成陣列
6476
		$request=(array)json_decode($conf["request"]);
6477
 
6478
		#函式說明:
6479
		#檢查必填與可省略的參數,可省略參數可指定預設要給與什麼數值內容.
6480
		#回傳結果:
6481
		#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
6482
		#$result["error"],執行不正常結束的錯訊息陣列.
6483
		#$result["simpleError"],簡單表示的錯誤訊息.
6484
		#$result["function"],當前執行的函式名稱.
6485
		#$result["argu"],設置給予的參數.
6486
		#$result["passed"],識別要檢查的全體變數是否存在以及型態是否正確的變數,"true"代表檢查全部通過;"false"代表檢查不通過
6487
		#$result[$shouldBeCheckedVarName]["varExist"],所檢查的變數是否存在,"false"代表不存在;"true"代表存在
6488
		#$result[$shouldBeCheckedVarName]["varType"],所檢查的變數型態是否正確,"false"代表錯誤;"true"代表正確
6489
		#$result[$shouldBeCheckedVarName]["error"],每個參數設定的錯誤訊息
6490
		#$result["shouldNotBeEmpty"],不應該為空字串或控陣列的變數.
6491
		#$result["argu"],字串陣列,目前輸入的參數名稱陣列.
6492
		#$result["legalVarName"],字串陣列,合法可用的參數名稱陣列.
6493
		#$result["notNeedVar"],字串陣列,多餘的參數名稱.
6494
		#必填參數:
6495
		#$conf["varInput"],陣列變數,要檢查的陣列變數,請在要檢查的參數前面加上&,這樣變動的結果才能被套用。
6496
		$conf["variableCheck::checkArguments"]["varInput"]=&$request;
6497
		#$conf["referenceVarKey"],字串,$conf參數後面的key值,用於移除不要的參考陣列.
6498
		$conf["variableCheck::checkArguments"]["referenceVarKey"]="variableCheck::checkArguments";
6499
		#可省略參數:
6500
		#$conf["mustBeFilledVariableName"],爲必填參數的變數名稱陣列,形態爲陣列變數,元素數量需要跟"mustBeFilledVariableType"參數的元素數量一致,例如: $conf["mustBeFilledVariableName"] = array("id","account","password");
6501
		$conf["variableCheck::checkArguments"]["mustBeFilledVariableName"]=array("cmd2run");
6502
		#$conf["mustBeFilledVariableType"],爲必填參數的變數陣列應該爲何種變數形態,形態爲陣列,元素數量需要跟"mustBeFilledVariableName"參數的元素數量一致,例如: $conf["mustBeFilledVariableType"] = array("string",integer,"double","resource","object"); , null代表不指定變數形態.
6503
		$conf["variableCheck::checkArguments"]["mustBeFilledVariableType"]=array("string");
6504
		#$conf["canBeEmptyString"],字串,必填變數內容如果是空字串就不能算是有設置的話,請設為"false",預設爲"true",可以為空字串.
6505
		#$conf["variableCheck::checkArguments"]["canBeEmptyString"]="true";
6506
		#$conf["canNotBeEmpty"],字串陣列,哪些必填參數的內容不得為空字串或空陣列,僅當$conf["canBeEmptyString"]為"true"時會生效.
6507
		#$conf["variableCheck::checkArguments"]["canNotBeEmpty"]=array("cmd");
6508
		#$conf["canBeEmpty"],字串陣列,哪些必填參數的內容可為空字串或空陣列,僅當$conf["canBeEmptyString"]為"false"時會生效.
6509
		#$conf["canBeEmpty"]=array();
6510
		#$conf["skipableVariableCanNotBeEmpty"],字串陣列,哪些可省略參數不可以為空字串或空陣列.
6511
		#$conf["variableCheck::checkArguments"]["skipableVariableCanNotBeEmpty"]=array("params");
6512
		#$conf["skipableVariableName"],陣列字串,爲可省略參數的變數名稱陣列,形態爲陣列變數,例如: $conf["skipableVariableName"] = array("id","account","password");
6513
		$conf["variableCheck::checkArguments"]["skipableVariableName"]=array("id","params");
6514
		#$conf["skipableVariableType"],陣列字串,爲可省略參數的變數名稱陣列,形態爲陣列變數,例如: $conf["skipableVariableType"] = array("string",integer,"double");
6515
		$conf["variableCheck::checkArguments"]["skipableVariableType"]=array("string","array");
6516
		#$conf["skipableVarDefaultValue"],字串陣列,每個不存在的可省略變數要初始化為什麼,null與代表不指定,若預設值是參數之一,請將$conf["mustBeFilledVar"]改成"\$conf["\mustBeFilledVar\"]".
6517
		#$conf["variableCheck::checkArguments"]["skipableVarDefaultValue"]=array($phpMaxMemInConfig,"10",null);
6518
		#$conf["disallowAllSkipableVarIsEmpty"],字串,是否允許每個可省略參數都為空字串,預設為"true"允許,反之為"false".
6519
		#$conf["disallowAllSkipableVarIsEmpty"]="";
6520
		#$conf["disallowAllSkipableVarIsEmptyArray"],字串,是否允許每個可省略參數都為空陣列,預設為"true"允許,反之為"false".
6521
		#$conf["disallowAllSkipableVarIsEmptyArray"]="";
6522
		#$conf["arrayCountEqualCheck"],字串陣列,為檢查哪些陣列參數的元素數量要一樣,$conf["arrayCountEqualCheck"][$i]=array()為第$i組key為哪些的變數其元素數量要相等.
6523
		#$conf["arrayCountEqualCheck"][]=array();
6524
		#參考資料:
6525
		#array_keys=>http://php.net/manual/en/function.array-keys.php
6526
		#備註:
6527
		#無.
6528
		$checkArguments=variableCheck::checkArguments($conf["variableCheck::checkArguments"]);
6529
		unset($conf["variableCheck::checkArguments"]);
6530
 
6531
		#debug
6532
		#var_dump(__LINE__,$checkArguments);
6533
 
6534
		#如果執行失敗
6535
		if($checkArguments["status"]==="false"){
6536
 
6537
			#設置執行失敗
6538
			$result["status"]="false";
6539
 
6540
			#設置執行錯誤訊息
6541
			$result["error"]=$checkArguments;
6542
 
6543
			#回傳結果
6544
			return $result;
6545
 
6546
			}#if end
6547
 
6548
		#如果檢查不通過
6549
		if($checkArguments["passed"]==="false"){
6550
 
6551
			#設置執行失敗
6552
			$result["status"]="false";
6553
 
6554
			#設置執行錯誤訊息
6555
			$result["error"]=$checkArguments;
6556
 
6557
			#回傳結果
6558
			return $result;
6559
 
6560
			}#if end
6561
 
6562
		#函式說明:
6563
		#呼叫shell執行系統命令,並取得回傳的內容.
6564
		#回傳結果:
6565
		#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
6566
		#$result["error"],錯誤訊息陣列.
6567
		#$result["function"],當前執行的函數名稱.
6568
		#$result["argu"],使用的參數.
6569
		#$result["cmd"],執行的指令內容.
6570
		#$result["fullCmd"],如果參數 $conf["inBackGround"] 為 "true" 則會回傳該值.
6571
		#$result["output"],爲執行完二元碼後的輸出陣列,若 $conf["inBackGround"] 為 "true",則為當下的輸出.
6572
		#$result["tmpFileOutput"],儲存輸出的暫存檔案名稱,若 $conf["inBackGround"] 為 "true" 則會回傳該值.
6573
		#$result["running"],是否還在執行.
6574
		#$result["pid"],pid.
6575
		#$result["statusCode"],執行結束後的代碼.
6576
		#$result["escape"],陣列,儲存重新排序過且已經escape過的指令(key為"cmd")與參數(key為"argu")與兩者組合的一維陣列(key為"array").
6577
		#必填參數:
6578
		#$conf["command"],字串,要執行的指令.
6579
		$conf["external::callShell"]["command"]=$request["cmd2run"];
6580
		#$conf["fileArgu"],字串,變數__FILE__的內容.
6581
		$conf["external::callShell"]["fileArgu"]=__FILE__;
6582
		#可省略參數:
6583
		#$conf["argu"],陣列字串,指令搭配的參數,預設為空陣列.
6584
		$conf["external::callShell"]["argu"]=$request["params"];
6585
		#$conf["arguIsAddr"],陣列字串,指令搭配的哪些參數為路徑,為路徑的參數會進行轉換以便符合呼叫當前函數的位置,預設不指定,若有3個參數,其中第3個參數為路徑,則表示為array("false","false","true").
6586
		#$conf["arguIsAddr"]=array();
6587
		#$conf["pre"],陣列,要在本指令前執行的每個指令與參數.
6588
		#$conf["pre"][$i]["cmd"],字串,要在本指令前執行的第$i+1個指令.
6589
		#$conf["pre"][$i]["param"],陣列字串,要在本指令前執行的第$i+1個指令的參數.
6590
		#$conf["enablePrintDescription"],字串,是否要印出$conf["printDescription"]的內容,"true"代表要,"false"代表不要,預設為"false".
6591
		#$conf["enablePrintDescription"]="true";
6592
		#$conf["printDescription"],字串,執行該外部程式前要印出來的的文字,預設為$conf["command"]的內容加上使用的$conf["argu"]參數.
6593
		#$conf["printDescription"]="";
6594
		#$conf["escapeshellarg"],字串,是否要啟用過濾參數,用了比較安全,但可能會出錯,"true"為啟用,"false"為不啟用,預設為"false".如果參數為"< 、<< 、> 、>> 、| 、2>&1"之一則不會過濾.
6595
		$conf["external::callShell"]["escapeshellarg"]="true";
6596
		#$conf["thereIsShellVar"],陣列字串,指令搭配的參數"argu",若含有「\'」,則取代為「"」.每個argu參數都要有對應的元素."true"代表要置換.
6597
		#$conf["thereIsShellVar"]=array();
6598
		#$conf["username"],字串,要用什麼使用者來執行,預設為執行php的使用者,該參數不適用於apache環境.
6599
		#$conf["username"]="";
6600
		#$conf["password"],字串,root的使用者密碼,預設不使用密碼,該參數不適用於apache環境.
6601
		#$conf["password"]="";
6602
		#$conf["useScript"],字串,是否要啟用Linux的script指令來記錄輸出,"true"代表要,Fedora的selinux會擋住該操作;"false"代表不要,預設為"false".
6603
		#$conf["useScript"]="";
6604
		#$conf["logFilePath"],字串,當 $conf["useScript"] 為 "true" 時,輸出的內容要暫存到哪裡,預設為 "/tmp/.qbpwcf_tmp/external/callShell/".
6605
		#$conf["logFilePath"]=".qbpwcf_tmp/external/callShell/";
6606
		#$conf["inBackGround"],字串,是否要在背景執行,且不會等待程式執行結束再執行下一個指令,"true"代表是,"false"代表不要,預設為"false",如果$conf["command"]有用「;」區隔的多個指令將會出錯.
6607
		#$conf["inBackGround"]="";
6608
		#$conf["getErr"],字串,"true"代表將錯誤輸出變成標準輸出,反之"false"為不變動.
6609
		#$conf["getErr"]="false";
6610
		#$conf["doNotRun"],字串,"true"代表不執行指令,預設為"false"會執行指令.
6611
		$conf["external::callShell"]["doNotRun"]="true";
6612
		#參考資料:
6613
		#exec=>http://php.net/manual/en/function.exec.php
6614
		#escapeshellcmd=>http://php.net/manual/en/function.escapeshellcmd.php
6615
		#escapeshellarg=>http://php.net/manual/en/function.escapeshellarg.php
6616
		#備註:
6617
		#不是所有指令都能用apache的身份執行,目前已知java,javac指令無法執行,使用root身份可能會被selinux阻擋.
6618
		#若使用的 command、argu 參數,含有 ~ 則會被視為字串,若有需要其於 shell 中代表的家目錄位置,可用 fileAccess::tildeToPath 來進行轉換.
6619
		$callShell=external::callShell($conf["external::callShell"]);
6620
		unset($conf["external::callShell"]);
6621
 
6622
		#如果執行失敗
6623
		if($callShell["status"]==="false"){
6624
 
6625
			#設置執行失敗
6626
			$result["status"]="false";
6627
 
6628
			#設置執行錯誤訊息
6629
			$result["error"]=$callShell;
6630
 
6631
			#回傳結果
6632
			return $result;
6633
 
6634
			}#if end
6635
 
6636
		#函式說明:
6637
		#將一維陣列轉換為用特定符號間隔的字串,ex:array("1","2","3") to "a;b;c;".
6638
		#回傳的結果:
6639
		#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
6640
		#$result["function"],當前執行的function名稱
6641
		#$result["error"],錯誤訊息陣列.
6642
		#$result["content"],處理好的字串.
6643
		#$result["argu"],使用的參數.
6644
		#必填參數:
6645
		#$conf["inputArray"],字串陣列,要轉成字串的一維陣列.
6646
		$conf["arrays::arrayToString"]["inputArray"]=$callShell["escape"]["array"];
6647
		#可省略參數:
6648
		#$conf["spiltSymbol"],字串,用來區隔字串的符號,預設為;
6649
		$conf["arrays::arrayToString"]["spiltSymbol"]=" ";
6650
		#$conf["skipEnd"],字串,結尾是否不要加上符號,預設為"false",要加上符號,"true"代表不要加上符號。
6651
		$conf["arrays::arrayToString"]["skipEnd"]="true";
6652
		#參考資料:
6653
		#無.
6654
		#備註:
6655
		#無.
6656
		$arrayToString=arrays::arrayToString($conf["arrays::arrayToString"]);
6657
		unset($conf["arrays::arrayToString"]);
6658
 
6659
		#如果執行失敗
6660
		if($arrayToString["status"]==="false"){
6661
 
6662
			#設置執行失敗
6663
			$result["status"]="false";
6664
 
6665
			#設置執行錯誤訊息
6666
			$result["error"]=$arrayToString;
6667
 
6668
			#回傳結果
6669
			return $result;
6670
 
6671
			}#if end
6672
 
6673
		#函式說明:
6674
		#透過proc來多執行序運作.
6675
		#回傳結果:
6676
		#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
6677
		#$reuslt["error"],執行不正常結束的錯訊息陣列.
6678
		#$result["function"],當前執行的函式名稱.
6679
		#$result["argu"],使用的參數.
6680
		#$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"代表程序的資訊.
6681
		#必填參數:
6682
		#$conf["cmds"],字串陣列,每個元素代表要執行的指令與參數.
6683
		$conf["threads::proc"]["cmds"]=array($arrayToString["content"]);
6684
		#可省略參數:
6685
		#$conf["wait"],字串,是否需要等待所有程序結束,預設為"true"要等待;反之為"false"不要等待.
6686
		#$conf["threads::proc"]["wait"]="false";
6687
		#$conf["workingDir"],字串陣列,個別程式執行時的家目錄,預設不指定.
6688
		#$conf["workingDir"]=array("path");
6689
		#$conf["envs"],2維字串陣列,每個元素代表個別程式執行時的指定環境變數,key變數名稱;value為變數內容.預設為array("QBPWCF" => "Quick Build PHP Website Componment base on Fedora Linux");
6690
		#$conf["envs"]=array(array("key"=>"value"));
6691
		#$conf["executeBy"],字串陣列,每個元素代表個別指令要用什麼程式執行,預設為"bash".
6692
		#$conf["executeBy"]=array("bash");
6693
		#參考資料:
6694
		#https://www.php.net/manual/en/function.proc-open.php
6695
		#https://www.php.net/manual/en/function.proc-get-status.php
6696
		#備註:
6697
		#無.
6698
		$proc=threads::proc($conf["threads::proc"]);
6699
		unset($conf["threads::proc"]);
6700
 
6701
		/* debug
6702
 
6703
		#函式說明:
6704
		#撰寫log
6705
		#回傳結果:
6706
		#$result["status"],狀態,"true"或"false".
6707
		#$result["error"],錯誤訊息陣列.
6708
		#$result["function"],當前函式的名稱.
6709
		#$result["argu"],使用的參數.
6710
		#$result["content"],要寫入log的內容字串.
6711
		#必填參數:
6712
		#$conf["path"],字串,log檔案的路徑與名稱.
6713
		$conf["logs::record"]["path"]=$conf["socket"]."(sock::addOnProcessFuncForUnixDomainSockServerInRunWithAutoAddMemoryDaemon).log";
6714
		#$conf["content"],any,要寫的內容,若內容不為字串則會用var_dump的格式寫入.
6715
		$conf["logs::record"]["content"]=$proc;
6716
		#$conf["fileArgu"],字串,php變數__FILE__的內容,亦即該檔案在檔案系統的絕對路徑
6717
		$conf["logs::record"]["fileArgu"]=__FILE__;
6718
		#可省略參數:
6719
		#$conf["rewrite"],預設為"false",接續寫入;反之"true"代表重新寫入.
6720
		#$conf["rewrite"]="false";
6721
		#$conf["returnOnly"],預設為"false",會寫入到log檔案.若為"true"則不會寫入log.
6722
		#$conf["returnOnly"]="true";
6723
		#參考資料:
6724
		#無.
6725
		#備註:
6726
		#無.
6727
		$record=logs::record($conf["logs::record"]);
6728
		unset($conf["logs::record"]);
6729
 
6730
		#如果執行失敗
6731
		if($record["status"]==="false"){
6732
 
6733
			#設置執行錯誤識別
6734
			$result["status"]="false";
6735
 
6736
			#設置執行錯誤
6737
			$result["error"]=$record;
6738
 
6739
			#回傳結果
6740
			return $result;
6741
 
6742
			}#if end
6743
 
6744
		*/
6745
 
6746
		#設置要暫存在server端的內容
6747
		$result["cache"]=&$proc;
6748
 
6749
		#如果執行失敗
6750
		if($proc["status"]==="false"){
6751
 
6752
			#設置執行失敗
6753
			$result["status"]="false";
6754
 
6755
			#設置執行錯誤訊息
6756
			$result["error"]=$proc;
6757
 
6758
			#回傳結果
6759
			return $result;
6760
 
6761
			}#if end
6762
 
6763
		#設置執行正常
6764
		$result["status"]="true";
6765
 
6766
		#後面的程式不要執行
6767
		$result["continue"]="false";
6768
 
6769
		#回傳結果
6770
		return $result;
6771
 
6772
		}#function addOnProcessFuncForUnixDomainSockServerInRunWithAutoAddMemoryDaemon end
6773
 
6774
	/*
6775
	#函式說明:
6776
	#執行程式時,依照需要增加記憶體的上限.
6777
	#回傳結果:
6778
	#$result["status"],執行是否正常,"true"為正常,"false"為不正常.
6779
	#$result["error"],錯誤訊息陣列.
6780
	#$result["function"],當前執行的函數名稱.
6781
	#$result["argu"],使用的參數.
6782
	#$result["content"],程式執行後的結果(unix domain socket server的輸出).
6783
	#必填參數:
6784
	#$conf["cmd"],字串參數,要執行的指令.
6785
	$conf["cmd"]="";
6786
	#可省略參數:
6787
	#$conf["params"],陣列字串參數,每個元素代表依序哦昂使用的參數.
6788
	#$conf["params"]=array("");
6789
	#$conf["fileArgu"],字串,__FILE__的內容.
6790
	#$conf["fileArgu"]="";
6791
	#參考資料:
6792
	#https://www.php.net/manual/en/function.memory-get-usage.php
6793
	#https://www.php.net/manual/en/ini.core.php#ini.memory-limit
6794
	#https://www.php.net/manual/en/function.stream-get-meta-data.php
6795
	#備註:
6796
	#無.
6797
	*/
6798
	public static function runWithAutoAddMemoryDaemon(&$conf=array()){
6799
 
6800
		#初始化要回傳的結果
6801
		$result=array();
6802
 
6803
		#取得當前執行的函數名稱
6804
		$result["function"]=__FUNCTION__;
6805
 
6806
		#取得參數
6807
		$result["argu"]=$conf;
6808
 
6809
		#如果 $conf 不為陣列
6810
		if(gettype($conf)!="array"){
6811
 
6812
			#設置執行失敗
6813
			$result["status"]="false";
6814
 
6815
			#設置執行錯誤訊息
6816
			$result["error"][]="\$conf變數須為陣列形態";
6817
 
6818
			#如果傳入的參數為 null
6819
			if(is_null($conf)){
6820
 
6821
				#設置執行錯誤訊息
6822
				$result["error"][]="\$conf變數不得為null,請檢查函數「".$result["function"]."」的參數設置有無正確!";
6823
 
6824
				}#if end
6825
 
6826
			#回傳結果
6827
			return $result;
6828
 
6829
			}#if end
6830
 
6831
		#檢查參數
6832
		#函式說明:
6833
		#檢查必填與可省略的參數,可省略參數可指定預設要給與什麼數值內容.
6834
		#回傳結果:
6835
		#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
6836
		#$result["error"],執行不正常結束的錯訊息陣列.
6837
		#$result["simpleError"],簡單表示的錯誤訊息.
6838
		#$result["function"],當前執行的函式名稱.
6839
		#$result["argu"],設置給予的參數.
6840
		#$result["passed"],識別要檢查的全體變數是否存在以及型態是否正確的變數,"true"代表檢查全部通過;"false"代表檢查不通過
6841
		#$result[$shouldBeCheckedVarName]["varExist"],所檢查的變數是否存在,"false"代表不存在;"true"代表存在
6842
		#$result[$shouldBeCheckedVarName]["varType"],所檢查的變數型態是否正確,"false"代表錯誤;"true"代表正確
6843
		#$result[$shouldBeCheckedVarName]["error"],每個參數設定的錯誤訊息
6844
		#$result["shouldNotBeEmpty"],不應該為空字串或控陣列的變數.
6845
		#$result["argu"],字串陣列,目前輸入的參數名稱陣列.
6846
		#$result["legalVarName"],字串陣列,合法可用的參數名稱陣列.
6847
		#$result["notNeedVar"],字串陣列,多餘的參數名稱.
6848
		#必填參數:
6849
		#$conf["varInput"],陣列變數,要檢查的陣列變數,請在要檢查的參數前面加上&,這樣變動的結果才能被套用。
6850
		$conf["variableCheck::checkArguments"]["varInput"]=&$conf;
6851
		#$conf["referenceVarKey"],字串,$conf參數後面的key值,用於移除不要的參考陣列.
6852
		$conf["variableCheck::checkArguments"]["referenceVarKey"]="variableCheck::checkArguments";
6853
		#可省略參數:
6854
		#$conf["mustBeFilledVariableName"],爲必填參數的變數名稱陣列,形態爲陣列變數,元素數量需要跟"mustBeFilledVariableType"參數的元素數量一致,例如: $conf["mustBeFilledVariableName"] = array("id","account","password");
6855
		$conf["variableCheck::checkArguments"]["mustBeFilledVariableName"]=array("cmd");
6856
		#$conf["mustBeFilledVariableType"],爲必填參數的變數陣列應該爲何種變數形態,形態爲陣列,元素數量需要跟"mustBeFilledVariableName"參數的元素數量一致,例如: $conf["mustBeFilledVariableType"] = array("string",integer,"double","resource","object"); , null代表不指定變數形態.
6857
		$conf["variableCheck::checkArguments"]["mustBeFilledVariableType"]=array("string");
6858
		#$conf["canBeEmptyString"],字串,必填變數內容如果是空字串就不能算是有設置的話,請設為"false",預設爲"true",可以為空字串.
6859
		$conf["variableCheck::checkArguments"]["canBeEmptyString"]="false";
6860
		#$conf["canNotBeEmpty"],字串陣列,哪些必填參數的內容不得為空字串或空陣列,僅當$conf["canBeEmptyString"]為"true"時會生效.
6861
		#$conf["canNotBeEmpty"]=array();
6862
		#$conf["canBeEmpty"],字串陣列,哪些必填參數的內容可為空字串或空陣列,僅當$conf["canBeEmptyString"]為"false"時會生效.
6863
		#$conf["canBeEmpty"]=array();
6864
		#$conf["skipableVariableCanNotBeEmpty"],字串陣列,哪些可省略參數不可以為空字串或空陣列.
6865
		$conf["variableCheck::checkArguments"]["skipableVariableCanNotBeEmpty"]=array("params","fileArgu");
6866
		#$conf["skipableVariableName"],陣列字串,爲可省略參數的變數名稱陣列,形態爲陣列變數,例如: $conf["skipableVariableName"] = array("id","account","password");
6867
		$conf["variableCheck::checkArguments"]["skipableVariableName"]=array("params","fileArgu");
6868
		#$conf["skipableVariableType"],陣列字串,爲可省略參數的變數名稱陣列,形態爲陣列變數,例如: $conf["skipableVariableType"] = array("string",integer,"double");
6869
		$conf["variableCheck::checkArguments"]["skipableVariableType"]=array("array","string");
6870
		#$conf["skipableVarDefaultValue"],字串陣列,每個不存在的可省略變數要初始化為什麼,null與代表不指定,若預設值是參數之一,請將$conf["mustBeFilledVar"]改成"\$conf["\mustBeFilledVar\"]".
6871
		$conf["variableCheck::checkArguments"]["skipableVarDefaultValue"]=array(null,__FILE__);
6872
		#$conf["disallowAllSkipableVarIsEmpty"],字串,是否允許每個可省略參數都為空字串,預設為"true"允許,反之為"false".
6873
		#$conf["disallowAllSkipableVarIsEmpty"]="";
6874
		#$conf["disallowAllSkipableVarIsEmptyArray"],字串,是否允許每個可省略參數都為空陣列,預設為"true"允許,反之為"false".
6875
		#$conf["disallowAllSkipableVarIsEmptyArray"]="";
6876
		#$conf["disallowAllSkipableVarNotExist"],字串,是否不允許每個可省略參數都不存在,預設為"false"代表允許,反之為"true".
6877
		#$conf["disallowAllSkipableVarNotExist"]="";
6878
		#$conf["arrayCountEqualCheck"],字串陣列,為檢查哪些陣列參數的元素數量要一樣,$conf["arrayCountEqualCheck"][$i]=array()為第$i組key為哪些的變數其元素數量要相等.
6879
		#$conf["arrayCountEqualCheck"][]=array();
6880
		#參考資料:
6881
		#array_keys=>http://php.net/manual/en/function.array-keys.php
6882
		#備註:
6883
		#無.
6884
		$checkArguments=variableCheck::checkArguments($conf["variableCheck::checkArguments"]);
6885
		unset($conf["variableCheck::checkArguments"]);
6886
 
6887
		#如果執行失敗
6888
		if($checkArguments["status"]==="false"){
6889
 
6890
			#設置執行失敗
6891
			$result["status"]="false";
6892
 
6893
			#設置錯誤資訊
6894
			$result["error"]=$checkArguments;
6895
 
6896
			#回傳結果
6897
			return $result;
6898
 
6899
			}#if end
6900
 
6901
		#如果檢查不通過
6902
		if($checkArguments["passed"]==="false"){
6903
 
6904
			#設置執行失敗
6905
			$result["status"]="false";
6906
 
6907
			#設置錯誤資訊
6908
			$result["error"]=$checkArguments;
6909
 
6910
			#回傳結果
6911
			return $result;
6912
 
6913
			}#if end
6914
 
6915
		/*
6916
		#函式說明:
6917
		#於 ./tmp 底下建立暫存目錄與回傳暫存檔案名稱路徑 
6918
		#回傳結果:
6919
		#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
6920
		#$result["error"],錯誤訊息.
6921
		#$result["function"],當前執行的函數名稱.
6922
		#$result["content"],暫存檔案的路徑與名稱.
6923
		#必填參數:
6924
		#無.
6925
		#可省略參數:
6926
		#無.
6927
		#參考資料:
6928
		#無.
6929
		#備註:
6930
		#無.
6931
		*/
34 liveuser 6932
		$conf["fileAccess::createTempFile"]=array();
6933
		$createTempFile=fileAccess::createTempFile($conf["fileAccess::createTempFile"]);
6934
		unset($conf["fileAccess::createTempFile"]);
3 liveuser 6935
 
6936
		#如果執行失敗
6937
		if($createTempFile["status"]==="false"){
6938
 
6939
			#設置執行失敗
6940
			$result["status"]="false";
6941
 
6942
			#設置執行錯誤訊息
6943
			$result["error"]=$createTempFile;
6944
 
6945
			#回傳結果
6946
			return $result;
6947
 
6948
			}#if end
6949
 
6950
		#取得暫存的 unix domain socket 檔案
6951
		$tmpUnixDomainSock=$createTempFile["content"];
6952
 
6953
		#初始化用來運行  unixDomainSockServer.php 的參數
6954
		$argu=array();
6955
 
6956
		#設置參數
6957
		$argu[]="--sock";
6958
 
6959
		#設置參數
6960
		$argu[]=$tmpUnixDomainSock;
6961
 
6962
		#設置參數
6963
		$argu[]="--addOnProcessFunc";
6964
 
6965
		#設置參數
6966
		$argu[]="\qbpwcf\sock::addOnProcessFuncForUnixDomainSockServerInRunWithAutoAddMemoryDaemon";
6967
 
6968
		#設置參數
6969
		$argu[]="--funcToRunWhenIdle";
6970
 
6971
		#設置參數
6972
		$argu[]="\qbpwcf\config::autoAddMemory";
6973
 
6974
		#設置參數
6975
		$argu[]="--onlyOutputCache";
6976
 
6977
		#設置參數
6978
		$argu[]="true";
6979
 
6980
		#設置參數
6981
		$argu[]="--cacheLayer";
6982
 
6983
		#設置參數
6984
		$argu[]="serverCache";
6985
 
6986
		#設置參數
6987
		$argu[]="--cacheLayer";
6988
 
6989
		#設置參數
6990
		$argu[]="serverSide";
6991
 
6992
		#設置參數
6993
		$argu[]="--cacheLayer";
6994
 
6995
		#設置參數
6996
		$argu[]="funcToRunWhenIdle";
6997
 
6998
		#設置參數
6999
		$argu[]="--cacheLayer";
7000
 
7001
		#設置參數
7002
		$argu[]="\qbpwcf\config::autoAddMemory";
7003
 
7004
		#設置參數
7005
		$argu[]="--cacheLayer";
7006
 
7007
		#設置參數
7008
		$argu[]="cache";
7009
 
7010
		#設置參數
7011
		$argu[]="--cacheLayer";
7012
 
7013
		#設置參數
7014
		$argu[]="stdout";
7015
 
7016
		#函式說明:
7017
		#呼叫shell執行系統命令,並取得回傳的內容.
7018
		#回傳結果:
7019
		#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
7020
		#$result["error"],錯誤訊息陣列.
7021
		#$result["function"],當前執行的函數名稱.
7022
		#$result["argu"],使用的參數.
7023
		#$result["cmd"],執行的指令內容.
7024
		#$result["fullCmd"],如果參數 $conf["inBackGround"] 為 "true" 則會回傳該值.
7025
		#$result["output"],爲執行完二元碼後的輸出陣列,若 $conf["inBackGround"] 為 "true",則為當下的輸出.
7026
		#$result["tmpFileOutput"],儲存輸出的暫存檔案名稱,若 $conf["inBackGround"] 為 "true" 則會回傳該值.
7027
		#$result["running"],是否還在執行.
7028
		#$result["pid"],pid.
7029
		#$result["statusCode"],執行結束後的代碼.
7030
		#$result["escape"],陣列,儲存重新排序過且已經escape過的指令(key為"cmd")與參數(key為"argu")與兩者組合的一維陣列(key為"array").
7031
		#必填參數:
7032
		#$conf["command"],字串,要執行的指令.
7033
		$conf["external::callShell"]["command"]="unixDomainSockServer.php";
7034
		#$conf["fileArgu"],字串,變數__FILE__的內容.
7035
		$conf["external::callShell"]["fileArgu"]=$conf["fileArgu"];
7036
		#可省略參數:
7037
		#$conf["argu"],陣列字串,指令搭配的參數,預設為空陣列.
7038
		$conf["external::callShell"]["argu"]=$argu;
7039
		#$conf["arguIsAddr"],陣列字串,指令搭配的哪些參數為路徑,為路徑的參數會進行轉換以便符合呼叫當前函數的位置,預設不指定,若有3個參數,其中第3個參數為路徑,則表示為array("false","false","true").
7040
		#$conf["arguIsAddr"]=array();
7041
		#$conf["pre"],陣列,要在本指令前執行的每個指令與參數.
7042
		#$conf["pre"][$i]["cmd"],字串,要在本指令前執行的第$i+1個指令.
7043
		#$conf["pre"][$i]["param"],陣列字串,要在本指令前執行的第$i+1個指令的參數.
7044
		#$conf["enablePrintDescription"],字串,是否要印出$conf["printDescription"]的內容,"true"代表要,"false"代表不要,預設為"false".
7045
		#$conf["enablePrintDescription"]="true";
7046
		#$conf["printDescription"],字串,執行該外部程式前要印出來的的文字,預設為$conf["command"]的內容加上使用的$conf["argu"]參數.
7047
		#$conf["printDescription"]="";
7048
		#$conf["escapeshellarg"],字串,是否要啟用過濾參數,用了比較安全,但可能會出錯,"true"為啟用,"false"為不啟用,預設為"false".如果參數為"< 、<< 、> 、>> 、| 、2>&1"之一則不會過濾.
7049
		$conf["external::callShell"]["escapeshellarg"]="true";
7050
		#$conf["thereIsShellVar"],陣列字串,指令搭配的參數"argu",若含有「\'」,則取代為「"」.每個argu參數都要有對應的元素."true"代表要置換.
7051
		#$conf["thereIsShellVar"]=array();
7052
		#$conf["username"],字串,要用什麼使用者來執行,預設為執行php的使用者,該參數不適用於apache環境.
7053
		#$conf["username"]="";
7054
		#$conf["password"],字串,root的使用者密碼,預設不使用密碼,該參數不適用於apache環境.
7055
		#$conf["password"]="";
7056
		#$conf["useScript"],字串,是否要啟用Linux的script指令來記錄輸出,"true"代表要,Fedora的selinux會擋住該操作;"false"代表不要,預設為"false".
7057
		#$conf["useScript"]="";
7058
		#$conf["logFilePath"],字串,當 $conf["useScript"] 為 "true" 時,輸出的內容要暫存到哪裡,預設為 "/tmp/.qbpwcf_tmp/external/callShell/".
7059
		#$conf["logFilePath"]=".qbpwcf_tmp/external/callShell/";
7060
		#$conf["inBackGround"],字串,是否要在背景執行,且不會等待程式執行結束再執行下一個指令,"true"代表是,"false"代表不要,預設為"false",如果$conf["command"]有用「;」區隔的多個指令將會出錯.
7061
		#$conf["inBackGround"]="";
7062
		#$conf["getErr"],字串,"true"代表將錯誤輸出變成標準輸出,反之"false"為不變動.
7063
		#$conf["getErr"]="false";
7064
		#$conf["doNotRun"],字串,"true"代表不執行指令,預設為"false"會執行指令.
7065
		$conf["external::callShell"]["doNotRun"]="true";
7066
		#參考資料:
7067
		#exec=>http://php.net/manual/en/function.exec.php
7068
		#escapeshellcmd=>http://php.net/manual/en/function.escapeshellcmd.php
7069
		#escapeshellarg=>http://php.net/manual/en/function.escapeshellarg.php
7070
		#備註:
7071
		#不是所有指令都能用apache的身份執行,目前已知java,javac指令無法執行,使用root身份可能會被selinux阻擋.
7072
		#若使用的 command、argu 參數,含有 ~ 則會被視為字串,若有需要其於 shell 中代表的家目錄位置,可用 fileAccess::tildeToPath 來進行轉換.
7073
		$callShell=external::callShell($conf["external::callShell"]);
7074
		unset($conf["external::callShell"]);
7075
 
7076
		#debug
7077
		#var_dump(__LINE__,$callShell);exit;
7078
 
7079
		#如果執行失敗
7080
		if($callShell["status"]==="false"){
7081
 
7082
			#如果socket存在
7083
			if(file_exists($tmpUnixDomainSock)){
7084
 
7085
				#移除之
7086
				unlink($tmpUnixDomainSock);
7087
 
7088
				}#if end
7089
 
7090
			#設置執行失敗
7091
			$result["status"]="false";
7092
 
7093
			#設置執行錯誤訊息
7094
			$result["error"]=$callShell;
7095
 
7096
			#回傳結果
7097
			return $result;
7098
 
7099
			}#if end
7100
 
7101
		#函式說明:
7102
		#將一維陣列轉換為用特定符號間隔的字串,ex:array("1","2","3") to "a;b;c;".
7103
		#回傳的結果:
7104
		#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
7105
		#$result["function"],當前執行的function名稱
7106
		#$result["error"],錯誤訊息陣列.
7107
		#$result["content"],處理好的字串.
7108
		#$result["argu"],使用的參數.
7109
		#必填參數:
7110
		#$conf["inputArray"],字串陣列,要轉成字串的一維陣列.
7111
		$conf["arrays::arrayToString"]["inputArray"]=$callShell["escape"]["array"];
7112
		#可省略參數:
7113
		#$conf["spiltSymbol"],字串,用來區隔字串的符號,預設為;
7114
		$conf["arrays::arrayToString"]["spiltSymbol"]=" ";
7115
		#$conf["skipEnd"],字串,結尾是否不要加上符號,預設為"false",要加上符號,"true"代表不要加上符號。
7116
		$conf["arrays::arrayToString"]["skipEnd"]="true";
7117
		#參考資料:
7118
		#無.
7119
		#備註:
7120
		#無.
7121
		$arrayToString=arrays::arrayToString($conf["arrays::arrayToString"]);
7122
		unset($conf["arrays::arrayToString"]);
7123
 
7124
		#如果執行失敗
7125
		if($arrayToString["status"]==="false"){
7126
 
7127
			#如果socket存在
7128
			if(file_exists($tmpUnixDomainSock)){
7129
 
7130
				#移除之
7131
				unlink($tmpUnixDomainSock);
7132
 
7133
				}#if end
7134
 
7135
			#設置執行失敗
7136
			$result["status"]="false";
7137
 
7138
			#設置執行錯誤訊息
7139
			$result["error"]=$arrayToString;
7140
 
7141
			#回傳結果
7142
			return $result;
7143
 
7144
			}#if end
7145
 
7146
		#函式說明:
7147
		#透過proc來多執行序運作.
7148
		#回傳結果:
7149
		#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
7150
		#$reuslt["error"],執行不正常結束的錯訊息陣列.
7151
		#$result["function"],當前執行的函式名稱.
7152
		#$result["argu"],使用的參數.
7153
		#$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"代表程序的資訊.
7154
		#必填參數:
7155
		#$conf["cmds"],字串陣列,每個元素代表要執行的指令與參數.
7156
		$conf["threads::proc"]["cmds"]=array($arrayToString["content"]);
7157
		#可省略參數:
7158
		#$conf["wait"],字串,是否需要等待所有程序結束,預設為"true"要等待;反之為"false"不要等待.
7159
		$conf["threads::proc"]["wait"]="false";
7160
		#$conf["workingDir"],字串陣列,個別程式執行時的家目錄,預設不指定.
7161
		#$conf["workingDir"]=array("path");
7162
		#$conf["envs"],2維字串陣列,每個元素代表個別程式執行時的指定環境變數,key變數名稱;value為變數內容.預設為array("QBPWCF" => "Quick Build PHP Website Componment base on Fedora Linux");
7163
		#$conf["envs"]=array(array("key"=>"value"));
7164
		#$conf["executeBy"],字串陣列,每個元素代表個別指令要用什麼程式執行,預設為"bash".
7165
		#$conf["executeBy"]=array("bash");
7166
		#參考資料:
7167
		#https://www.php.net/manual/en/function.proc-open.php
7168
		#https://www.php.net/manual/en/function.proc-get-status.php
7169
		#備註:
7170
		#無.
7171
		$procForUnixDoaminSocket=threads::proc($conf["threads::proc"]);	
7172
		unset($conf["threads::proc"]);	
7173
 
7174
		#如果執行失敗
7175
		if($procForUnixDoaminSocket["status"]==="false"){
7176
 
7177
			#如果socket存在
7178
			if(file_exists($tmpUnixDomainSock)){
7179
 
7180
				#移除之
7181
				unlink($tmpUnixDomainSock);
7182
 
7183
				}#if end
7184
 
7185
			#設置執行失敗
7186
			$result["status"]="false";
7187
 
7188
			#設置執行錯誤訊息
7189
			$result["error"]=$procForUnixDoaminSocket;
7190
 
7191
			#回傳結果
7192
			return $result;
7193
 
7194
			}#if end
7195
 
7196
		#var_dump($procForUnixDoaminSocket);exit;
7197
 
7198
		#如果 unix doamin socket server 沒有在運行
7199
		if($procForUnixDoaminSocket["content"][0]["proc_get_status"]["running"]===false){
7200
 
7201
			#如果socket存在
7202
			if(file_exists($tmpUnixDomainSock)){
7203
 
7204
				#移除之
7205
				unlink($tmpUnixDomainSock);
7206
 
7207
				}#if end
7208
 
7209
			#設置執行失敗
7210
			$result["status"]="false";
7211
 
7212
			#設置執行錯誤訊息
7213
			$result["error"]=$procForUnixDoaminSocket;
7214
 
7215
			#回傳結果
7216
			return $result;
7217
 
7218
			}#if end
7219
 
7220
		#如果當下 unix doamin socket server 沒有在運行
7221
		if(proc_get_status($procForUnixDoaminSocket["content"][0]["process"])["running"]===false){
7222
 
7223
			#如果socket存在
7224
			if(file_exists($tmpUnixDomainSock)){
7225
 
7226
				#移除之
7227
				unlink($tmpUnixDomainSock);
7228
 
7229
				}#if end
7230
 
7231
			#設置執行失敗
7232
			$result["status"]="false";
7233
 
7234
			#設置執行錯誤訊息
7235
			$result["error"]=$procForUnixDoaminSocket;
7236
 
7237
			#回傳結果
7238
			return $result;
7239
 
7240
			}#if end
7241
 
7242
		#debug
7243
		#var_dump(__LINE__,"before send msg");
7244
 
7245
		#初始化要求執行程式的訊息
7246
		$msg=array();
7247
 
7248
		#設置執行的指令
7249
		$msg["cmd2run"]=$conf["cmd"];
7250
 
7251
		#如果有參數
7252
		if(isset($conf["params"])){
7253
 
7254
			#設置參數
7255
			$msg["params"]=$conf["params"];
7256
 
7257
			}#if end
7258
 
7259
		#初始化儲存等待了幾秒
7260
		$waitSec=0;
7261
 
7262
		#無窮迴圈
7263
		while(true){
7264
 
7265
			#函式說明:
7266
			#連線到 unixDomainSockServer 提供的 unix domain socket.
7267
			#回傳結果:
7268
			#$result["status"],"true"代表執行正常;"false"代表執行不正常.
7269
			#$result["error"],錯誤訊息陣列.
7270
			#$result["function"],當前執行的函式名稱.
7271
			#$result["content"],取得的回應.
7272
			#必填參數:
7273
			#$conf["sock"],字串,要連線的unix domain socket.
7274
			$conf["sock::unixDomainSockClient"]["sock"]=$tmpUnixDomainSock;
7275
			#可省略參數:
7276
			#$conf["id"],字串,取得的id,若無此值,則會得到新的數值.
7277
			#$conf["id"]="";
7278
			#$conf["cmd"],字串,要執行的指令,當$conf["id"]參數合法時,才會執行.
7279
			#$conf["sock::unixDomainSockClient"]["cmd"]=$callShell["escape"]["cmd"];
7280
			#$conf["param"],參數陣列.
7281
			#$conf["sock::unixDomainSockClient"]["param"]=$callShell["escape"]["argu"];
7282
			#$conf["escaped"],字串,param參數是否已經escaped了,預設為"false",反之為"true".
7283
			#$conf["sock::unixDomainSockClient"]["escaped"]="true";
7284
			#$conf["custom"],陣列,要客制化傳輸的內容,會覆蓋以上除了$conf["id"]以外的可省略參數.
7285
			#$conf["custom"]=array();
7286
			#參考資料:
7287
			#http://php.net/manual/en/function.stream-socket-client.php
7288
			#http://php.net/manual/en/function.stream-get-contents.php
7289
			#備註:
7290
			#無.
7291
			$paramsOfUnixDomainSockClient=$conf["sock::unixDomainSockClient"];
7292
			$unixDomainSockClient=sock::unixDomainSockClient($paramsOfUnixDomainSockClient);
7293
			unset($paramsOfUnixDomainSockClient);
7294
 
7295
			#如果執行成功
7296
			if($unixDomainSockClient["status"]==="true"){
7297
 
7298
				#debug
7299
				#var_dump(__LINE__,"before parse id");
7300
 
7301
				#跳出while
7302
				break;
7303
 
7304
				}#if end
7305
 
7306
			#提示錯誤
7307
			else{
7308
 
7309
				#debug
7310
				#var_dump(__LINE__,$unixDomainSockClient);
7311
 
7312
				}#else end
7313
 
7314
			#如果當下 unix doamin socket server 沒有在運行
7315
			if(proc_get_status($procForUnixDoaminSocket["content"][0]["process"])["running"]===false){
7316
 
7317
				#如果socket存在
7318
				if(file_exists($tmpUnixDomainSock)){
7319
 
7320
					#移除之
7321
					unlink($tmpUnixDomainSock);
7322
 
7323
					}#if end
7324
 
7325
				#設置執行失敗
7326
				$result["status"]="false";
7327
 
7328
				#設置執行錯誤訊息
7329
				$result["error"][]="client取得回應前server就意外結束了";
7330
 
7331
				#設置執行錯誤訊息
7332
				$result["error"][]=$procForUnixDoaminSocket;
7333
 
7334
				#回傳結果
7335
				return $result;
7336
 
7337
				}#if end
7338
 
7339
			#等後1秒,擔心unix domain socket server 尚未跑起來.
7340
			sleep(1);
7341
 
7342
			#已等待時間加1秒
7343
			$waitSec=$waitSec+1;
7344
 
7345
			}#while end
7346
 
7347
		#debug
7348
		#var_dump(__LINE__,"json string got:".$unixDomainSockClient["content"]);
7349
 
7350
		#取得json回應
7351
		$jsonRes=json_decode($unixDomainSockClient["content"]);
7352
 
7353
		#如果執行失敗
7354
		if($jsonRes===null){
7355
 
7356
			#如果socket存在
7357
			if(file_exists($tmpUnixDomainSock)){
7358
 
7359
				#移除之
7360
				unlink($tmpUnixDomainSock);
7361
 
7362
				}#if end
7363
 
7364
			#設置執行錯誤識別
7365
			$result["status"]="false";
7366
 
7367
			#設置錯誤訊息
7368
			$result["error"]=$unixDomainSockClient;
7369
 
7370
			#回傳結果
7371
			return $result;
7372
 
7373
			}#if end
7374
 
7375
		#如果沒有產生新id
7376
		if(!isset($jsonRes->id)){
7377
 
7378
			#如果socket存在
7379
			if(file_exists($tmpUnixDomainSock)){
7380
 
7381
				#移除之
7382
				unlink($tmpUnixDomainSock);
7383
 
7384
				}#if end
7385
 
7386
			#設置執行錯誤識別
7387
			$result["status"]="false";
7388
 
7389
			#設置錯誤訊息
7390
			$result["error"]=$unixDomainSockClient;
7391
 
7392
			#回傳結果
7393
			return $result;
7394
 
7395
			}#if end
7396
 
7397
		#debug
7398
		#var_dump(__LINE__,"got id:".$jsonRes->id);
7399
 
7400
		#debug
7401
		#while(true){};
7402
 
7403
		#用新的id再傳送一次要求給 qbpwcf_usock_path
7404
		$paramsOfUnixDomainSockClient=array();
7405
		$paramsOfUnixDomainSockClient["sock"]=$tmpUnixDomainSock;
7406
		$paramsOfUnixDomainSockClient["id"]=$jsonRes->id;
7407
		$paramsOfUnixDomainSockClient["custom"]=$msg;
7408
		$unixDomainSockClient=sock::unixDomainSockClient($paramsOfUnixDomainSockClient);
7409
		unset($paramsOfUnixDomainSockClient);
7410
 
7411
		#debug
7412
		#var_dump(__LINE__,$unixDomainSockClient);
7413
 
7414
		#如果執行失敗
7415
		if($unixDomainSockClient["status"]==="false"){
7416
 
7417
			#如果socket存在
7418
			if(file_exists($tmpUnixDomainSock)){
7419
 
7420
				#移除之
7421
				unlink($tmpUnixDomainSock);
7422
 
7423
				}#if end
7424
 
7425
			#設置執行錯誤識別
7426
			$result["status"]="false";
7427
 
7428
			#設置錯誤訊息
7429
			$result["error"]=$unixDomainSockClient;
7430
 
7431
			#回傳結果
7432
			return $result;
7433
 
7434
			}#if end
7435
 
7436
		#debug
7437
		#var_dump(__LINE__,$unixDomainSockClient);
7438
 
7439
		#如果有回應的內容
7440
		if(!empty($unixDomainSockClient["content"])){
7441
 
7442
			#取得json回應
7443
			$jsonRes=(array)json_decode($unixDomainSockClient["content"]);
7444
 
7445
			#如果執行失敗
7446
			if($jsonRes===null){
7447
 
7448
				#如果socket存在
7449
				if(file_exists($tmpUnixDomainSock)){
7450
 
7451
					#移除之
7452
					unlink($tmpUnixDomainSock);
7453
 
7454
					}#if end
7455
 
7456
				#設置執行錯誤識別
7457
				$result["status"]="false";
7458
 
7459
				#設置錯誤訊息
7460
				$result["error"]=$unixDomainSockClient;
7461
 
7462
				#回傳結果
7463
				return $result;
7464
 
7465
				}#if end
7466
 
7467
			#如果執行指令失敗
7468
			if($jsonRes["status"]==="false"){
7469
 
7470
				#如果socket存在
7471
				if(file_exists($tmpUnixDomainSock)){
7472
 
7473
					#移除之
7474
					unlink($tmpUnixDomainSock);
7475
 
7476
					}#if end
7477
 
7478
				#設置執行錯誤識別
7479
				$result["status"]="false";
7480
 
7481
				#設置錯誤訊息
7482
				$result["error"]=$jsonRes["error"];
7483
 
7484
				#回傳結果
7485
				return $result;
7486
 
7487
				}#if end
7488
 
7489
			#印出client收到的結果
7490
			#var_dump($jsonRes);
7491
 
7492
			}#if end
7493
 
7494
		#debug
7495
		#var_dump(__LINE__,$procForUnixDoaminSocket);
7496
 
7497
		#初始化儲存標準輸出
7498
		$result["content"]["stdout"]="";
7499
 
7500
		#初始化儲存非標準輸出
7501
		$result["content"]["stderr"]="";
7502
 
7503
		#等待 unixDomainSockServer 結束執行
7504
		while(true){
7505
 
7506
			#取得程序狀態
7507
			$proc_get_status=proc_get_status($procForUnixDoaminSocket["content"][0]["process"]);
7508
 
7509
			/* debug
7510
 
7511
			#函式說明:
7512
			#撰寫log
7513
			#回傳結果:
7514
			#$result["status"],狀態,"true"或"false".
7515
			#$result["error"],錯誤訊息陣列.
7516
			#$result["function"],當前函式的名稱.
7517
			#$result["argu"],使用的參數.
7518
			#$result["content"],要寫入log的內容字串.
7519
			#必填參數:
7520
			#$conf["path"],字串,log檔案的路徑與名稱.
7521
			$conf["logs::record"]["path"]="/tmp/sock::runWithAutoAddMemoryDaemon.log";
7522
			#$conf["content"],any,要寫的內容,若內容不為字串則會用var_dump的格式寫入.
7523
			$conf["logs::record"]["content"]=$proc_get_status;
7524
			#$conf["fileArgu"],字串,php變數__FILE__的內容,亦即該檔案在檔案系統的絕對路徑
7525
			$conf["logs::record"]["fileArgu"]=__FILE__;
7526
			#可省略參數:
7527
			#$conf["rewrite"],預設為"false",接續寫入;反之"true"代表重新寫入.
7528
			#$conf["rewrite"]="false";
7529
			#$conf["returnOnly"],預設為"false",會寫入到log檔案.若為"true"則不會寫入log.
7530
			#$conf["returnOnly"]="true";
7531
			#參考資料:
7532
			#無.
7533
			#備註:
7534
			#無.
7535
			$record=logs::record($conf["logs::record"]);
7536
			unset($conf["logs::record"]);
7537
 
7538
			#如果執行失敗
7539
			if($record["status"]==="false"){
7540
 
7541
				#設置執行錯誤識別
7542
				$result["status"]="false";
7543
 
7544
				#設置執行錯誤
7545
				$result["error"]=$record;
7546
 
7547
				#回傳結果
7548
				return $result;
7549
 
7550
				}#if end
7551
 
7552
			*/
7553
 
7554
			#確認process是否存在
7555
			#ps auxwf | grep sshd | grep -v 'grep' | wc -l
7556
			#函式說明:
7557
			#呼叫shell執行系統命令,並取得回傳的內容.
7558
			#回傳結果:
7559
			#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
7560
			#$result["error"],錯誤訊息陣列.
7561
			#$result["function"],當前執行的函數名稱.
7562
			#$result["argu"],使用的參數.
7563
			#$result["cmd"],執行的指令內容.
7564
			#$result["fullCmd"],如果參數 $conf["inBackGround"] 為 "true" 則會回傳該值.
7565
			#$result["output"],爲執行完二元碼後的輸出陣列,若 $conf["inBackGround"] 為 "true",則為當下的輸出.
7566
			#$result["tmpFileOutput"],儲存輸出的暫存檔案名稱,若 $conf["inBackGround"] 為 "true" 則會回傳該值.
7567
			#$result["running"],是否還在執行.
7568
			#$result["pid"],pid.
7569
			#$result["statusCode"],執行結束後的代碼.
7570
			#$result["escape"],陣列,儲存重新排序過且已經escape過的指令(key為"cmd")與參數(key為"argu")與兩者組合的一維陣列(key為"array").
7571
			#必填參數:
7572
			#$conf["command"],字串,要執行的指令.
7573
			$conf["external::callShell"]["command"]="ps";
7574
			#$conf["fileArgu"],字串,變數__FILE__的內容.
7575
			$conf["external::callShell"]["fileArgu"]=$conf["fileArgu"];
7576
			#可省略參數:
7577
			#$conf["argu"],陣列字串,指令搭配的參數,預設為空陣列.
7578
			$conf["external::callShell"]["argu"]=array("auxwf","|","grep",$proc_get_status["pid"],"|","grep","-v","'grep'","|","wc","-l");
7579
			#$conf["arguIsAddr"],陣列字串,指令搭配的哪些參數為路徑,為路徑的參數會進行轉換以便符合呼叫當前函數的位置,預設不指定,若有3個參數,其中第3個參數為路徑,則表示為array("false","false","true").
7580
			#$conf["arguIsAddr"]=array();
7581
			#$conf["pre"],陣列,要在本指令前執行的每個指令與參數.
7582
			#$conf["pre"][$i]["cmd"],字串,要在本指令前執行的第$i+1個指令.
7583
			#$conf["pre"][$i]["param"],陣列字串,要在本指令前執行的第$i+1個指令的參數.
7584
			#$conf["enablePrintDescription"],字串,是否要印出$conf["printDescription"]的內容,"true"代表要,"false"代表不要,預設為"false".
7585
			#$conf["enablePrintDescription"]="true";
7586
			#$conf["printDescription"],字串,執行該外部程式前要印出來的的文字,預設為$conf["command"]的內容加上使用的$conf["argu"]參數.
7587
			#$conf["printDescription"]="";
7588
			#$conf["escapeshellarg"],字串,是否要啟用過濾參數,用了比較安全,但可能會出錯,"true"為啟用,"false"為不啟用,預設為"false".如果參數為"< 、<< 、> 、>> 、| 、2>&1"之一則不會過濾.
7589
			#$conf["escapeshellarg"]="false";
7590
			#$conf["thereIsShellVar"],陣列字串,指令搭配的參數"argu",若含有「\'」,則取代為「"」.每個argu參數都要有對應的元素."true"代表要置換.
7591
			#$conf["thereIsShellVar"]=array();
7592
			#$conf["username"],字串,要用什麼使用者來執行,預設為執行php的使用者,該參數不適用於apache環境.
7593
			#$conf["username"]="";
7594
			#$conf["password"],字串,root的使用者密碼,預設不使用密碼,該參數不適用於apache環境.
7595
			#$conf["password"]="";
7596
			#$conf["useScript"],字串,是否要啟用Linux的script指令來記錄輸出,"true"代表要,Fedora的selinux會擋住該操作;"false"代表不要,預設為"false".
7597
			#$conf["useScript"]="";
7598
			#$conf["logFilePath"],字串,當 $conf["useScript"] 為 "true" 時,輸出的內容要暫存到哪裡,預設為 "/tmp/.qbpwcf_tmp/external/callShell/".
7599
			#$conf["logFilePath"]=".qbpwcf_tmp/external/callShell/";
7600
			#$conf["inBackGround"],字串,是否要在背景執行,且不會等待程式執行結束再執行下一個指令,"true"代表是,"false"代表不要,預設為"false",如果$conf["command"]有用「;」區隔的多個指令將會出錯.
7601
			#$conf["inBackGround"]="";
7602
			#$conf["getErr"],字串,"true"代表將錯誤輸出變成標準輸出,反之"false"為不變動.
7603
			#$conf["getErr"]="false";
7604
			#$conf["doNotRun"],字串,"true"代表不執行指令,預設為"false"會執行指令.
7605
			#$conf["doNotRun"]="false";
7606
			#參考資料:
7607
			#exec=>http://php.net/manual/en/function.exec.php
7608
			#escapeshellcmd=>http://php.net/manual/en/function.escapeshellcmd.php
7609
			#escapeshellarg=>http://php.net/manual/en/function.escapeshellarg.php
7610
			#備註:
7611
			#不是所有指令都能用apache的身份執行,目前已知java,javac指令無法執行,使用root身份可能會被selinux阻擋.
7612
			#若使用的 command、argu 參數,含有 ~ 則會被視為字串,若有需要其於 shell 中代表的家目錄位置,可用 fileAccess::tildeToPath 來進行轉換.
7613
			$callShell=external::callShell($conf["external::callShell"]);
7614
			unset($conf["external::callShell"]);
7615
 
7616
			#如果執行失敗
7617
			if($callShell["status"]==="false"){
7618
 
7619
				#設置執行失敗
7620
				$result["status"]="false";
7621
 
7622
				#設置執行錯誤訊息
7623
				$result["error"]=$callShell;
7624
 
7625
				#回傳結果
7626
				return $result;
7627
 
7628
				}#if end
7629
 
7630
			#如果沒有輸出結果
7631
			if(!isset($callShell["output"][0])){
7632
 
7633
				#設置執行失敗
7634
				$result["status"]="false";
7635
 
7636
				#設置執行錯誤訊息
7637
				$result["error"]=$callShell;
7638
 
7639
				#回傳結果
7640
				return $result;
7641
 
7642
				}#if end
7643
 
7644
			#如果執行結束了
7645
			if( $proc_get_status["running"]===false || $callShell["output"][0]==="0" ){
7646
 
7647
				#取得程式執行過程產生的標準輸出
7648
				$result["content"]["stdout"]=$procForUnixDoaminSocket["content"][0]["content"];
7649
 
7650
				#如果是resource
7651
				if(gettype($result["content"]["stdout"])==="resource"){
7652
 
7653
					#讀取內容
7654
					$result["content"]["stdout"]=stream_get_contents($result["content"]["stdout"]);
7655
 
7656
					}#if end
7657
 
7658
				#取得程式執行過程產生的非標準輸出
7659
				$result["content"]["stderr"]=$procForUnixDoaminSocket["content"][0]["error"];
7660
 
7661
				#如果是resource
7662
				if(gettype($result["content"]["stderr"])==="resource"){
7663
 
7664
					#讀取內容
7665
					$result["content"]["stderr"]=stream_get_contents($result["content"]["stderr"]);
7666
 
7667
					}#if end
7668
 
7669
				#跳出 while
7670
				break;
7671
 
7672
				}#if end
7673
 
7674
			#休息1秒
7675
			sleep(1);
7676
 
7677
			}#while end
7678
 
7679
		#如果socket存在
7680
		if(file_exists($tmpUnixDomainSock)){
7681
 
7682
			#移除之
7683
			unlink($tmpUnixDomainSock);
7684
 
7685
			}#if end
7686
 
7687
		#設置執行正常
7688
		$result["status"]="true";
7689
 
7690
		#回傳結果
7691
		return $result;
7692
 
7693
		}#function runWithAutoAddMemoryDaemon end
7694
 
7695
	/*
7696
	#函式說明:
7697
	#用fwrite寫入到resource,可以指定每個寫入字串的結尾方式.
7698
	#回傳結果:
7699
	#$result["status"],執行是否正常,"true"為正常,"false"為不正常.
7700
	#$result["error"],錯誤訊息陣列.
7701
	#$result["function"],當前執行的函數名稱.
7702
	#$result["argu"],使用的參數.
7703
	#$result["is_writable"],參數stream是否為可寫入的resource,"true"代表可寫入;"false"代表不可寫入.
7704
	#必填參數:
7705
	#$conf["stream"],resource,寫入的目標.
7706
	$conf["stream"]="";
7707
	#$conf["data"],字串陣列,要寫入的內容,每個元素代表每段要寫入的內容.
7708
	$conf["data"]=array();
7709
	#可省略參數:
7710
	#$conf["msgEndType"],字串,訊息結尾要怎麼寫,預設為"none",代表不做處理;"EOL"代表結尾要用PHP_EOL;"HTTP/1.1"代表"data"參數最多為2個,分別為header跟body,結尾方式為兩個PHP_EOL.
7711
	#$conf["msgEndType"]="";
7712
	#$conf["autoClose"],字串,寫入結束後是否要關閉resource,預設為"false"代表保持開着;反之為"true".
7713
	#$conf["autoClose"]="false";
7714
	#參考資料:
7715
	#https://stackoverflow.com/questions/5294305/how-to-check-if-a-php-stream-resource-is-readable-or-writable#5294425
7716
	#https://www.php.net/manual/en/function.stream-get-meta-data.php
7717
	#https://www.php.net/manual/en/function.is-writable.php
7718
	#https://www.php.net/manual/en/function.socket-get-status.php
7719
	#https://www.php.net/manual/en/function.fopen.php
7720
	#備註:
7721
	#無.
7722
	*/
7723
	public static function fwrite(&$conf=array()){
7724
 
7725
		#初始化要回傳的結果
7726
		$result=array();
7727
 
7728
		#取得當前執行的函數名稱
7729
		$result["function"]=__FUNCTION__;
7730
 
7731
		#取得參數
7732
		$result["argu"]=$conf;
7733
 
7734
		#如果 $conf 不為陣列
7735
		if(gettype($conf)!="array"){
7736
 
7737
			#設置執行失敗
7738
			$result["status"]="false";
7739
 
7740
			#設置執行錯誤訊息
7741
			$result["error"][]="\$conf變數須為陣列形態";
7742
 
7743
			#如果傳入的參數為 null
7744
			if(is_null($conf)){
7745
 
7746
				#設置執行錯誤訊息
7747
				$result["error"][]="\$conf變數不得為null,請檢查函數「".$result["function"]."」的參數設置有無正確!";
7748
 
7749
				}#if end
7750
 
7751
			#回傳結果
7752
			return $result;
7753
 
7754
			}#if end
7755
 
7756
		#檢查參數
7757
		#函式說明:
7758
		#檢查必填與可省略的參數,可省略參數可指定預設要給與什麼數值內容.
7759
		#回傳結果:
7760
		#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
7761
		#$result["error"],執行不正常結束的錯訊息陣列.
7762
		#$result["simpleError"],簡單表示的錯誤訊息.
7763
		#$result["function"],當前執行的函式名稱.
7764
		#$result["argu"],設置給予的參數.
7765
		#$result["passed"],識別要檢查的全體變數是否存在以及型態是否正確的變數,"true"代表檢查全部通過;"false"代表檢查不通過
7766
		#$result[$shouldBeCheckedVarName]["varExist"],所檢查的變數是否存在,"false"代表不存在;"true"代表存在
7767
		#$result[$shouldBeCheckedVarName]["varType"],所檢查的變數型態是否正確,"false"代表錯誤;"true"代表正確
7768
		#$result[$shouldBeCheckedVarName]["error"],每個參數設定的錯誤訊息
7769
		#$result["shouldNotBeEmpty"],不應該為空字串或控陣列的變數.
7770
		#$result["argu"],字串陣列,目前輸入的參數名稱陣列.
7771
		#$result["legalVarName"],字串陣列,合法可用的參數名稱陣列.
7772
		#$result["notNeedVar"],字串陣列,多餘的參數名稱.
7773
		#必填參數:
7774
		#$conf["varInput"],陣列變數,要檢查的陣列變數,請在要檢查的參數前面加上&,這樣變動的結果才能被套用。
7775
		$conf["variableCheck::checkArguments"]["varInput"]=&$conf;
7776
		#$conf["referenceVarKey"],字串,$conf參數後面的key值,用於移除不要的參考陣列.
7777
		$conf["variableCheck::checkArguments"]["referenceVarKey"]="variableCheck::checkArguments";
7778
		#可省略參數:
7779
		#$conf["mustBeFilledVariableName"],爲必填參數的變數名稱陣列,形態爲陣列變數,元素數量需要跟"mustBeFilledVariableType"參數的元素數量一致,例如: $conf["mustBeFilledVariableName"] = array("id","account","password");
7780
		$conf["variableCheck::checkArguments"]["mustBeFilledVariableName"]=array("stream","data");
7781
		#$conf["mustBeFilledVariableType"],爲必填參數的變數陣列應該爲何種變數形態,形態爲陣列,元素數量需要跟"mustBeFilledVariableName"參數的元素數量一致,例如: $conf["mustBeFilledVariableType"] = array("string",integer,"double","resource","object"); , null代表不指定變數形態.
7782
		$conf["variableCheck::checkArguments"]["mustBeFilledVariableType"]=array("resource","array");
7783
		#$conf["canBeEmptyString"],字串,必填變數內容如果是空字串就不能算是有設置的話,請設為"false",預設爲"true",可以為空字串.
7784
		#$conf["variableCheck::checkArguments"]["canBeEmptyString"]="false";
7785
		#$conf["canNotBeEmpty"],字串陣列,哪些必填參數的內容不得為空字串或空陣列,僅當$conf["canBeEmptyString"]為"true"時會生效.
7786
		$conf["variableCheck::checkArguments"]["canNotBeEmpty"]=array("stream");
7787
		#$conf["canBeEmpty"],字串陣列,哪些必填參數的內容可為空字串或空陣列,僅當$conf["canBeEmptyString"]為"false"時會生效.
7788
		#$conf["canBeEmpty"]=array();
7789
		#$conf["skipableVariableCanNotBeEmpty"],字串陣列,哪些可省略參數不可以為空字串或空陣列.
7790
		$conf["variableCheck::checkArguments"]["skipableVariableCanNotBeEmpty"]=array("msgEndType","autoClose");
7791
		#$conf["skipableVariableName"],陣列字串,爲可省略參數的變數名稱陣列,形態爲陣列變數,例如: $conf["skipableVariableName"] = array("id","account","password");
7792
		$conf["variableCheck::checkArguments"]["skipableVariableName"]=array("msgEndType","autoClose");
7793
		#$conf["skipableVariableType"],陣列字串,爲可省略參數的變數名稱陣列,形態爲陣列變數,例如: $conf["skipableVariableType"] = array("string",integer,"double");
7794
		$conf["variableCheck::checkArguments"]["skipableVariableType"]=array("string","string");
7795
		#$conf["skipableVarDefaultValue"],字串陣列,每個不存在的可省略變數要初始化為什麼,null與代表不指定,若預設值是參數之一,請將$conf["mustBeFilledVar"]改成"\$conf["\mustBeFilledVar\"]".
7796
		$conf["variableCheck::checkArguments"]["skipableVarDefaultValue"]=array("none","false");
7797
		#$conf["disallowAllSkipableVarIsEmpty"],字串,是否允許每個可省略參數都為空字串,預設為"true"允許,反之為"false".
7798
		#$conf["disallowAllSkipableVarIsEmpty"]="";
7799
		#$conf["disallowAllSkipableVarIsEmptyArray"],字串,是否允許每個可省略參數都為空陣列,預設為"true"允許,反之為"false".
7800
		#$conf["disallowAllSkipableVarIsEmptyArray"]="";
7801
		#$conf["disallowAllSkipableVarNotExist"],字串,是否不允許每個可省略參數都不存在,預設為"false"代表允許,反之為"true".
7802
		#$conf["disallowAllSkipableVarNotExist"]="";
7803
		#$conf["arrayCountEqualCheck"],字串陣列,為檢查哪些陣列參數的元素數量要一樣,$conf["arrayCountEqualCheck"][$i]=array()為第$i組key為哪些的變數其元素數量要相等.
7804
		#$conf["arrayCountEqualCheck"][]=array();
7805
		#參考資料:
7806
		#array_keys=>http://php.net/manual/en/function.array-keys.php
7807
		#備註:
7808
		#無.
7809
		$checkArguments=variableCheck::checkArguments($conf["variableCheck::checkArguments"]);
7810
		unset($conf["variableCheck::checkArguments"]);
7811
 
7812
		#如果執行失敗
7813
		if($checkArguments["status"]==="false"){
7814
 
7815
			#設置執行失敗
7816
			$result["status"]="false";
7817
 
7818
			#設置錯誤資訊
7819
			$result["error"]=$checkArguments;
7820
 
7821
			#回傳結果
7822
			return $result;
7823
 
7824
			}#if end
7825
 
7826
		#如果檢查不通過
7827
		if($checkArguments["passed"]==="false"){
7828
 
7829
			#設置執行失敗
7830
			$result["status"]="false";
7831
 
7832
			#設置錯誤資訊
7833
			$result["error"]=$checkArguments;
7834
 
7835
			#回傳結果
7836
			return $result;
7837
 
7838
			}#if end
7839
 
7840
		#debug
7841
		#var_dump(__LINE__,$conf["stream"]);
7842
 
7843
		/*
7844
 
7845
		#函式說明:
7846
		#處理各種錯誤與例外.
7847
		#回傳結果:
7848
		#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
7849
		#$result["passed"],檢查是否通過,"true"代表通過,"false"代表不通過.
7850
		#$result["argu"],使用的參數.
7851
		#$result["function"],當前執行的函數.
7852
		#$result["error"],涵式錯誤訊息陣列.
7853
		#必填參數:
7854
		#無.
7855
		#可省略參數:
7856
		#$conf["allowCodition"],陣列,滿足什麼條件的錯誤跟例外要繼續執行而不中斷.
7857
		$conf["variableCheck::setErrorHandler"]["allowCodition"]=array("stream_get_meta_data(): supplied resource is not a valid stream resource","[function] => stream_get_meta_data");
7858
		#$conf["debug"],字串,"true"代表遇到不允許繼續執行的例外時要輸出debug資訊;預設為"false";
7859
		$conf["variableCheck::setErrorHandler"]["debug"]="true";
7860
		#$conf["format"],字串,遇到不允許的錯誤時,要用什麼格式呈現,預設為"html",其他選擇有"cmd".
7861
		#$conf["format"]="html";
7862
		#參考資料:
7863
		#無.
7864
		#備註:
7865
		#無.
7866
		$setErrorHandler=variableCheck::setErrorHandler($conf["variableCheck::setErrorHandler"]);
7867
		unset($conf["variableCheck::setErrorHandler"]);
7868
 
7869
		#如果有回傳內容
7870
		if($setErrorHandler!==null){
7871
 
7872
			#設置執行失敗
7873
			$result["status"]="false";
7874
 
7875
			#設置錯誤資訊
7876
			$result["error"]=$setErrorHandler;
7877
 
7878
			#回傳結果
7879
			return $result;
7880
 
7881
			}#if end
7882
 
7883
		*/
7884
 
7885
		#取得 stream 狀態
7886
		$stream_get_meta_data=stream_get_meta_data($conf["stream"]);
7887
 
7888
		#debug
7889
		#var_dump(__LINE__,$stream_get_meta_data);
7890
 
7891
		#如果存在 uri
7892
		if(isset($stream_get_meta_data["uri"])){
7893
 
7894
			#取得能否寫入
7895
			$is_writable=is_writable($stream_get_meta_data["uri"]);
7896
 
7897
			}#if end
7898
 
7899
		#反之用 mode 來判斷
7900
		else if(isset($stream_get_meta_data["mode"])){
7901
 
7902
			#函式說明:
7903
			#檢查一個字串裡面是否有多個關鍵字
7904
			#回傳結果:
7905
			#$result["status"],"true"代表執行成功,"false"代表執行失敗.
7906
			#$result["error"],錯誤訊息.
7907
			#$result["function"],當前執行的函數名稱.
7908
			#$result["founded"],是否有找到的關鍵字,"true"代表有找到關鍵字;"false"代表沒有找到關鍵字.
7909
			#$result["foundedKeyWords"],找到的關鍵字.
7910
			#$result["foundedAll"],是否有找到全部的關鍵字,"true"代表有;"false"代表沒有.
7911
			#$result["argu"],使用的參數.
7912
			#必填參數:
7913
			#$conf["keyWords"],字串陣列,想要搜尋的關鍵字.
7914
			$conf["search::findManyKeyWords"]["keyWords"]=array("r+","w","a","x","c");
7915
			#$conf["string"],字串,要被搜尋的字串內容.
7916
			$conf["search::findManyKeyWords"]["string"]=$stream_get_meta_data["mode"];
7917
			#可省略參數:
7918
			#$conf["completeEqual"],字串,是否內容要完全符合,不能多出任何不符合的內容,預設為不需要完全符合.
7919
			#$conf["completeEqual"]="true";
7920
			#參考資料:
7921
			#無.
7922
			#備註:
7923
			#無.
7924
			$findManyKeyWords=search::findManyKeyWords($conf["search::findManyKeyWords"]);
7925
			unset($conf["search::findManyKeyWords"]);
7926
 
7927
			#如果執行失敗
7928
			if($findManyKeyWords["status"]==="false"){
7929
 
7930
				#設置執行失敗
7931
				$result["status"]="false";
7932
 
7933
				#設置錯誤資訊
7934
				$result["error"]=$findManyKeyWords;
7935
 
7936
				#回傳結果
7937
				return $result;
7938
 
7939
				}#if end
7940
 
7941
			#如果模式含有寫入的屬性
7942
			if($findManyKeyWords["founded"]==="true"){
7943
 
7944
				#設置可以寫入
7945
				$is_writable=true;
7946
 
7947
				}#if end
7948
 
7949
			}#else 
7950
 
7951
		#反之需要其他判斷方式
7952
		else{
7953
 
7954
			#設置警示訊息
7955
			$result["warning"][]="無法判別 resource 能否寫入";
7956
 
7957
			#設置警示訊息
7958
			$result["warning"][]=$stream_get_meta_data;
7959
 
7960
			#直接放行
7961
			$is_writable=true;
7962
 
7963
			}#else end
7964
 
7965
		#如果不可寫入
7966
		if($is_writable!==true){
7967
 
7968
			#設置執行失敗
7969
			$result["status"]="false";
7970
 
7971
			#設置錯誤資訊
7972
			$result["error"][]="resource 無法寫入";
7973
 
7974
			#設置錯誤資訊
7975
			$result["error"][]=$stream_get_meta_data;
7976
 
7977
			#設置resource不可寫入
7978
			$result["is_writable"]="false";
7979
 
7980
			#回傳結果
7981
			return $result;
7982
 
7983
			}#if end
7984
 
7985
		#設置resource可寫入
7986
		$result["is_writable"]="true";
7987
 
7988
		#判斷訊息結尾的格式
7989
		switch($conf["msgEndType"]){
7990
 
7991
			#如果是 "none"
7992
			case "none":
7993
 
7994
				#要寫入的每個字串
7995
				foreach($conf["data"] as $msg){
7996
 
7997
					#寫入內容
7998
					fwrite($conf["stream"],$msg);
7999
 
8000
					}#foreach end
8001
 
8002
				break;
8003
 
8004
			#如果是 "EOL"
8005
			case "EOL":
8006
 
8007
				#要寫入的每個字串
8008
				foreach($conf["data"] as $msg){
8009
 
8010
					#寫入內容,用PHP_EOL結尾.
8011
					fwrite($conf["stream"],$msg.PHP_EOL);
8012
 
8013
					}#foreach end
8014
 
8015
				break;
8016
 
8017
			#如果是 "HTTP/1.1"
8018
			case "HTTP/1.1":
8019
 
8020
				#如果要寫入的字串大於2段
8021
				if(count($conf["data"])>2){
8022
 
8023
					#設置執行失敗
8024
					$result["status"]="false";
8025
 
8026
					#設置錯誤資訊
8027
					$result["error"][]="當參數 msgEndType 為 ".$conf["msgEndType"]." 時,參數 data 的數量不得超過2個.";
8028
 
8029
					#設置resource不可寫入
8030
					$result["is_writable"]="false";
8031
 
8032
					#回傳結果
8033
					return $result;
8034
 
8035
					}#if end
8036
 
8037
				#要寫入的每個字串
8038
				foreach($conf["data"] as $msg){
8039
 
8040
					#寫入 header/body
8041
					fwrite($conf["stream"],$msg.PHP_EOL.PHP_EOL);
8042
 
8043
					}#foreach end
8044
 
8045
				#跳出switch
8046
				break;
8047
 
8048
			#非預期的類型
8049
			default:
8050
 
8051
				#設置執行失敗
8052
				$result["status"]="false";
8053
 
8054
				#設置錯誤資訊
8055
				$result["error"][]="unsupported msgEndType ".$conf["msgEndType"];
8056
 
8057
				#回傳結果
8058
				return $result;
8059
 
8060
			}#switch end
8061
 
8062
		#若要關閉resource
8063
		if($conf["autoClose"]==="true"){
8064
 
8065
			#關閉resouce.
8066
			fclose($conf["stream"]);
8067
 
8068
			}#if end
8069
 
8070
		#設置執行正常
8071
		$result["status"]="true";
8072
 
8073
		#回傳結果
8074
		return $result;
8075
 
8076
		}#function fwrite end
8077
 
8078
	}#class sock end
8079
 
8080
?>