Subversion Repositories qbpwcf-lib(archive)

Rev

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

Rev Author Line No. Line
1 liveuser 1
<?php
2
/*
3
 
4
	QBPWCF, Quick Build PHP website Component base on Fedora Linux.
624 liveuser 5
    Copyright (C) 2015~2024 Min-Jhin,Chen
1 liveuser 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
 
243 liveuser 25
/*
26
類別說明:
27
跟socket應用相關的類別.
28
備註:
29
無.
30
*/
1 liveuser 31
class sock{
21 liveuser 32
 
1 liveuser 33
	/*
34
	#函式說明:
35
	#當前類別被呼叫的靜態方法不存在時,將會執行該函數,回報該方法不存在.
36
	#回傳結果:
37
	#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
38
	#$reuslt["error"],執行不正常結束的錯訊息陣列.
39
	#$result["function"],當前執行的函式名稱.
40
	#必填參數:
41
	#$method,物件,為物件實體或類別名稱,會自動置入該參數.
42
	#$arguments,陣列,為呼叫方法時所用的參數.
216 liveuser 43
	#可省略參數:
44
	#無.
1 liveuser 45
	#參考資料:
46
	#__call=>http://php.net/manual/en/language.oop5.overloading.php#object.callstatic
216 liveuser 47
	#備註:
48
	#無.
1 liveuser 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,陣列,為呼叫方法時所用的參數.
216 liveuser 79
	#可省略參數:
80
	#無.
1 liveuser 81
	#參考資料:
216 liveuser 82
	#__callStatic=>http://php.net/manual/en/language.oop5.overloading.php#object.callstatic
83
	#備註:
84
	#無.
1 liveuser 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
	#函式說明:
386 liveuser 107
	#建立 unix domain socket server, 僅提供具備檔案存取權限的用戶使用,預設提供可以下達任何指令的功能.
1 liveuser 108
	#回傳結果:
109
	#$result["status"],"true"代表執行正常;"false"代表執行不正常.
110
	#$result["error"],錯誤訊息陣列.
111
	#$result["function"],當前執行的函式名稱.
668 liveuser 112
	#$result["serverCache"],函式結束前,儲存在serverCache的內容,若有元素"exit"存在則代表是正常結束.
851 liveuser 113
	#$result["serverCache"]["serverSide"],server side 的 cache.
114
	#$result["serverCache"]["serverSide"]["procs"], server side 的 procs cache,儲存執行的子程序資訊.
115
	#$result["serverCache"]["clientSide"],client site 的 cache.
1 liveuser 116
	#必填參數:
117
	#$conf["sock"],字串,socket檔案要放在哪邊,名稱為何.
118
	$conf["sock"]="";
119
	#$conf["fileArgu"],字串,變數__FILE__的內容.
2 liveuser 120
	$conf["fileArgu"]=__FILE__;
1 liveuser 121
	#可省略參數:
122
	#$conf["changeOwner"],字串,要將socket檔案的擁有着權限進行修改."user.group"代表擁有者帳號為user,群組為group.
123
	#$conf["changeOwner"]="";
591 liveuser 124
	#$conf["changePermission"],字串,要將socket檔案的權限設為多少.ex: "0666"(所有帳戶都有存取的權限) 或 "0660"(僅有擁有者與群組帳戶有存取的權限) 或 "0600"(只有擁有者有權限執行).
1 liveuser 125
	#$conf["changePermission"]="";
126
	#$conf["sessionTimeout"],字串,當連線結束後於下一次連線間隔多久就算session timeout,server端會將記錄移除,client端需要重新拿取id,預設為300秒.
127
	#$conf["sessionTimeout"]="300";
705 liveuser 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"代表執行不正常.
386 liveuser 129
	#$conf["addOnProcessFunc"]=array();
668 liveuser 130
	#$conf["funcToRunWhenIdle"],字串陣列,當沒有事件產生時,要執行的函式名稱,給予參數為array("client"=>所有用戶,"clientCache"=>$result["serverCache"]["clientSide"]["addOnProcessFunc"][$funcToRunWhenIdle],"serverCache"=>$result["serverCache"]["serverSide"]["funcToRunWhenIdle"][$funcToRunWhenIdle]).
387 liveuser 131
	#$conf["funcToRunWhenIdle"]=array();
667 liveuser 132
	#$conf["paramsForFuncToRunWhenIdle"],2維陣列,每個元素代表指定給予funcToRunWhenIdle參數中的指定元素的參數.
133
	#$conf["paramsForFuncToRunWhenIdle"]=array();
565 liveuser 134
	#$conf["infoToFunction"],陣列,需要增加給addOnProcessFunc跟funcToRunWhenIdle函式的資訊,在函式中其參數的info鍵值.
135
	#$conf["infoToFunction"]=array("debug"=>$debug);
669 liveuser 136
	#$conf["shutdownStrAddr"],字串,儲存收到用戶傳什麼樣的字串會結束本函式的檔案位置與名稱,預設為 $conf["sock"].".shutdown".
137
	#$conf["shutdownStrAddr"]="";
1 liveuser 138
	#參考資料:
139
	#http://php.net/manual/en/function.stream-socket-server.php
216 liveuser 140
	#備註:
141
	#無.
1 liveuser 142
	*/
216 liveuser 143
	public static function unixDomainSockServer(&$conf){
1 liveuser 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
206
 
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"],字串陣列,哪些可省略參數不可以為空字串或空陣列.
669 liveuser 239
		$conf["variableCheck::checkArguments"]["skipableVariableCanNotBeEmpty"]=array("changeOwner","changePermission","sessionTimeout","addOnProcessFunc","funcToRunWhenIdle","infoToFunction","shutdownStrAddr");
1 liveuser 240
		#$conf["skipableVariableName"],陣列字串,爲可省略參數的變數名稱陣列,形態爲陣列變數,例如: $conf["skipableVariableName"] = array("id","account","password");
669 liveuser 241
		$conf["variableCheck::checkArguments"]["skipableVariableName"]=array("changeOwner","changePermission","sessionTimeout","addOnProcessFunc","funcToRunWhenIdle","infoToFunction","paramsForFuncToRunWhenIdle","shutdownStrAddr");
1 liveuser 242
		#$conf["skipableVariableType"],陣列字串,爲可省略參數的變數名稱陣列,形態爲陣列變數,例如: $conf["skipableVariableType"] = array("string",integer,"double"); 
669 liveuser 243
		$conf["variableCheck::checkArguments"]["skipableVariableType"]=array("string","string","string","array","array","array","array","array");
244
		#$conf["skipableVarDefaultValue"],字串陣列,每個不存在的可省略變數要初始化為什麼,null與代表不指定,若預設值是參數之一,請將$conf["mustBeFilledVar"]改成"\$conf[\"mustBeFilledVar\"]".
245
		$conf["variableCheck::checkArguments"]["skipableVarDefaultValue"]=array(null,null,"300",null,null,null,array(),null);
1 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
		#如果 $conf["sock"] 存在
286
		if(file_exists($conf["sock"])){
287
 
288
			#則移除之.
289
			unlink($conf["sock"]);
290
 
291
			}#if end
292
 
706 liveuser 293
		#取得 socket 的路徑
294
		#函式說明:
295
		#將字串特定關鍵字與其後面的內容剔除
296
		#回傳結果:
297
		#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
298
		#$result["error"],錯誤訊息陣列.
299
		#$result["warning"],警告訊息鎮列.
300
		#$result["founded"],有無找到定字串"true"代表有,"false"代表沒有.
301
		#$result["function"],當前執行的函數名稱.
302
		#$result["oriStr"],要處理的原始字串內容.
303
		#$result["content"],處理好的的字串內容.
304
		#$result["argu"],使用的參數.
305
		#必填參數:
306
		#$conf["stringIn"],字串,要處理的字串.
307
		$conf["stringProcess::delStrAfterKeyWord"]["stringIn"]=$conf["sock"];
308
		#$conf["keyWord"],字串,特定字串.
309
		$conf["stringProcess::delStrAfterKeyWord"]["keyWord"]="/";
310
		#可省略參數:
311
		#$conf["deleteLastRepeatedOne"],字串,預設為"false";若為"true"則代表連續遇到同 $conf["keyWord"] 的內容,要將移除內容的起點往後移動到為後一個 $conf["keyWord"].
312
		$conf["stringProcess::delStrAfterKeyWord"]["deleteLastRepeatedOne"]="true";
313
		#參考資料:
314
		#無.
315
		#備註:
316
		#無.
317
		$delStrAfterKeyWord=stringProcess::delStrAfterKeyWord($conf["stringProcess::delStrAfterKeyWord"]);
318
		unset($conf["stringProcess::delStrAfterKeyWord"]);
319
 
320
		#如果執行失敗
321
		if($delStrAfterKeyWord["status"]==="false"){
322
 
323
			#設置執行失敗
324
			$result["status"]="false";
325
 
326
			#設置錯誤訊息
327
			$result["error"][]=$delStrAfterKeyWord;
328
 
329
			#設置錯誤訊息
330
			$result["error"][]="建立 unix domain socket(".$conf["sock"].") 失敗";
331
 
332
			#印出錯誤訊息
333
			echo print_r($result,true);
334
 
335
			#回傳結果
336
			return $result;
337
 
338
			}#if end
339
 
340
		#如果有 "/"
341
		if($delStrAfterKeyWord["founded"]==="true"){
342
 
343
			#確保建立socket的路徑有存在
344
			#函式說明:
345
			#確保路徑存在.
346
			#回傳結果:
347
			#$result["status"],執行正常與否,"true"代表正常,"false"代表不正常.
348
			#$result["error"],錯誤訊息陣列.
349
			#$resutl["function"],當前執行的涵式名稱.
350
			#$result["path"],建立好的路徑字串.
351
			#$result["fileName"],檔案名稱,若 $conf["haveFileName"] 為 "true" 則會回傳.
352
			#$result["argu"],使用的參數.
353
			#必填參數:
354
			#$conf["path"],要檢查的路徑
355
			$conf["fileAccess::validatePath"]["path"]=$delStrAfterKeyWord["content"];		
356
			#$conf["fileArgu"],字串,php變數__FILE__的內容,亦即該檔案在檔案系統的絕對路徑
357
			$conf["fileAccess::validatePath"]["fileArgu"]=__FILE__;
358
			#可省略參數:
359
			#$conf["haveFileName"],字串,"true"代表有$conf["path"]檔案名稱,"false"代表$conf["path"]為純路徑,預設為"false".
360
			$conf["fileAccess::validatePath"]["haveFileName"]="false";
361
			#$conf["dirPermission"],字串,新建資料夾的權限設定,預設爲0770,亦即擁有者,同群組者可以讀,寫,存取,其他人僅能存取.
362
			#$conf["dirPermission"]="";
363
			#$conf["web"],是否為檔案系統,"true"為網頁路徑,"false"為網頁系統,預設為"false".
364
			$conf["fileAccess::validatePath"]["web"]="false";
365
			#參考資料:
366
			#無.
367
			#備註:
368
			#無.
369
			$validatePath=fileAccess::validatePath($conf["fileAccess::validatePath"]);
370
			unset($conf["fileAccess::validatePath"]);
371
 
372
			#如果執行失敗
373
			if($validatePath["status"]==="false"){
374
 
375
				#設置執行失敗
376
				$result["status"]="false";
377
 
378
				#設置錯誤訊息
379
				$result["error"][]=$validatePath;
380
 
381
				#設置錯誤訊息
382
				$result["error"][]="建立 unix domain socket(".$conf["sock"].") 失敗";
383
 
384
				#印出錯誤訊息
385
				echo print_r($result,true);
386
 
387
				#回傳結果
388
				return $result;
389
 
390
				}#if end
391
 
392
			}#if end
393
 
1 liveuser 394
		#建立 unix domain socket
395
		$socket=stream_socket_server("unix://".$conf["sock"], $errno, $errstr);
396
 
397
		#如果建立 unix domain socket 失敗
398
		if(!$socket){
399
 
400
			#設置執行失敗
401
			$result["status"]="false";
402
 
403
			#設置錯誤訊息
706 liveuser 404
			$result["error"][]=$errstr." (".$errno.")";
1 liveuser 405
 
706 liveuser 406
			#設置錯誤訊息
407
			$result["error"][]="建立 unix domain socket(".$conf["sock"].") 失敗";
408
 
1 liveuser 409
			#印出錯誤訊息
410
			echo print_r($result,true);
411
 
412
			#回傳結果
413
			return $result;
414
 
415
			}#if end
416
 
417
		#如果建立 unix domain socket 成功
418
		else{
419
 
669 liveuser 420
			#產生用於代表結束本函式的字串
421
			#函式說明:
422
			#使用 linux 的 uuid 指令來產生 uuid 字串
423
			#回傳結果:
424
			#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
425
			#$result["error"],錯誤訊息.
426
			#$result["function"],當前執行的函式名稱.
427
			#$result["content"],uuid.
428
			#必填參數:
429
			#無.
430
			#可省略參數:
431
			#無.
432
			#參考資料:
433
			#無.
434
			#備註:
435
			#無.
436
			$uuid=cmd::uuid();
437
 
438
			#如果執行失敗
439
			if($uuid["status"]==="false"){
440
 
441
				#設置執行失敗
442
				$result["status"]="false";
443
 
444
				#設置錯誤訊息
445
				$result["error"]=$uuid;
446
 
447
				#回傳結果
448
				return $result;
449
 
450
				}#if end
451
 
452
			#設置代表結束本服務的uuid字串
453
			$shutdownStr=$uuid["content"];
454
 
455
			#如果沒有設置
456
			if(!isset($conf["shutdownStrAddr"])){
457
 
458
				#初始化存放 shutdownStr 的檔案
459
				$conf["shutdownStrAddr"]=$conf["sock"].".shutdownStr";
460
 
461
				}#if end
462
 
463
			#如果檔案位置名稱跟socket一樣
464
			else if($conf["sock"]===$conf["shutdownStrAddr"]){
465
 
466
				#設置執行失敗
467
				$result["status"]="false";
468
 
469
				#設置錯誤訊息
470
				$result["error"][]="參數shutdownStrAddr跟sock不可一樣";
471
 
472
				#設置錯誤訊息
473
				$result["error"][]=$checkArguments;
474
 
475
				#回傳結果
476
				return $result;
477
 
478
				}#else end
479
 
480
			#建立裡面儲存若要結束本程式需要接收到什麼樣的字串
481
			#函式說明:
482
			#將字串寫入到檔案
483
			#回傳結果:
484
			#$result["status"],"true"表示檔案寫入成功,"false"表示檔案寫入失敗.
485
			#$result["error"],錯誤訊息陣列.
486
			#$result["function"],當前執行的函數名稱.
487
			#$result["fileInfo"],實際上寫入的檔案資訊陣列.
488
			#$result["fileInfo"]["createdFileName"],建立好的檔案名稱.
489
			#$result["fileInfo"]["createdFilePath"],檔案建立的路徑.
490
			#$result["fileInfo"]["createdFilePathAndName"].建立好的檔案名稱與路徑.
491
			#$result["argu"],使用的參數.
492
			#必填參數:
493
			#$conf["fileArgu"],字串,php變數__FILE__的內容,亦即該檔案在檔案系統的絕對路徑
494
			$conf["fileAccess::writeTextIntoFile"]["fileArgu"]=$conf["fileArgu"];
495
			#可省略參數:
496
			#$conf["fileName"],字串,爲要編輯的檔案名稱,預設為隨機產生的檔案名稱.
497
			$conf["fileAccess::writeTextIntoFile"]["fileName"]=$conf["shutdownStrAddr"];
498
			#$conf["inputString"],字串,爲要寫入到裏面的內容,若要每筆資料寫入後換行,則可以在字串內容後面加上 \r\n 即可,預設為"".
499
			$conf["fileAccess::writeTextIntoFile"]["inputString"]=$shutdownStr;
500
			#$conf["writeMethod"],字串,爲檔案撰寫的方式,可省略,是複寫'a'還是,重新寫入'w',預設爲'w',重新寫入.
501
			#$conf["writeMethod"]="a";
502
			#$conf["checkRepeat"],字串,"true"代表建立檔案之前要先檢查檔案是否存在,若存在則在原名稱後面加上從(1)開始的編號.
503
			#$conf["checkRepeat"]="";
504
			#$conf["filenameExtensionStartPoint"],字串,檔案的副檔名是從倒數第幾個小數點(dot)開始,預設為"1",最後一個小數點,必須與$conf["checkRepeat"]搭配才會生效.
505
			#$conf["filenameExtensionStartPoint"]="";
506
			#$conf["repeatNameRule"],字串,遇到相同名稱的檔案要如何加上識別的編號,編號用「\$i」表示,預設為"(\$i)",必須與$conf["checkRepeat"]搭配才會生效.
507
			#$conf["repeatNameRule"]="";
508
			#$conf["web"],檔案是否位於網站上"true",若是在檔案系統則為"false",預設為"true".
509
			$conf["fileAccess::writeTextIntoFile"]["web"]="false";
510
			#參考資料:
511
			#無.
512
			#備註:
513
			#無.
514
			$writeTextIntoFile=fileAccess::writeTextIntoFile($conf["fileAccess::writeTextIntoFile"]);
515
			unset($conf["fileAccess::writeTextIntoFile"]);
516
 
517
			#如果執行失敗
518
			if($writeTextIntoFile["status"]==="false"){
519
 
520
				#設置執行失敗
521
				$result["status"]="false";
522
 
523
				#設置錯誤訊息
524
				$result["error"]=$writeTextIntoFile;
525
 
526
				#回傳結果
527
				return $result;
528
 
529
				}#if end
530
 
531
			#debug
851 liveuser 532
			#var_dump(__LINE__,$writeTextIntoFile);exit;
669 liveuser 533
 
1 liveuser 534
			#初始化 client 陣列
535
			$client=array();
536
 
537
			#如果有設置$conf["changeOwner"]
538
			if(isset($conf["changeOwner"])){
539
 
540
				#如果裡面的"."不是一個
541
				if(substr_count($conf["changeOwner"],".")!==1){
542
 
543
					#設置執行失敗
544
					$result["status"]="false";
545
 
546
					#設置錯誤訊息
547
					$result["error"][]="參數 changeOwner 應為 username.groupname";
548
 
549
					#印出錯誤訊息
550
					echo print_r($result,true);
551
 
552
					#回傳結果
553
					return $result;
554
 
667 liveuser 555
					}#if end
714 liveuser 556
 
1 liveuser 557
				#改變檔案的擁有者
714 liveuser 558
				#函式說明:
559
				#使用 linux 的 chown 指令來修改目標檔案或目錄的擁有者跟群組擁有者資訊.
560
				#回傳結果:
561
				#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
562
				#$result["error"],錯誤訊息.
563
				#$result["function"],當前執行的函式名稱.
564
				#$result["cmd"],執行的指令.
565
				#$result["content"],執行的結果陣列,如果參數 "recursive" 跟 "excludeSelf" 都有設定的話,就會回傳該結果.
566
				#必填參數:
567
				#$conf["owner"],字串,要變哪個使用者擁有.
568
				$conf["cmd::chown"]["owner"]=explode(".",$conf["changeOwner"])[0];
569
				#$conf["target"],字串,需要變更擁有者、 群組的目標.
570
				$conf["cmd::chown"]["target"]=$conf["sock"];
571
				#可省略參數:
572
				#$conf["group"],字串,要變成什麼群組擁有,預設跟"owner"一樣.
573
				$conf["cmd::chown"]["group"]=explode(".",$conf["changeOwner"])[1];
574
				#$conf["recursive"],字串,"true"代表目標目錄底下的內容都要套用,預設為"false".
575
				#$conf["recursive"]="true";
576
				#$conf["excludeSelf"],字串,預設為"false"代表不處理;若為"true"則會排除目標自己(資料夾).
577
				#$conf["excludeSelf"]="true";
578
				#參考資料:
579
				#無.
580
				#備註:
581
				#無.
582
				$chown=cmd::chown($conf["cmd::chown"]);
583
				unset($conf["cmd::chown"]);
584
 
1 liveuser 585
				#如果改變檔案擁有者限失敗
586
				if($chown===false){
587
 
588
					#設置執行失敗
589
					$result["status"]="false";
590
 
591
					#設置錯誤訊息
2 liveuser 592
					$result["error"][]="改變 ".$conf["sock"]." 檔案的擁有資訊為 ".explode(".",$conf["changeOwner"])[0]." 失敗,通常只有系統帳戶才能變更之.";
1 liveuser 593
 
594
					#印出錯誤訊息
595
					echo print_r($result,true);
596
 
597
					#回傳結果
598
					return $result;	
599
 
600
					}#if end
601
 
602
				}#if end
603
 
604
			#如果有設置 $conf["changePermission"]
605
			if(isset($conf["changePermission"])){
606
 
582 liveuser 607
				#函式說明:
714 liveuser 608
				#使用 linux 的 chmod 指令來修改目標檔案或目錄的權限.
582 liveuser 609
				#回傳結果:
610
				#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
611
				#$result["error"],錯誤訊息.
612
				#$result["function"],當前執行的函式名稱.
613
				#$result["cmd"],執行的指令.
614
				#$result["content"],執行的結果陣列,如果參數 "recursive" 跟 "excludeSelf" 都有設定的話,就會回傳該結果.
615
				#必填參數:
616
				#$conf["mode"],字串,要變成什麼權限.
714 liveuser 617
				$conf["cmd::chmod"]["mode"]=$conf["changePermission"];
582 liveuser 618
				#$conf["target"],字串,需要變更權限的目標.
714 liveuser 619
				$conf["cmd::chmod"]["target"]=$conf["sock"];
582 liveuser 620
				#可省略參數:
714 liveuser 621
				#$conf["recursive"],字串,"true"代表目標目錄底下的內容都要套用,預設為"false".
622
				#$conf["recursive"]="true";
623
				#$conf["excludeSelf"],字串,預設為"false"代表不處理;若為"true"則會排除目標自己(資料夾).
624
				#$conf["excludeSelf"]="true";
582 liveuser 625
				#參考資料:
626
				#無.
627
				#備註:
628
				#無.
714 liveuser 629
				$chmod=cmd::chmod($conf["cmd::chmod"]);
630
				unset($conf["cmd::chmod"]);
1 liveuser 631
 
582 liveuser 632
				#如果變更檔案權限失敗
633
				if($chmod["status"]==="false"){
634
 
1 liveuser 635
					#設置執行失敗
636
					$result["status"]="false";
637
 
638
					#設置錯誤訊息
591 liveuser 639
					$result["error"]=$chmod;
1 liveuser 640
 
641
					#印出錯誤訊息
642
					echo print_r($result,true);
643
 
644
					#回傳結果
645
					return $result;	
582 liveuser 646
 
1 liveuser 647
					}#if end
648
 
649
				}#if end
650
 
667 liveuser 651
			#初始化儲存 server 資訊的變數,預設數值為 $result 自己
652
			$result["serverCache"]=&$result;
653
 
654
			#初始化方便識別 server 資訊的變數
655
			$serverCache=&$result["serverCache"];
656
 
705 liveuser 657
			#初始化 server site cache
658
			$serverCache["serverSide"]=array();
659
 
851 liveuser 660
			#初始化 儲存 透過 proc 執行的子程序 
661
			$serverCache["serverSide"]["procs"]=array();
662
 
705 liveuser 663
			#初始化 client site cache
664
			$serverCache["clientSide"]=array();
665
 
666
			#初始化方便識別 client site cache 資訊的變數
667
			$clientCache=&$serverCache["clientSide"];
668
 
1 liveuser 669
			#將建立的 listen sock 放到 $master 陣列
670
			$master[] = $socket;
671
 
672
			#永久監聽, 不 timeout
673
			while(true){
674
 
669 liveuser 675
				#debug
690 liveuser 676
				#var_dump(__LINE__,gmdate("Y-m-d H:i:s",time()));
669 liveuser 677
 
1 liveuser 678
				#設置給 stream_select 監控的sock變數
679
				$read = $write = $except = $master;
680
 
681
				#等待5秒,看有沒有連線進來讀寫資料
682
				$mod_fd = stream_select($read, $write, $except, 5);
683
 
851 liveuser 684
				#如果執行失敗
1 liveuser 685
				if($mod_fd===FALSE){
686
 
851 liveuser 687
					#提示錯誤訊息
852 liveuser 688
					echo "Stream_select failed at ".gmdate("Y-m-d H:i:s",time());
669 liveuser 689
 
851 liveuser 690
					#結束監聽
691
					exit(1);
1 liveuser 692
 
693
					}#if end
386 liveuser 694
 
695
				#如果沒有訊息,代表閒置時可以做的事情
696
				else if($mod_fd===0){
1 liveuser 697
 
669 liveuser 698
					#提示idle
699
					echo ".";
700
 
851 liveuser 701
					#清除 session timeout 的連線 - start
702
 
852 liveuser 703
					#初始化要給 server 的回應
704
					$res=array();
705
 
386 liveuser 706
					#初始化計數移除幾個用戶
851 liveuser 707
					$res["delIdleConCount"]=0;
1 liveuser 708
 
386 liveuser 709
					#針對每個 $client
710
					foreach($client as $index=>$uncheckClient){
1 liveuser 711
 
386 liveuser 712
						#如果上次的要求時間為300秒前.
713
						if(time()-(int)$uncheckClient["last_req_time"]>$conf["sessionTimeout"]){
714
 
715
							#移除該用戶變數
716
							unset($client["$index"]);
717
 
718
							#計數移除了幾個用戶
851 liveuser 719
							$res["delIdleConCount"]++;
386 liveuser 720
 
721
							}#if end
1 liveuser 722
 
386 liveuser 723
						}#foreach end
1 liveuser 724
 
386 liveuser 725
					#設置執行正常
726
					$res["status"]="true";
1 liveuser 727
 
852 liveuser 728
					#如果有移除閒置的連線
729
					if($res["delIdleConCount"]>0){
387 liveuser 730
 
852 liveuser 731
						#印出給 server 的訊息
732
						echo PHP_EOL."response:".PHP_EOL.print_r($res,true);
733
 
734
						}#if end
735
 
851 liveuser 736
					#清除 session timeout 的連線 - end
737
 
738
					#清除 太久沒有 被查詢的 proc(子程序) - start
739
 
852 liveuser 740
					#初始化要給 server 的回應
741
					$res=array();
742
 
851 liveuser 743
					#初始化計數移除幾個沒被關注的子程序
744
					$res["delIdleProcCount"]=0;
745
 
854 liveuser 746
					#針對每個 子程序
851 liveuser 747
					foreach($serverCache["serverSide"]["procs"] as $procIndex=>$procInfo){
748
 
854 liveuser 749
						#debug
750
						#var_dump(__FUNCTION__,__LINE__,$procInfo);
751
 
851 liveuser 752
						#如果上次的要求時間為300秒前.
753
						if(time()-(int)$procInfo["latestAccessTime"]>$conf["sessionTimeout"]){
754
 
755
							#若運行中
854 liveuser 756
							if($procInfo["content"][0]["statusCode"]==="?"){
851 liveuser 757
 
758
								#更新資訊
759
								#函式說明:
760
								#更新透過proc執行的多程序資訊.
761
								#回傳結果:
762
								#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
763
								#$reuslt["error"],執行不正常結束的錯訊息陣列.
764
								#$result["function"],當前執行的函式名稱.
765
								#$result["argu"],使用的參數.
766
								#$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"代表程序的資訊.
767
								#必填參數:
768
								#$conf["procs"],陣列,運行self::proc後回傳的content.
769
								$conf["threads::proc_update"]["procs"]=$procInfo["content"];
770
								#可省略參數:
771
								#無.
772
								#參考資料:
773
								#無.
774
								#備註:
775
								#無.
776
								$proc_update=threads::proc_update($conf["threads::proc_update"]);
777
								unset($conf["threads::proc_update"]);
778
 
779
								#若執行不正常
780
								if($proc_update["status"]==="false"){
781
 
782
									#設置執行失敗
783
									$result["status"]="false";
784
 
785
									#設置錯誤訊息
786
									$result["error"]=$proc_update;
787
 
788
									#印出錯誤訊息
789
									echo print_r($result,true);
790
 
791
									#回傳結果
792
									return $result;	
793
 
794
									}#if end
795
 
796
								#更新程序狀態
854 liveuser 797
								$procInfo["content"]=$proc_update["content"][0];
851 liveuser 798
 
799
								#更新會後存取時間
800
 
801
								#若已經執行結束
802
								if($procInfo["content"]["statusCode"]!=="?"){
803
 
804
									#換下一個
805
									continue;
806
 
807
									}#if end
808
 
809
								#執行到這代表一樣再運行中
810
 
811
								#終止程序
812
								proc_close($procInfo["content"]["process"]);
813
 
814
								#移除該用戶變數
815
								unset($serverCache["serverSide"]["procs"][$procIndex]);	
816
 
817
								#換下一個
818
								continue;
819
 
820
								}#if end
821
 
822
							#反之為已運行結束
823
 
824
							#移除該用戶變數
825
							unset($serverCache["serverSide"]["procs"][$procIndex]);
826
 
827
							#計數移除幾個沒被關注的子程序
828
							$res["delIdleProcCount"]++;
829
 
830
							}#if end
831
 
832
						}#foreach end
833
 
834
					#設置執行正常
835
					$res["status"]="true";
836
 
852 liveuser 837
					#如果有移除沒被關注的子程序
838
					if($res["delIdleProcCount"]>0){
851 liveuser 839
 
852 liveuser 840
						#印出給 server 的訊息
841
						echo PHP_EOL."response:".PHP_EOL.print_r($res,true);
842
 
843
						}#if end
844
 
851 liveuser 845
					#清除 太久沒有 被查詢的 proc(子程序) - end
846
 
387 liveuser 847
					#如果有設置 idle 要執行的函式
848
					if(isset($conf["funcToRunWhenIdle"])){
849
 
851 liveuser 850
						#提示有idle要執行的函式
851
						echo "response:".PHP_EOL."There is funcToRunWhenIdle param set.".PHP_EOL;
852
 
387 liveuser 853
						#針對每個 funcToRunWhenIdle
667 liveuser 854
						foreach($conf["funcToRunWhenIdle"] as $index => $funcToRunWhenIdle){
805 liveuser 855
 
851 liveuser 856
							#提示正要執行的函式
857
							echo "response:".PHP_EOL."Executeing ".$funcToRunWhenIdle."...".PHP_EOL;
858
 
387 liveuser 859
							#初始化要給 funcToRunWhenIdle 函式的參數
860
							$parasmForFuncToRunWhenIdle=array();
861
 
862
							#取得所有用戶
863
							$parasmForFuncToRunWhenIdle["client"]=&$client;
864
 
565 liveuser 865
							#如果有設置 infoToFunction
866
							if(isset($conf["infoToFunction"])){
867
 
868
								#設置info
572 liveuser 869
								$parasmForFuncToRunWhenIdle["info"]=&$conf["infoToFunction"];
565 liveuser 870
 
871
								}#if end
667 liveuser 872
 
805 liveuser 873
							#debug
874
							#var_dump(__FILE__,__LINE__,$serverCache["serverSide"]);
875
 
667 liveuser 876
							#如果屬於該 $funcToRunWhenIdle 的 server side cache 不存在
877
							if(!isset($serverCache["serverSide"]["funcToRunWhenIdle"][$funcToRunWhenIdle])){
878
 
879
								#初始化為空陣列
880
								$serverCache["serverSide"]["funcToRunWhenIdle"][$funcToRunWhenIdle]=array();
881
 
882
								}#if end
883
 
669 liveuser 884
							#設置給予 $funcToRunWhenIdle 函式的 serverCache 參數
885
							$parasmForFuncToRunWhenIdle["serverCache"]=&$serverCache;
667 liveuser 886
 
669 liveuser 887
							#儲存 $funcToRunWhenIdle 函式 的運行結束的時間點到 server side 的 cache
668 liveuser 888
							$serverCache["serverSide"]["funcToRunWhenIdle"][$funcToRunWhenIdle]["lastRunTime"]=time::unix()["content"];
667 liveuser 889
 
890
							#如果有要指定給 $funcToRunWhenIdle 的參數
891
							if(isset($conf["paramsForFuncToRunWhenIdle"][$index])){
892
 
893
								#針對每個 要給予 funcToRunWhenIdle 的參數
894
								foreach($conf["paramsForFuncToRunWhenIdle"][$index] as $arguKeyForFuncToRunWhenIdle => $arguValueForFuncToRunWhenIdle){
895
 
896
									#設置給予 funcToRunWhenIdle 的參數
897
									$parasmForFuncToRunWhenIdle[$arguKeyForFuncToRunWhenIdle]=$arguValueForFuncToRunWhenIdle;
898
 
805 liveuser 899
									#debug
900
									#var_dump(__LINE__,$parasmForFuncToRunWhenIdle);
901
 
667 liveuser 902
									}#foreach end
903
 
904
								}#if end
905
 
669 liveuser 906
							/* debug
667 liveuser 907
 
669 liveuser 908
							#函式說明:
909
							#撰寫log
910
							#回傳結果:
911
							#$result["status"],狀態,"true"或"false".
912
							#$result["error"],錯誤訊息陣列.
913
							#$result["function"],當前函式的名稱.
914
							#$result["argu"],使用的參數.
915
							#$result["content"],要寫入log的內容字串.
916
							#必填參數:
917
							#$conf["path"],字串,log檔案的路徑與名稱.
918
							$conf["logs::record"]["path"]=$conf["sock"].".log";
919
							#$conf["content"],any,要寫的內容,若內容不為字串則會用var_dump的格式寫入.
920
							$conf["logs::record"]["content"]=$parasmForFuncToRunWhenIdle;
921
							#$conf["fileArgu"],字串,php變數__FILE__的內容,亦即該檔案在檔案系統的絕對路徑
922
							$conf["logs::record"]["fileArgu"]=__FILE__;
923
							#可省略參數:
924
							#$conf["rewrite"],預設為"false",接續寫入;反之"true"代表重新寫入.
925
							#$conf["rewrite"]="false";
926
							#$conf["returnOnly"],預設為"false",會寫入到log檔案.若為"true"則不會寫入log.
927
							#$conf["returnOnly"]="true";
928
							#參考資料:
929
							#無.
930
							#備註:
931
							#無.
932
							$record=logs::record($conf["logs::record"]);
933
							unset($conf["logs::record"]);
934
 
935
							#如果執行失敗
936
							if($record["status"]==="false"){
937
 
938
								#設置執行錯誤識別
939
								$result["status"]="false";
940
 
941
								#設置執行錯誤
942
								$result["error"]=$record;
943
 
944
								#回傳結果
945
								return $result;
946
 
947
								}#if end
948
 
949
							*/
950
 
805 liveuser 951
							#debug
952
							#var_dump(__LINE__,$parasmForFuncToRunWhenIdle);
953
 
954
							#debug
955
							#var_dump(__LINE__,"\$call_user_func=".$funcToRunWhenIdle."(\$parasmForFuncToRunWhenIdle);");
956
 
705 liveuser 957
							#呼叫 $funcToRunWhenIdle 函式,參數用 $client[$request->id], 取得執行後的回應.
667 liveuser 958
							eval("\$call_user_func=".$funcToRunWhenIdle."(\$parasmForFuncToRunWhenIdle);");
669 liveuser 959
 
960
							/* debug
667 liveuser 961
 
669 liveuser 962
							#函式說明:
963
							#撰寫log
964
							#回傳結果:
965
							#$result["status"],狀態,"true"或"false".
966
							#$result["error"],錯誤訊息陣列.
967
							#$result["function"],當前函式的名稱.
968
							#$result["argu"],使用的參數.
969
							#$result["content"],要寫入log的內容字串.
970
							#必填參數:
971
							#$conf["path"],字串,log檔案的路徑與名稱.
972
							$conf["logs::record"]["path"]=$conf["sock"].".log";
973
							#$conf["content"],any,要寫的內容,若內容不為字串則會用var_dump的格式寫入.
974
							$conf["logs::record"]["content"]=$call_user_func;
975
							#$conf["fileArgu"],字串,php變數__FILE__的內容,亦即該檔案在檔案系統的絕對路徑
976
							$conf["logs::record"]["fileArgu"]=__FILE__;
977
							#可省略參數:
978
							#$conf["rewrite"],預設為"false",接續寫入;反之"true"代表重新寫入.
979
							#$conf["rewrite"]="false";
980
							#$conf["returnOnly"],預設為"false",會寫入到log檔案.若為"true"則不會寫入log.
981
							#$conf["returnOnly"]="true";
982
							#參考資料:
983
							#無.
984
							#備註:
985
							#無.
986
							$record=logs::record($conf["logs::record"]);
987
							unset($conf["logs::record"]);
851 liveuser 988
 
669 liveuser 989
							#如果執行失敗
990
							if($record["status"]==="false"){
991
 
992
								#設置執行錯誤識別
993
								$result["status"]="false";
994
 
995
								#設置執行錯誤
996
								$result["error"]=$record;
997
 
998
								#回傳結果
999
								return $result;
1000
 
1001
								}#if end
1002
 
1003
							*/	
1004
 
705 liveuser 1005
							#儲存 $funcToRunWhenIdle 函式 的運行結果資訊到 server side 的 cache
669 liveuser 1006
							$serverCache["serverSide"]["funcToRunWhenIdle"][$funcToRunWhenIdle]["result"]=&$call_user_func;
387 liveuser 1007
 
705 liveuser 1008
							#儲存 $funcToRunWhenIdle 函式 的運行結束的時間點到 server side 的 cache
667 liveuser 1009
							$serverCache["serverSide"]["funcToRunWhenIdle"][$funcToRunWhenIdle]["lastEndTime"]=time::unix()["content"];
1010
 
805 liveuser 1011
							#debug
1012
							#var_dump(__FILE__,__LINE__,$serverCache);
1013
 
669 liveuser 1014
							#如果 運行 $funcToRunWhenIdle 後回傳的內容含有 key 為 status 的元素
1015
							if(isset($call_user_func["status"])){
1016
 
1017
								#如果其數值為 "false"
1018
								if($call_user_func["status"]==="false"){
1019
 
1020
									#印出訊息,結束執行
707 liveuser 1021
									var_dump(__FILE__,__LINE__,$call_user_func);exit;
669 liveuser 1022
 
1023
									}#if end
1024
 
1025
								}#if end
1026
 
1027
							#如果有訊息要提示
1028
							if(isset($call_user_func["content"])){
1029
 
1030
								#印出提示訊息
1031
								var_dump($call_user_func["content"]);
1032
 
1033
								}#if end
1034
 
667 liveuser 1035
							#如果 運行 $funcToRunWhenIdle 後回傳的內容含有 key 為 cache 的元素
1036
							if(isset($call_user_func["cache"])){
1037
 
805 liveuser 1038
								#debug
1039
								#var_dump(__FILE__,__LINE__,$call_user_func["cache"]);
1040
 
667 liveuser 1041
								#儲存到 server side 的 cache
669 liveuser 1042
								$serverCache["serverSide"]["funcToRunWhenIdle"][$funcToRunWhenIdle]["cache"]=&$call_user_func["cache"];
667 liveuser 1043
 
669 liveuser 1044
								/*
1045
								#debug
1046
								#函式說明:
1047
								#撰寫log
1048
								#回傳結果:
1049
								#$result["status"],狀態,"true"或"false".
1050
								#$result["error"],錯誤訊息陣列.
1051
								#$result["function"],當前函式的名稱.
1052
								#$result["argu"],使用的參數.
1053
								#$result["content"],要寫入log的內容字串.
1054
								#必填參數:
1055
								#$conf["path"],字串,log檔案的路徑與名稱.
1056
								$conf["logs::record"]["path"]=$conf["sock"].".log";
1057
								#$conf["content"],any,要寫的內容,若內容不為字串則會用var_dump的格式寫入.
1058
								$conf["logs::record"]["content"]=$call_user_func;
1059
								#$conf["fileArgu"],字串,php變數__FILE__的內容,亦即該檔案在檔案系統的絕對路徑
1060
								$conf["logs::record"]["fileArgu"]=__FILE__;
1061
								#可省略參數:
1062
								#$conf["rewrite"],預設為"false",接續寫入;反之"true"代表重新寫入.
1063
								#$conf["rewrite"]="false";
1064
								#$conf["returnOnly"],預設為"false",會寫入到log檔案.若為"true"則不會寫入log.
1065
								#$conf["returnOnly"]="true";
1066
								#參考資料:
1067
								#無.
1068
								#備註:
1069
								#無.
1070
								$record=logs::record($conf["logs::record"]);
1071
								unset($conf["logs::record"]);
1072
 
1073
								#如果執行失敗
1074
								if($record["status"]==="false"){
1075
 
1076
									#設置執行錯誤識別
1077
									$result["status"]="false";
1078
 
1079
									#設置執行錯誤
1080
									$result["error"]=$record;
1081
 
1082
									#回傳結果
1083
									return $result;
1084
 
1085
									}#if end
1086
								*/
1087
 
667 liveuser 1088
								}#if end
669 liveuser 1089
 
668 liveuser 1090
							#如果回傳結果含有 exit 元素
1091
							if(isset($call_user_func["exit"])){
688 liveuser 1092
 
1093
								/*
1094
								#debug
1095
								#函式說明:
1096
								#撰寫log
1097
								#回傳結果:
1098
								#$result["status"],狀態,"true"或"false".
1099
								#$result["error"],錯誤訊息陣列.
1100
								#$result["function"],當前函式的名稱.
1101
								#$result["argu"],使用的參數.
1102
								#$result["content"],要寫入log的內容字串.
1103
								#必填參數:
1104
								#$conf["path"],字串,log檔案的路徑與名稱.
1105
								$conf["logs::record"]["path"]=$conf["sock"].".log";
1106
								#$conf["content"],any,要寫的內容,若內容不為字串則會用var_dump的格式寫入.
1107
								$conf["logs::record"]["content"]=$call_user_func["exit"];
1108
								#$conf["fileArgu"],字串,php變數__FILE__的內容,亦即該檔案在檔案系統的絕對路徑
1109
								$conf["logs::record"]["fileArgu"]=__FILE__;
1110
								#可省略參數:
1111
								#$conf["rewrite"],預設為"false",接續寫入;反之"true"代表重新寫入.
1112
								#$conf["rewrite"]="false";
1113
								#$conf["returnOnly"],預設為"false",會寫入到log檔案.若為"true"則不會寫入log.
1114
								#$conf["returnOnly"]="true";
1115
								#參考資料:
1116
								#無.
1117
								#備註:
1118
								#無.
1119
								$record=logs::record($conf["logs::record"]);
1120
								unset($conf["logs::record"]);
1121
 
1122
								#如果執行失敗
1123
								if($record["status"]==="false"){
669 liveuser 1124
 
688 liveuser 1125
									#設置執行錯誤識別
1126
									$result["status"]="false";
1127
 
1128
									#設置執行錯誤
1129
									$result["error"]=$record;
1130
 
1131
									#回傳結果
1132
									return $result;
1133
 
1134
									}#if end
1135
								*/
1136
 
668 liveuser 1137
								#如果是要結束daemon執行
1138
								if($call_user_func["exit"]==="true"){
1139
 
1140
									#設置daemon結束的原因
1141
									$call_user_func["exit"]="exit by funcToRunWhenIdle(".$funcToRunWhenIdle.")";
1142
 
669 liveuser 1143
									#設置執行正常
1144
									$result["status"]="true";
1145
 
668 liveuser 1146
									#結束執行
1147
									return $result;
1148
 
1149
									}#if end
1150
 
1151
								}#if end
667 liveuser 1152
 
851 liveuser 1153
							#提示正要執行的函式
1154
							echo "response:".PHP_EOL.$funcToRunWhenIdle." Executed.".PHP_EOL;
1155
 
387 liveuser 1156
							}#foreach end
1157
 
1158
						}#if end
1159
 
386 liveuser 1160
					#等待下個要求
1161
					continue;
1162
 
1163
					}#if end
1164
 
1165
				#有偵測到讀寫的動作
1166
				else{
1167
 
1168
					#針對每個 sock 陣列
1169
					foreach($read as $readStream){
1 liveuser 1170
 
386 liveuser 1171
						#如果元素是 listen 的 socket
1172
						if($readStream === $socket){
1 liveuser 1173
 
386 liveuser 1174
							#當等待別人連線時,若有人連線進來.
1175
							$conn = stream_socket_accept($socket);
1 liveuser 1176
 
717 liveuser 1177
							#取得 meta data
1178
							#$stream_meta_data=stream_get_meta_data($conn);
1179
 
1180
							#debug
1181
							#var_dump(__LINE__,$stream_meta_data);
1182
 
386 liveuser 1183
							#印出有連線進來的訊息
1184
							echo "received a connection".PHP_EOL;
1 liveuser 1185
 
386 liveuser 1186
							#初始化取得的內容
1187
							$request="";
1 liveuser 1188
 
386 liveuser 1189
							#初始化要回應的內容
1190
							$res=array();
1 liveuser 1191
 
386 liveuser 1192
							#取得 request 的時間
1193
							$last_req_time=time();
1 liveuser 1194
 
386 liveuser 1195
							#當有要求時
1196
							while(!feof($conn)){
1 liveuser 1197
 
386 liveuser 1198
								#讀取要求
1199
								$tmp=fgets($conn, 1024);
1200
 
1201
								#如果讀到 PHP_EOL
1202
								if($tmp===PHP_EOL){
1 liveuser 1203
 
386 liveuser 1204
									#結束讀取要求
1205
									break;	
1 liveuser 1206
 
1207
									}#if end
386 liveuser 1208
 
1209
								#串接回應
1210
								$request=$request.$tmp;
1 liveuser 1211
 
386 liveuser 1212
								}#while end	
1213
 
1214
							#印出有連線進來的訊息
1215
							echo "received content:".PHP_EOL.$request.PHP_EOL;
1 liveuser 1216
 
386 liveuser 1217
							#parse request json
1218
							$request=json_decode($request);
1 liveuser 1219
 
386 liveuser 1220
							#如果 parse json 失敗
1221
							if($request===false){
1222
 
1223
								#設置錯誤訊息
1224
								$res["error"]="要求格式必須為json";
1225
 
1226
								#設置執行失敗
1227
								$res["status"]="false";
1228
 
1229
								#印出回的訊息
1230
								echo "res:".print_r($res,true);
1231
 
1232
								#寫入回應的內容
1233
								fwrite($conn,json_encode($res).PHP_EOL);
1 liveuser 1234
 
386 liveuser 1235
								#結束回應
1236
								fwrite($conn,PHP_EOL.PHP_EOL);
1 liveuser 1237
 
386 liveuser 1238
								#關閉socket連線,將回應輸出.
1239
								fclose($conn);
1240
 
1241
								#等待下個要求
1242
								continue;
1243
 
1244
								}#if end
1245
 
1246
							#若無ID資訊
1247
							if(!isset($request->id)){
668 liveuser 1248
 
386 liveuser 1249
								#無窮迴圈
1250
								while(true){
1251
 
1252
									#set client id 設置要回應的訊息
1253
									#函式說明:
1254
									#呼叫shell執行系統命令,並取得回傳的內容.
1255
									#回傳結果:
1256
									#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
1257
									#$result["error"],錯誤訊息陣列.
1258
									#$result["function"],當前執行的函數名稱.
1259
									#$result["argu"],使用的參數.
1260
									#$result["cmd"],執行的指令內容.
1261
									#$result["fullCmd"],如果參數 $conf["inBackGround"] 為 "true" 則會回傳該值.
1262
									#$result["output"],爲執行完二元碼後的輸出陣列,若 $conf["inBackGround"] 為 "true",則為當下的輸出.
1263
									#$result["tmpFileOutput"],儲存輸出的暫存檔案名稱,若 $conf["inBackGround"] 為 "true" 則會回傳該值.
1264
									#$result["running"],是否還在執行.
1265
									#$result["pid"],pid.
1266
									#$result["statusCode"],執行結束後的代碼.
1267
									#必填參數:
1268
									#$conf["command"],字串,要執行的指令.
1269
									$conf["external::callShell"]["command"]="uuid";
1270
									#$conf["fileArgu"],字串,變數__FILE__的內容.
1271
									$conf["external::callShell"]["fileArgu"]=__FILE__;
1272
									#可省略參數:
1273
									#$conf["argu"],陣列字串,指令搭配的參數,預設為空陣列.
1274
									#$conf["argu"]=array("");
1275
									#$conf["arguIsAddr"],陣列字串,指令搭配的哪些參數為路徑,為路徑的參數會進行轉換以便符合呼叫當前函數的位置,預設不指定,若有3個參數,其中第3個參數為路徑,則表示為array("false","false","true").
1276
									#$conf["arguIsAddr"]=array();
1277
									#$conf["plainArgu"],字串陣列,哪幾個參數不要加上"",若為"true"則代表不用包;反之"false"則代表要包.
1278
									#$conf["plainArgu"]=array();
1279
									#$conf["useApostrophe"],字串陣列,如果有需要包住,則用「'」,而非「"」處理.前者為"true";後者為"false".
1280
									#$conf["useApostrophe"]=array();
1281
									#$conf["pre"],陣列,要在本指令前執行的每個指令與參數.
1282
									#$conf["pre"][$i]["cmd"],字串,要在本指令前執行的第$i+1個指令.
1283
									#$conf["pre"][$i]["param"],陣列字串,要在本指令前執行的第$i+1個指令的參數.
1284
									#$conf["enablePrintDescription"],字串,是否要印出$conf["printDescription"]的內容,"true"代表要,"false"代表不要,預設為"false".
1285
									#$conf["enablePrintDescription"]="true";
1286
									#$conf["printDescription"],字串,執行該外部程式前要印出來的的文字,預設為$conf["command"]的內容加上使用的$conf["argu"]參數.
1287
									#$conf["printDescription"]="";
1288
									#$conf["escapeshellarg"],字串,是否要啟用過濾參數,用了比較安全,但可能會出錯,"true"為啟用,"false"為不啟用,預設為"false".如果參數為"< 、<< 、> 、>> 、| 、2>&1"之一則不會過濾.
1289
									$conf["external::callShell"]["escapeshellarg"]="true";
1290
									#$conf["thereIsShellVar"],陣列字串,指令搭配的參數"argu",若含有「\'」,則取代為「"」.每個argu參數都要有對應的元素."true"代表要置換.
1291
									#$conf["thereIsShellVar"]=array();
1292
									#$conf["username"],字串,要用什麼使用者來執行,預設為執行php的使用者,該參數不適用於apache環境.
1293
									#$conf["username"]="";
1294
									#$conf["password"],字串,root的使用者密碼,預設不使用密碼,該參數不適用於apache環境.
1295
									#$conf["password"]="";
1296
									#$conf["useScript"],字串,是否要啟用Linux的script指令來記錄輸出,"true"代表要,Fedora的selinux會擋住該操作;"false"代表不要,預設為"false".
1297
									#$conf["useScript"]="";
1298
									#$conf["logFilePath"],字串,當 $conf["useScript"] 為 "true" 時,輸出的內容要暫存到哪裡,預設為 "/tmp/.qbpwcf_tmp/external/callShell/".
1299
									#$conf["logFilePath"]=".qbpwcf_tmp/external/callShell/";
1300
									#$conf["inBackGround"],字串,是否要在背景執行,且不會等待程式執行結束再執行下一個指令,"true"代表是,"false"代表不要,預設為"false",如果$conf["command"]有用「;」區隔的多個指令將會出錯.
1301
									#$conf["inBackGround"]="";
1302
									#$conf["getErr"],字串,"true"代表將錯誤輸出變成標準輸出,反之"false"為不變動.
1303
									#$conf["getErr"]="false";
1304
									#$conf["doNotRun"],字串,"true"代表不執行指令,預設為"false"會執行指令.
1305
									#$conf["doNotRun"]="false";
1306
									#參考資料:
1307
									#exec=>http://php.net/manual/en/function.exec.php
1308
									#escapeshellcmd=>http://php.net/manual/en/function.escapeshellcmd.php
1309
									#escapeshellarg=>http://php.net/manual/en/function.escapeshellarg.php
1310
									#備註:
1311
									#不是所有指令都能用apache的身份執行,目前已知java,javac指令無法執行,使用root身份可能會被selinux阻擋.
1312
									#若使用的 command、argu 參數,含有 ~ 則會被視為字串,若有需要其於 shell 中代表的家目錄位置,可用 fileAccess::tildeToPath 來進行轉換.
1313
									$callShell=external::callShell($conf["external::callShell"]);
1314
									unset($conf["external::callShell"]);
1315
 
1316
									#如果執行失敗
1317
									if($callShell["status"]==="false"){
1318
 
1319
										#設置執行失敗
1320
										$result["status"]="false";
1321
 
1322
										#設置錯誤訊息
1323
										$result["error"]=$callShell;
669 liveuser 1324
 
386 liveuser 1325
										#回傳結果
1326
										return $result;	
1327
 
1328
										}#if end
1329
 
1330
									#如果沒有預期的 uuid 回應
1331
									if(!isset($callShell["output"][0])){
1332
 
1333
										#設置執行失敗
1334
										$result["status"]="false";
1335
 
1336
										#設置錯誤訊息
1337
										$result["error"][]="get uuid failed!";
1338
 
1339
										#設置錯誤訊息
1340
										$result["error"][]=$callShell;
669 liveuser 1341
 
386 liveuser 1342
										#回傳結果
1343
										return $result;	
1344
 
1345
										}#if end
1346
 
1347
									#檢查 client id 是否已經存在
1348
									if(isset($client[$callShell["output"][0]])){
1349
 
1350
										#休息一微秒
1351
										usleep(1);
1352
 
1353
										#再次建立id試試
1354
										continue;
1355
 
1356
										}#if end
1357
 
1358
									#設置回應的id
668 liveuser 1359
									$res["id"]=$callShell["output"][0];
386 liveuser 1360
 
1361
									#建立id完畢
1362
									break;
1363
 
668 liveuser 1364
									}#while end
1365
 
386 liveuser 1366
								#儲存使用者id與最後一次來request的時間
1367
								$client[$res["id"]]=array("last_req_time"=>$last_req_time);
1368
 
1369
								#印出用戶端列表
1370
								echo "clients:".print_r($client,true);
1371
 
1372
								#設置執行正常
1373
								$res["status"]="true";
1374
 
1375
								#印出回的訊息
1376
								echo "response:".PHP_EOL.print_r($res,true);
1377
 
1378
								#寫入回應的內容
1379
								fwrite($conn,json_encode($res).PHP_EOL);
1 liveuser 1380
 
386 liveuser 1381
								#結束回應
1382
								fwrite($conn,PHP_EOL.PHP_EOL);
1383
 
1384
								#關閉socket連線,將回應輸出.
1385
								fclose($conn);
1386
 
1387
								#等待下個要求
1388
								continue;
1389
 
1390
								}#if end	
1 liveuser 1391
 
386 liveuser 1392
							#若ID資訊不存在
1393
							if(!isset($client[$request->id])){
1 liveuser 1394
 
386 liveuser 1395
								#設置執行失敗
1396
								$res["status"]="false";
1 liveuser 1397
 
386 liveuser 1398
								#設置ID不存在的訊息
1399
								$res["error"]="ID:".$request->id." 不存在,請再要一次ID.";
1 liveuser 1400
 
386 liveuser 1401
								#印出回的訊息
1402
								echo "response:".PHP_EOL.print_r($res,true);
1403
 
1404
								#寫入回應的內容
1405
								fwrite($conn,json_encode($res).PHP_EOL);
1 liveuser 1406
 
386 liveuser 1407
								#結束回應
1408
								fwrite($conn,PHP_EOL.PHP_EOL);
1 liveuser 1409
 
386 liveuser 1410
								#關閉socket連線,將回應輸出.
1411
								fclose($conn);
1 liveuser 1412
 
386 liveuser 1413
								#等待下個要求
1414
								continue;
1 liveuser 1415
 
1416
								}#if end
1417
 
852 liveuser 1418
							#如果有客製化訊息
1419
							if(isset($request->custom)){
1420
 
1421
								#取代之
1422
								$request=$request->custom;
1423
 
1424
								}#if end
1425
 
851 liveuser 1426
							#若有要執行的指令 cmd,且非客製化.
1427
							if( isset($request->cmd) && !isset($request->custom) ){
1 liveuser 1428
 
669 liveuser 1429
								#如果是要結束連線
1430
								if($request->cmd==="quit"){
1431
 
1432
									#設置執行正常
1433
									$res["status"]="true";
1434
 
1435
									#設置訊息
1436
									$res["content"]="將關閉與您的連線";
1437
 
1438
									#寫入回應的內容
1439
									fwrite($conn,json_encode($res).PHP_EOL);
1440
 
1441
									#結束回應
1442
									fwrite($conn,PHP_EOL.PHP_EOL);
1443
 
1444
									#關閉socket連線,將回應輸出.
1445
									fclose($conn);
1446
 
1447
									#移除該用戶變數
1448
									unset($client[$index]);
1449
 
1450
									#計數移除了幾個用戶
1451
									$res["delCount"]++;
1452
 
1453
									#設置執行正常
1454
									$res["status"]="true";
1455
 
1456
									#印出回的訊息
1457
									echo "response:".PHP_EOL.print_r($res,true);
1458
 
1459
									#等待下個要求
1460
									continue;
1461
 
1462
									}#if end
1463
 
1464
								#如果是要結束server
1465
								if($request->cmd===$shutdownStr){
1466
 
1467
									#設置執行正常
1468
									$res["status"]="true";
1469
 
1470
									#設置訊息
1471
									$res["content"]="本服務將結束";
1472
 
1473
									#寫入回應的內容
1474
									fwrite($conn,json_encode($res).PHP_EOL);
1475
 
1476
									#結束回應
1477
									fwrite($conn,PHP_EOL.PHP_EOL);
1478
 
1479
									#關閉socket連線,將回應輸出.
1480
									fclose($conn);
1481
 
1482
									#設置執行正常
1483
									$result["status"]="true";
1484
 
1485
									#結束本程式
1486
									return $result;
1487
 
1488
									}#if end
1489
 
386 liveuser 1490
								#涵式說明:
1491
								#呼叫shell執行系統命令,並取得回傳的內容.
1492
								#回傳的結果:
1493
								#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
1494
								#$result["error"],錯誤訊息陣列.
1495
								#$result["function"],當前執行的函數名稱.
1496
								#$result["argu"],使用的參數.
1497
								#$result["cmd"],執行的指令內容.
1498
								#$result["fullCmd"],如果參數 $conf["inBackGround"] 為 "true" 則會回傳該值.
1499
								#$result["output"],爲執行完二元碼後的輸出陣列,若 $conf["inBackGround"] 為 "true",則為當下的輸出.
1500
								#$result["tmpFileOutput"],儲存輸出的暫村檔案名稱,若 $conf["inBackGround"] 為 "true" 則會回傳該值.
1501
								#$result["running"],是否還在執行.
1502
								#$result["pid"],pid
1503
								#必填的參數
1504
								#$conf["command"],字串,要執行的指令與.
1505
								$conf["external::callShell"]["command"]=$request->cmd;
1506
								#$conf["fileArgu"],字串,變數__FILE__的內容.
1507
								$conf["external::callShell"]["fileArgu"]=$conf["fileArgu"];		
1508
								#可省略參數:
1509
 
443 liveuser 1510
								#如果有指定參數
386 liveuser 1511
								if(isset($request->param)){
443 liveuser 1512
 
386 liveuser 1513
									#$conf["argu"],陣列字串,指令搭配的參數,預設為空陣列.
1514
									$conf["external::callShell"]["argu"]=$request->param;
443 liveuser 1515
 
386 liveuser 1516
									}#if end
1517
 
1518
								#$conf["arguIsAddr"],陣列字串,指令搭配的哪些參數為路徑,為路徑的參數會進行轉換以便符合呼叫當前函數的位置,預設不指定,若有3個參數,其中第3個參數為路徑,則表示為array("false","false","true").
1519
								#$conf["arguIsAddr"]=array();	
1520
								#$conf["pre"],陣列,要在本指令前執行的每個指令與參數.
1521
								#$conf["pre"][$i]["cmd"],字串,要在本指令前執行的第$i+1個指令.
1522
								#$conf["pre"][$i]["param"],陣列字串,要在本指令前執行的第$i+1個指令的參數.
1523
								#$conf["enablePrintDescription"],字串,是否要印出$conf["printDescription"]的內容,"true"代表要,"false"代表不要,預設為"false".
1524
								#$conf["enablePrintDescription"]="true";
1525
								#$conf["printDescription"],字串,執行該外部程式前要印出來的的文字,預設為$conf["command"]的內容.
1526
								#$conf["printDescription"]="";
668 liveuser 1527
 
443 liveuser 1528
								#如果有參數
1529
								if(isset($request->param)){
1530
 
1531
									#如果有識別是否已經 escaped 參數
1532
									if(isset($request->escaped)){
1533
 
1534
										#設置預設要 escape
1535
										$needEscaped="true";
1536
 
1537
										#如果已經 ecaped
1538
										if($request->escaped){
1539
 
1540
											#設置不用 escape
1541
											$needEscaped="false";
1542
 
1543
											}#if end
1544
 
1545
										#$conf["escapeshellarg"],字串,是否要啟用過濾參數,用了比較安全,但可能會出錯,"true"為啟用,"false"為不啟用,預設為"false".
1546
										$conf["external::callShell"]["escapeshellarg"]=$needEscaped;
1547
 
1548
										}#if end
1549
 
1550
									}#if end
1551
 
386 liveuser 1552
								#如果有設置要用特定的使用者身份執行
1553
								if(isset($request->user) && isset($request->password)){
1554
 
1555
									#$conf["username"],字串,要用什麼使用者來執行,預設為執行php的使用者,該參數不適用於apache環境.
1556
									$conf["external::callShell"]["username"]=$request->user;
1557
 
1558
									#$conf["password"],字串,與$conf["username"]搭配的使用者密碼,預設不使用密碼,該參數不適用於apache環境.
1559
									$conf["external::callShell"]["password"]=$request->password;
1560
 
1561
									}#if end
1562
 
1563
								#$conf["useScript"],字串,是否要啟用Linux的script指令來記錄輸出,"true"代表要,Fedora的selinux會擋住該操作;"false"代表不要,預設為"false".
1564
								#$conf["useScript"]="";
1565
								#$conf["logFilePath"],字串,當 $conf["useScript"] 為 "true" 時,輸出的內容要暫存到哪裡,預設為 "/tmp/.qbpwcf_tmp/external/callShell/".
1566
								#$conf["logFilePath"]=".qbpwcf_tmp/external/callShell/";
1567
								#$conf["inBackGround"],字串,是否要在背景執行,且不會等待程式執行結束再執行下一個指令,"true"代表是,"false"代表不要,預設為"false",如果$conf["command"]有用「;」區隔的多個指令將會出錯.
1568
								#$conf["inBackGround"]="";
1569
								#備註:
1570
								#不是所有指令都能用apache的身份執行,目前已知java,javac指令無法執行,使用root身份可能會被selinux阻擋.
1571
								#參考資料:
1572
								#exec=>http://php.net/manual/en/function.exec.php
1573
								#escapeshellcmd=>http://php.net/manual/en/function.escapeshellcmd.php
1574
								#escapeshellarg=>http://php.net/manual/en/function.escapeshellarg.php
1575
								$callShell=external::callShell($conf["external::callShell"]);
1576
								unset($conf["external::callShell"]);
1577
 
1578
								#設置要回覆的內容
1579
								$res=$callShell;
668 liveuser 1580
 
386 liveuser 1581
								#印出回的訊息
668 liveuser 1582
								echo "response:".PHP_EOL.print_r($res,true);
1583
 
386 liveuser 1584
								#寫入回應的內容
1585
								fwrite($conn,json_encode($res).PHP_EOL);
668 liveuser 1586
 
386 liveuser 1587
								#結束回應
1588
								fwrite($conn,PHP_EOL.PHP_EOL);
1589
 
1590
								#關閉socket連線,將回應輸出.
668 liveuser 1591
								fclose($conn);
1592
 
386 liveuser 1593
								#更新使用者id與最後一次來request的時間
1594
								$client[$request->id]["last_req_time"]=$last_req_time;	
668 liveuser 1595
 
386 liveuser 1596
								#等待下個要求
1597
								continue;
668 liveuser 1598
 
386 liveuser 1599
								}#if end
1 liveuser 1600
 
669 liveuser 1601
							#設置接收到json字串資訊
717 liveuser 1602
							$client[$request->id]["request"]=(array)($request);
669 liveuser 1603
 
386 liveuser 1604
							#設置用戶端的socket
668 liveuser 1605
							$client[$request->id]["socket"]=$conn;
1 liveuser 1606
 
851 liveuser 1607
							#如果有要求在背景中執行指令的訊息
852 liveuser 1608
							if(isset($request->cmdInBg)){
851 liveuser 1609
 
854 liveuser 1610
								#debug
1611
								#var_dump(__FUNCTION__,__LINE__,$request);
1612
 
851 liveuser 1613
								#如果有參數
852 liveuser 1614
								if(isset($request->param)){
851 liveuser 1615
 
1616
									#函式說明:
1617
									#將一維陣列轉換為用特定符號間隔的字串,ex:array("1","2","3") to "a;b;c;".
1618
									#回傳的結果:
1619
									#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
1620
									#$result["function"],當前執行的function名稱
1621
									#$result["error"],錯誤訊息陣列.
1622
									#$result["content"],處理好的字串.
1623
									#$result["argu"],使用的參數.
1624
									#必填參數:
1625
									#$conf["inputArray"],字串陣列,要轉成字串的一維陣列.
852 liveuser 1626
									$conf["arrays::arrayToString"]["inputArray"]=$request->param;
851 liveuser 1627
									#可省略參數:
1628
									#$conf["spiltSymbol"],字串,用來區隔字串的符號,預設為;
1629
									$conf["arrays::arrayToString"]["spiltSymbol"]=" ";
1630
									#$conf["skipEnd"],字串,結尾是否不要加上符號,預設為"false",要加上符號,"true"代表不要加上符號。
1631
									$conf["arrays::arrayToString"]["skipEnd"]="true";
1632
									#$conf["spiltSymbolAtStart"],字串,是否要在開頭加上spiltSymbol,預設為"false",代表不要;反之為“true”.
1633
									$conf["arrays::arrayToString"]["spiltSymbolAtStart"]="true";
1634
									#參考資料:
1635
									#無.
1636
									#備註:
1637
									#無.
1638
									$arrayToString=arrays::arrayToString($conf["arrays::arrayToString"]);
1639
									unset($conf["arrays::arrayToString"]);
1640
 
1641
									#如果執行失敗
1642
									if($arrayToString["status"]==="false"){
1643
 
1644
										#設置執行失敗
1645
										$result["status"]="false";
1646
 
1647
										#設置錯誤訊息
1648
										$result["error"]=$arrayToString;
1649
 
1650
										#回傳結果
1651
										return $result;
1652
 
1653
										}#if end
1654
 
1655
									#串接參數
852 liveuser 1656
									$request->cmdInBg=$request->cmdInBg.$arrayToString["content"];
851 liveuser 1657
 
1658
									}#if end
1659
 
1660
								#函式說明:
1661
								#透過proc來多執行序運作.
1662
								#回傳結果:
1663
								#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
1664
								#$reuslt["error"],執行不正常結束的錯訊息陣列.
1665
								#$result["function"],當前執行的函式名稱.
1666
								#$result["argu"],使用的參數.
1667
								#$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"代表程序的資訊.
1668
								#必填參數:
1669
								#$conf["cmds"],字串陣列,每個元素代表要執行的指令與參數.
852 liveuser 1670
								$conf["threads::proc"]["cmds"]=array($request->cmdInBg);
851 liveuser 1671
								#可省略參數:
1672
								#$conf["wait"],字串,是否需要等待所有程序結束,預設為"true"要等待;反之為"false"不要等待.
1673
								$conf["threads::proc"]["wait"]="false";
1674
								#$conf["workingDir"],字串陣列,個別程式執行時的家目錄,預設不指定.
1675
								#$conf["workingDir"]=array("path");
1676
								#$conf["envs"],2維字串陣列,每個元素代表個別程式執行時的指定環境變數,key變數名稱;value為變數內容.預設為array("QBPWCF" => "Quick Build PHP Website Componment base on Fedora Linux");
1677
								#$conf["envs"]=array(array("key"=>"value"));
1678
								#$conf["executeBy"],字串陣列,每個元素代表個別指令要用什麼程式執行,預設為"bash".
1679
								#$conf["executeBy"]=array("bash");
1680
								#參考資料:
1681
								#https://www.php.net/manual/en/function.proc-open.php
1682
								#https://www.php.net/manual/en/function.proc-get-status.php
1683
								#備註:
1684
								#若需要取得當下的執行狀況,請使用 self::proc_update 來更新.
1685
								$proc=threads::proc($conf["threads::proc"]);
1686
								unset($conf["threads::proc"]);
1687
 
1688
								#如果執行失敗
1689
								if($proc["status"]==="false"){
1690
 
1691
									#設置執行失敗
1692
									$result["status"]="false";
1693
 
1694
									#設置錯誤訊息
1695
									$result["error"]=$proc;
1696
 
1697
									#回傳結果
1698
									return $result;
1699
 
1700
									}#if end
1701
 
1702
								#函式說明:
1703
								#使用 linux 的 uuid 指令來產生 uuid 字串
1704
								#回傳結果:
1705
								#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
1706
								#$result["error"],錯誤訊息.
1707
								#$result["function"],當前執行的函式名稱.
1708
								#$result["content"],uuid.
1709
								#必填參數:
1710
								#無.
1711
								#可省略參數:
1712
								#無.
1713
								#參考資料:
1714
								#無.
1715
								#備註:
1716
								#無.
1717
								$uuid=cmd::uuid();
1718
 
1719
								#如果執行失敗
1720
								if($uuid["status"]==="false"){
1721
 
1722
									#設置執行失敗
1723
									$result["status"]="false";
1724
 
1725
									#設置錯誤訊息
1726
									$result["error"]=$uuid;
1727
 
1728
									#回傳結果
1729
									return $result;
1730
 
1731
									}#if end
1732
 
1733
								#取得 uuid
1734
								$uuid=$uuid["content"];
1735
 
1736
								#儲存到 server side 的 procs
1737
								$result["serverCache"]["serverSide"]["procs"][$uuid]=$proc;
1738
 
1739
								#設置最後的檢查時間為當下
852 liveuser 1740
								$result["serverCache"]["serverSide"]["procs"][$uuid]["latestAccessTime"]=time();
851 liveuser 1741
 
1742
								#設置要回覆的內容
1743
								$res=array("status"=>"true","content"=>$uuid);
1744
 
1745
								#印出回的訊息
1746
								echo "response:".PHP_EOL.print_r($res,true);
1747
 
1748
								#寫入回應的內容
1749
								fwrite($conn,json_encode($res).PHP_EOL);
1750
 
1751
								#結束回應
1752
								fwrite($conn,PHP_EOL.PHP_EOL);
1753
 
1754
								#關閉socket連線,將回應輸出.
1755
								fclose($conn);
1756
 
1757
								#更新使用者id與最後一次來request的時間
1758
								$client[$request->id]["last_req_time"]=$last_req_time;
1759
 
1760
								#等待下個要求
1761
								continue;
1762
 
1763
								}#if end
1764
 
1765
							#如果要查詢程序執行的狀況
854 liveuser 1766
							if(isset($request->QueryProcByUUID)){
851 liveuser 1767
 
1768
								#如果沒有 proc 資訊
1769
								if(!isset($result["serverCache"]["serverSide"]["procs"])){
1770
 
1771
									#設置要回覆的內容
1772
									$res=array("status"=>"true","content"=>"");
1773
 
1774
									#印出回的訊息
1775
									echo "response:".PHP_EOL.print_r($res,true);
1776
 
1777
									#寫入回應的內容
1778
									fwrite($conn,json_encode($res).PHP_EOL);
1779
 
1780
									#結束回應
1781
									fwrite($conn,PHP_EOL.PHP_EOL);
1782
 
1783
									#關閉socket連線,將回應輸出.
1784
									fclose($conn);
1785
 
1786
									#更新使用者id與最後一次來request的時間
1787
									$client[$request->id]["last_req_time"]=$last_req_time;
1788
 
1789
									#等待下個要求
1790
									continue;
1791
 
1792
									}#if end
1793
 
1794
								#函式說明:
1795
								#更新透過proc執行的多程序資訊.
1796
								#回傳結果:
1797
								#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
1798
								#$reuslt["error"],執行不正常結束的錯訊息陣列.
1799
								#$result["function"],當前執行的函式名稱.
1800
								#$result["argu"],使用的參數.
1801
								#$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"代表程序的資訊.
1802
								#必填參數:
1803
								#$conf["procs"],陣列,運行self::proc後回傳的content.
854 liveuser 1804
								$conf["threads::proc_update"]["procs"]=$result["serverCache"]["serverSide"]["procs"][$request->QueryProcByUUID]["content"];
851 liveuser 1805
								#可省略參數:
1806
								#無.
1807
								#參考資料:
1808
								#無.
1809
								#備註:
1810
								#無.
1811
								$proc_update=threads::proc_update($conf["threads::proc_update"]);
1812
								unset($conf["threads::proc_update"]);
1813
 
1814
								#如果執行失敗
1815
								if($proc_update["status"]==="false"){
1816
 
1817
									#設置執行失敗
1818
									$result["status"]="false";
1819
 
1820
									#設置錯誤訊息
1821
									$result["error"]=$proc_update;
1822
 
1823
									#回傳結果
1824
									return $result;
1825
 
1826
									}#if end
1827
 
1828
								#更新 serverSide 的 proc cache
854 liveuser 1829
								$result["serverCache"]["serverSide"]["procs"][$request->QueryProcByUUID]["content"]=$proc_update["content"];
851 liveuser 1830
 
1831
								#設置最後檢查的時間
854 liveuser 1832
								$result["serverCache"]["serverSide"]["procs"][$request->QueryProcByUUID]["latestAccessTime"]=time();
851 liveuser 1833
 
854 liveuser 1834
								#印出子程序的資訊
1835
								echo "proc info:".PHP_EOL.print_r($proc_update["content"][0],true);
851 liveuser 1836
 
854 liveuser 1837
								#初始化要回傳的內容
1838
								$res=array();
1839
 
1840
								#設置 pid
1841
								$res["pid"]=$proc_update["content"][0]["proc_get_status"]["pid"];
1842
 
1843
								#設置輸入的內容
1844
								$res["input"]=$proc_update["content"][0]["input"];
1845
 
1846
								#預設設置已經結束執行
1847
								$res["running"]="false";
1848
 
1849
								#如果尚在執行
1850
								if($proc_update["content"][0]["statusCode"]==="?"){
1851
 
1852
									#設置正在執行
1853
									$res["running"]="true";
1854
 
1855
									}#if end
1856
 
1857
								#如果已經結束執行
1858
								if($res["running"]==="false"){
1859
 
1860
									#設置執行後得到的標準輸出
1861
									$res["output"]=$proc_update["content"][0]["content"];
1862
 
1863
									#設置執行後得到的錯誤輸出
1864
									$res["error"]=$proc_update["content"][0]["error"];
1865
 
1866
									}#if end
1867
 
1868
								#設置回應正常
1869
								$res["status"]="true";
1870
 
851 liveuser 1871
								#印出回的訊息
1872
								echo "response:".PHP_EOL.print_r($res,true);
1873
 
1874
								#寫入回應的內容
1875
								fwrite($conn,json_encode($res).PHP_EOL);
1876
 
1877
								#結束回應
1878
								fwrite($conn,PHP_EOL.PHP_EOL);
1879
 
1880
								#關閉socket連線,將回應輸出.
1881
								fclose($conn);
1882
 
1883
								#更新使用者id與最後一次來request的時間
1884
								$client[$request->id]["last_req_time"]=$last_req_time;
1885
 
1886
								#等待下個要求
1887
								continue;
1888
 
1889
								}#if end
1890
 
717 liveuser 1891
							#debug
718 liveuser 1892
							#var_dump(__LINE__,$conn,$client[$request->id]);
717 liveuser 1893
 
386 liveuser 1894
							#如果存在 addOnProcessFunc
1895
							if(isset($conf["addOnProcessFunc"])){
668 liveuser 1896
 
386 liveuser 1897
								#針對每個 addOnProcessFunc
1898
								foreach($conf["addOnProcessFunc"] as $addOnProcessFunc){
565 liveuser 1899
 
1900
									#如果有設置 infoToFunction
1901
									if(isset($conf["infoToFunction"])){
1902
 
1903
										#設置info
572 liveuser 1904
										$client[$request->id]["info"]=&$conf["infoToFunction"];
705 liveuser 1905
 
565 liveuser 1906
										}#if end
1907
 
705 liveuser 1908
									#設置client cache
1909
									$client[$request->id]["clientCache"]=&$clientCache;
1910
 
386 liveuser 1911
									#呼叫 $addOnProcessFunc 函式,參數用 $client[$request->id], 取得執行後的回應.
668 liveuser 1912
									eval("\$call_user_func=".$addOnProcessFunc."(\$client[\$request->id]);");
1913
 
669 liveuser 1914
									/* debug
1915
 
1916
									#函式說明:
1917
									#撰寫log
1918
									#回傳結果:
1919
									#$result["status"],狀態,"true"或"false".
1920
									#$result["error"],錯誤訊息陣列.
1921
									#$result["function"],當前函式的名稱.
1922
									#$result["argu"],使用的參數.
1923
									#$result["content"],要寫入log的內容字串.
1924
									#必填參數:
1925
									#$conf["path"],字串,log檔案的路徑與名稱.
1926
									$conf["logs::record"]["path"]=$conf["sock"].".log";
1927
									#$conf["content"],any,要寫的內容,若內容不為字串則會用var_dump的格式寫入.
1928
									$conf["logs::record"]["content"]=$call_user_func;
1929
									#$conf["fileArgu"],字串,php變數__FILE__的內容,亦即該檔案在檔案系統的絕對路徑
1930
									$conf["logs::record"]["fileArgu"]=__FILE__;
1931
									#可省略參數:
1932
									#$conf["rewrite"],預設為"false",接續寫入;反之"true"代表重新寫入.
1933
									#$conf["rewrite"]="false";
1934
									#$conf["returnOnly"],預設為"false",會寫入到log檔案.若為"true"則不會寫入log.
1935
									#$conf["returnOnly"]="true";
1936
									#參考資料:
1937
									#無.
1938
									#備註:
1939
									#無.
1940
									$record=logs::record($conf["logs::record"]);
1941
									unset($conf["logs::record"]);
699 liveuser 1942
 
669 liveuser 1943
									#如果執行失敗
1944
									if($record["status"]==="false"){
1945
 
1946
										#設置執行錯誤識別
1947
										$result["status"]="false";
1948
 
1949
										#設置執行錯誤
1950
										$result["error"]=$record;
1951
 
1952
										#回傳結果
1953
										return $result;
1954
 
1955
										}#if end
1956
 
1957
									*/
1958
 
386 liveuser 1959
									#如果回應不是 array
1960
									if(gettype($call_user_func)!=="array"){
1 liveuser 1961
 
386 liveuser 1962
										#設置執行失敗
1963
										$result["status"]="false";
668 liveuser 1964
 
386 liveuser 1965
										#設置錯誤訊息
1966
										$result["error"][]=$call_user_func;
1967
 
1968
										#設置錯誤訊息
1969
										$result["error"][]=$conf;
668 liveuser 1970
 
386 liveuser 1971
										#印出error資訊
668 liveuser 1972
										echo "error:".print_r($result,true);
1973
 
1974
										#回應錯誤訊息給用戶
1975
										fwrite($conn,json_encode($result).PHP_EOL);
1976
 
669 liveuser 1977
										#結束回應
1978
										fwrite($conn,PHP_EOL.PHP_EOL);
1979
 
1980
										#關閉socket連線,將回應輸出.
1981
										fclose($conn);
1982
 
386 liveuser 1983
										#回傳結果
1984
										return $result;
1985
 
1986
										}#if end
1 liveuser 1987
 
386 liveuser 1988
									#檢查回應的格式
1989
									#函式說明:
1990
									#檢查必填與可省略的參數,可省略參數可指定預設要給與什麼數值內容。
1991
									#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
1992
									#$reuslt["error"],執行不正常結束的錯訊息陣列.
1993
									#$result["function"],當前執行的函式名稱.
1994
									#$result["argu"],設置給予的參數.
1995
									#$result["passed"],識別要檢查的全體變數是否存在以及型態是否正確的變數,"true"代表檢查全部通過;"false"代表檢查不通過
1996
									#$result[$shouldBeCheckedVarName]["varExist"],所檢查的變數是否存在,"false"代表不存在;"true"代表存在
1997
									#$result[$shouldBeCheckedVarName]["varType"],所檢查的變數型態是否正確,"false"代表錯誤;"true"代表正確
1998
									#$result[$shouldBeCheckedVarName]["error"],每個參數設定的錯誤訊息
1999
									#$result["shouldNotBeEmpty"],不應該為空字串或控陣列的變數.
2000
									#$result["argu"],字串陣列,目前輸入的參數名稱陣列.
2001
									#$result["legalVarName"],字串陣列,合法可用的參數名稱陣列.
2002
									#$result["notNeedVar"],字串陣列,多餘的參數名稱.
2003
									#必填寫的參數:
2004
									#$conf["varInput"],陣列變數,要檢查的陣列變數,請在要檢查的參數前面加上&,這樣變動的結果才能被套用。
2005
									$conf["variableCheck::checkArguments"]["varInput"]=&$call_user_func;	
2006
									#$conf["referenceVarKey"],字串,$conf參數後面的key值,用於移除不要的參考陣列.
2007
									$conf["variableCheck::checkArguments"]["referenceVarKey"]="variableCheck::checkArguments";
2008
									#可以省略的參數:
2009
									#$conf["mustBeFilledVariableName"],爲必填參數的變數名稱陣列,形態爲陣列變數,元素數量需要跟"mustBeFilledVariableType"參數的元素數量一致,例如: $conf["mustBeFilledVariableName"] = array("id","account","password");
400 liveuser 2010
									$conf["variableCheck::checkArguments"]["mustBeFilledVariableName"]=array("status");
386 liveuser 2011
									#$conf["mustBeFilledVariableType"],爲必填參數的變數陣列應該爲何種變數形態,形態爲陣列,元素數量需要跟"mustBeFilledVariableName"參數的元素數量一致,例如: $conf["mustBeFilledVariableType"] = array("string",integer,"double","resource","object"); , null代表不指定變數形態.
400 liveuser 2012
									$conf["variableCheck::checkArguments"]["mustBeFilledVariableType"]=array("string");
386 liveuser 2013
									#$conf["canBeEmptyString"],字串,必填變數內容如果是空字串就不能算是有設置的話,請設為"false",預設爲"true",可以為空字串.
2014
									$conf["variableCheck::checkArguments"]["canBeEmptyString"]="false";
2015
									#$conf["canNotBeEmpty"],字串陣列,哪些必填參數的內容不得為空字串或空陣列,僅當$conf["canBeEmptyString"]為"true"時會生效.
2016
									#$conf["canNotBeEmpty"]=array();
2017
									#$conf["canBeEmpty"],字串陣列,哪些必填參數的內容可為空字串或空陣列,僅當$conf["canBeEmptyString"]為"false"時會生效.
2018
									#$conf["canBeEmpty"]=array();
2019
									#$conf["skipableVariableCanNotBeEmpty"],字串陣列,哪些可省略參數不可以為空字串或空陣列.
2020
									#$conf["variableCheck::checkArguments"]["skipableVariableCanNotBeEmpty"]=array("function","continue");
2021
									#$conf["skipableVariableName"],陣列字串,爲可省略參數的變數名稱陣列,形態爲陣列變數,例如: $conf["skipableVariableName"] = array("id","account","password");
669 liveuser 2022
									$conf["variableCheck::checkArguments"]["skipableVariableName"]=array("function","continue","content","cache","argu","error");
386 liveuser 2023
									#$conf["skipableVariableType"],陣列字串,爲可省略參數的變數名稱陣列,形態爲陣列變數,例如: $conf["skipableVariableType"] = array("string",integer,"double"); 
669 liveuser 2024
									$conf["variableCheck::checkArguments"]["skipableVariableType"]=array("string","string",null,"array","array","array");
386 liveuser 2025
									#$conf["skipableVarDefaultValue"],字串陣列,每個不存在的可省略變數要初始化為什麼,null與代表不指定,若預設值是參數之一,請將$conf["mustBeFilledVar"]改成"\$conf["\mustBeFilledVar\"]".
669 liveuser 2026
									$conf["variableCheck::checkArguments"]["skipableVarDefaultValue"]=array($addOnProcessFunc,"true",null,null,null,null);
386 liveuser 2027
									#$conf["disallowAllSkipableVarIsEmpty"],字串,是否允許每個可省略參數都為空字串,預設為"true"允許,反之為"false".
2028
									#$conf["disallowAllSkipableVarIsEmpty"]="";
2029
									#$conf["disallowAllSkipableVarIsEmptyArray"],字串,是否允許每個可省略參數都為空陣列,預設為"true"允許,反之為"false".
2030
									#$conf["disallowAllSkipableVarIsEmptyArray"]="";
2031
									#$conf["arrayCountEqualCheck"],字串陣列,為檢查哪些陣列參數的元素數量要一樣,$conf["arrayCountEqualCheck"][$i]=array()為第$i組key為哪些的變數其元素數量要相等.
2032
									#$conf["arrayCountEqualCheck"][]=array();
2033
									#參考資料來源:
2034
									#array_keys=>http://php.net/manual/en/function.array-keys.php
2035
									$checkArguments=variableCheck::checkArguments($conf["variableCheck::checkArguments"]);
2036
									unset($conf["variableCheck::checkArguments"]);
668 liveuser 2037
 
386 liveuser 2038
									#如果檢查參數失敗
2039
									if($checkArguments["status"]==="false"){
2040
 
2041
										#設置執行失敗
2042
										$result["status"]="false";
2043
 
2044
										#設置錯誤訊息
2045
										$result["error"]=$checkArguments;
2046
 
669 liveuser 2047
										#印出error資訊
2048
										echo "error:".print_r($result,true);
2049
 
668 liveuser 2050
										#回應錯誤訊息給用戶
2051
										fwrite($conn,json_encode($result).PHP_EOL);
2052
 
669 liveuser 2053
										#結束回應
2054
										fwrite($conn,PHP_EOL.PHP_EOL);
2055
 
2056
										#關閉socket連線,將回應輸出.
2057
										fclose($conn);
2058
 
386 liveuser 2059
										#回傳結果
2060
										return $result;
2061
 
2062
										}#if end
2063
 
2064
									#如果檢查參數不通過
2065
									if($checkArguments["passed"]==="false"){
2066
 
2067
										#設置執行失敗
2068
										$result["status"]="false";
2069
 
2070
										#設置錯誤訊息
2071
										$result["error"]=$checkArguments;
2072
 
669 liveuser 2073
										#印出error資訊
2074
										echo "error:".print_r($result,true);
2075
 
668 liveuser 2076
										#回應錯誤訊息給用戶
2077
										fwrite($conn,json_encode($result).PHP_EOL);
2078
 
669 liveuser 2079
										#結束回應
2080
										fwrite($conn,PHP_EOL.PHP_EOL);
2081
 
2082
										#關閉socket連線,將回應輸出.
2083
										fclose($conn);
2084
 
386 liveuser 2085
										#回傳結果
2086
										return $result;
2087
 
2088
										}#if end
1 liveuser 2089
 
386 liveuser 2090
									#如果回應不正常
2091
									if($call_user_func["status"]==="false"){
2092
 
2093
										#設置執行失敗
2094
										$result["status"]="false";
2095
 
2096
										#設置錯誤訊息
2097
										$result["error"][]=$call_user_func;
2098
 
2099
										#設置錯誤訊息
2100
										$result["error"][]=$conf;
2101
 
2102
										#印出error資訊
668 liveuser 2103
										echo "error:".print_r($result,true);
2104
 
2105
										#回應錯誤訊息給用戶
2106
										fwrite($conn,json_encode($result).PHP_EOL);
2107
 
669 liveuser 2108
										#結束回應
2109
										fwrite($conn,PHP_EOL.PHP_EOL);
2110
 
2111
										#關閉socket連線,將回應輸出.
2112
										fclose($conn);
2113
 
386 liveuser 2114
										#回傳結果
2115
										return $result;
2116
 
2117
										}#if end
2118
 
387 liveuser 2119
									#如果回應有 content 元素
2120
									if(isset($call_user_func["content"])){
2121
 
2122
										#用收到 content 元素內容來更新 $client[id]["request"]
2123
										$client[$request->id]["request"]=$call_user_func["content"];
2124
 
2125
										}#if end
668 liveuser 2126
 
851 liveuser 2127
									#如果回傳 cache 元素
668 liveuser 2128
									if(isset($call_user_func["cache"])){
2129
 
851 liveuser 2130
										#用收到 cache 元素內容來更新 server side 的 cache
669 liveuser 2131
										$result["serverCache"]["clientSide"]["addOnProcessFunc"][$addOnProcessFunc]=&$call_user_func["cache"];
668 liveuser 2132
 
2133
										}#if end
2134
 
386 liveuser 2135
									#如果回應不要往後面執行
2136
									if($call_user_func["continue"]==="false"){
2137
 
2138
										#結束 foreach
2139
										break;
2140
 
2141
										}#if end
668 liveuser 2142
 
386 liveuser 2143
									}#foreach end
2144
 
2145
								}#if end
2146
 
2147
							#執行到這代表是要保持連線
668 liveuser 2148
 
1 liveuser 2149
							#設置執行正常
2150
							$res["status"]="true";
668 liveuser 2151
 
1 liveuser 2152
							#印出回的訊息
668 liveuser 2153
							echo "response:".PHP_EOL.print_r($res,true);
2154
 
717 liveuser 2155
							#debug
2156
							#var_dump(__LINE__,$conn,get_resource_type($conn));
386 liveuser 2157
 
851 liveuser 2158
							#如果資源形態沒有異常(用戶關閉連線後,會有resource type變成"Unknown"的結果)
717 liveuser 2159
							if(get_resource_type($conn)!=="Unknown"){
1 liveuser 2160
 
717 liveuser 2161
								#函式說明:
2162
								#用fwrite寫入到resource,可以指定每個寫入字串的結尾方式.
2163
								#回傳結果:
2164
								#$result["status"],執行是否正常,"true"為正常,"false"為不正常.
2165
								#$result["error"],錯誤訊息陣列.
2166
								#$result["function"],當前執行的函數名稱.
2167
								#$result["argu"],使用的參數.
2168
								#$result["is_writable"],參數stream是否為可寫入的resource,"true"代表可寫入;"false"代表不可寫入.
2169
								#必填參數:
2170
								#$conf["stream"],resource,寫入的目標.
2171
								$conf["sock::fwrite"]["stream"]=&$conn;
2172
								#$conf["data"],字串陣列,要寫入的內容,每個元素代表每段要寫入的內容.
2173
								$conf["sock::fwrite"]["data"]=array(json_encode($res).PHP_EOL);
2174
								#可省略參數:
2175
								#$conf["msgEndType"],字串,訊息結尾要怎麼寫,預設為"none",代表不做處理;"EOL"代表結尾要用PHP_EOL;"HTTP/1.1"代表"data"參數最多為2個,分別為header跟body,結尾方式為兩個PHP_EOL.
2176
								$conf["sock::fwrite"]["msgEndType"]="HTTP/1.1";
2177
								#$conf["autoClose"],字串,寫入結束後是否要關閉resource,預設為"false"代表保持開着;反之為"true".
2178
								$conf["sock::fwrite"]["autoClose"]="true";
2179
								#參考資料:
2180
								#https://stackoverflow.com/questions/5294305/how-to-check-if-a-php-stream-resource-is-readable-or-writable#5294425
2181
								#https://www.php.net/manual/en/function.stream-get-meta-data.php
2182
								#https://www.php.net/manual/en/function.is-writable.php
2183
								#https://www.php.net/manual/en/function.socket-get-status.php
2184
								#備註:
2185
								#無.
2186
								$fwrite=sock::fwrite($conf["sock::fwrite"]);
2187
								unset($conf["sock::fwrite"]);
2188
 
2189
								#如果執行失敗
2190
								if($fwrite["status"]==="false"){
2191
 
2192
									#如果有 is_writable
2193
									if(isset($fwrite["is_writable"])){
2194
 
2195
										#如果有 is_writable
2196
										if($fwrite["is_writable"]==="true"){
2197
 
2198
											#設置執行失敗
2199
											$result["status"]="false";
2200
 
2201
											#設置錯誤訊息
2202
											$result["error"]=$fwrite;
2203
 
2204
											#印出error資訊
2205
											echo "error:".print_r($result,true);
2206
 
2207
											#結束並回傳1給shell
2208
											exit(1);
2209
 
2210
											}#if end
2211
 
2212
										}#if end
2213
 
2214
									#反之
2215
									else{
2216
 
2217
										#設置執行失敗
2218
										$result["status"]="false";
2219
 
2220
										#設置錯誤訊息
2221
										$result["error"]=$fwrite;
2222
 
2223
										#印出error資訊
2224
										echo "error:".print_r($result,true);
2225
 
2226
										#結束並回傳1給shell
2227
										exit(1);
2228
 
2229
										}#else end
2230
 
2231
									}#if end
2232
 
2233
								}#if end
2234
 
1 liveuser 2235
							#更新使用者id與最後一次來request的時間
2236
							$client[$request->id]["last_req_time"]=$last_req_time;	
668 liveuser 2237
 
386 liveuser 2238
							#印出用戶端列表
2239
							echo "clients:".print_r($client,true);	
668 liveuser 2240
 
1 liveuser 2241
							#等待下個要求
2242
							continue;
668 liveuser 2243
 
386 liveuser 2244
							}#if end
1 liveuser 2245
 
386 liveuser 2246
						#socket 陣列不是我們建立的 socket
2247
						else{
1 liveuser 2248
 
386 liveuser 2249
							#顯示 socket 的狀態
2250
							var_dump("socket_get_status".socket_get_status($conn));
1 liveuser 2251
 
386 liveuser 2252
							}#else end
1 liveuser 2253
 
386 liveuser 2254
						}#foreach end
2255
 
2256
					}#else end
2257
 
1 liveuser 2258
				}#while end
2259
 
2260
			#關閉 unix domain socket
2261
			fclose($socket);
2262
 
2263
			}#else end
2264
 
2265
		}#function unixDomainSockServer end
2266
 
2267
	/*
2268
	#函式說明:
2269
	#連線到 unixDomainSockServer 提供的 unix domain socket.
2270
	#回傳結果:
2271
	#$result["status"],"true"代表執行正常;"false"代表執行不正常.
2272
	#$result["error"],錯誤訊息陣列.
2273
	#$result["function"],當前執行的函式名稱.
668 liveuser 2274
	#$result["content"],取得的回應,讀到EOL,才會結束.
1 liveuser 2275
	#必填參數:
2276
	#$conf["sock"],字串,要連線的unix domain socket.
2277
	$conf["sock"]="";
2278
	#可省略參數:
2279
	#$conf["id"],字串,取得的id,若無此值,則會得到新的數值.
2280
	#$conf["id"]="";
2 liveuser 2281
	#$conf["cmd"],字串,要執行的指令,當$conf["id"]參數合法時,才會執行.
1 liveuser 2282
	#$conf["cmd"]="";
2283
	#$conf["param"],參數陣列.
2284
	#$conf["param"]=array();
443 liveuser 2285
	#$conf["escaped"],字串,param參數是否已經escaped了,預設為"false",反之為"true".
2286
	#$conf["escaped"]="true";
565 liveuser 2287
	#$conf["custom"],陣列,要客制化傳輸的內容,會覆蓋以上除了$conf["id"]以外的可省略參數.
387 liveuser 2288
	#$conf["custom"]=array();
765 liveuser 2289
	#$conf["raw"],字串,要直接傳送的字串內容,會忽略其他可省略參數.
2290
	#$conf["raw"]="";
1 liveuser 2291
	#參考資料:
2292
	#http://php.net/manual/en/function.stream-socket-client.php
2293
	#http://php.net/manual/en/function.stream-get-contents.php
216 liveuser 2294
	#備註:
519 liveuser 2295
	#無.
1 liveuser 2296
	*/
216 liveuser 2297
	public static function unixDomainSockClient(&$conf){
1 liveuser 2298
 
2299
		#初始化要回傳的結果
2300
		$result=array();
2301
 
2302
		#取得當前執行的函數名稱
2303
		$result["function"]=__FUNCTION__;
2304
 
2305
		#如果沒有參數
2306
		if(func_num_args()==0){
2307
 
2308
			#設置執行失敗
2309
			$result["status"]="false";
2310
 
2311
			#設置執行錯誤訊息
2312
			$result["error"]="函數".$result["function"]."需要參數";
2313
 
2314
			#回傳結果
2315
			return $result;
2316
 
2317
			}#if end
2318
 
2319
		#取得參數
2320
		$result["argu"]=$conf;
2321
 
2322
		#如果 $conf 不為陣列
2323
		if(gettype($conf)!="array"){
2324
 
2325
			#設置執行失敗
2326
			$result["status"]="false";
2327
 
2328
			#設置執行錯誤訊息
2329
			$result["error"][]="\$conf變數須為陣列形態";
2330
 
2331
			#如果傳入的參數為 null
2332
			if($conf==null){
2333
 
2334
				#設置執行錯誤訊息
2335
				$result["error"][]="\$conf變數不得為null,請檢查函數「".$result["function"]."」的參數設置有無正確!";
2336
 
2337
				}#if end
2338
 
2339
			#回傳結果
2340
			return $result;
2341
 
2342
			}#if end
2343
 
2344
		#檢查參數
2345
		#函式說明:
2346
		#檢查必填與可省略的參數,可省略參數可指定預設要給與什麼數值內容。
2347
		#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
2348
		#$reuslt["error"],執行不正常結束的錯訊息陣列.
2349
		#$result["function"],當前執行的函式名稱.
2350
		#$result["argu"],設置給予的參數.
2351
		#$result["passed"],識別要檢查的全體變數是否存在以及型態是否正確的變數,"true"代表檢查全部通過;"false"代表檢查不通過
2352
		#$result[$shouldBeCheckedVarName]["varExist"],所檢查的變數是否存在,"false"代表不存在;"true"代表存在
2353
		#$result[$shouldBeCheckedVarName]["varType"],所檢查的變數型態是否正確,"false"代表錯誤;"true"代表正確
2354
		#$result[$shouldBeCheckedVarName]["error"],每個參數設定的錯誤訊息
2355
		#$result["shouldNotBeEmpty"],不應該為空字串或控陣列的變數.
2356
		#$result["argu"],字串陣列,目前輸入的參數名稱陣列.
2357
		#$result["legalVarName"],字串陣列,合法可用的參數名稱陣列.
2358
		#$result["notNeedVar"],字串陣列,多餘的參數名稱.
2359
		#必填寫的參數:
2360
		#$conf["varInput"],陣列變數,要檢查的陣列變數,請在要檢查的參數前面加上&,這樣變動的結果才能被套用。
2361
		$conf["variableCheck::checkArguments"]["varInput"]=&$conf;	
2362
		#$conf["referenceVarKey"],字串,$conf參數後面的key值,用於移除不要的參考陣列.
2363
		$conf["variableCheck::checkArguments"]["referenceVarKey"]="variableCheck::checkArguments";
2364
		#可以省略的參數:
2365
		#$conf["mustBeFilledVariableName"],爲必填參數的變數名稱陣列,形態爲陣列變數,元素數量需要跟"mustBeFilledVariableType"參數的元素數量一致,例如: $conf["mustBeFilledVariableName"] = array("id","account","password");
2366
		$conf["variableCheck::checkArguments"]["mustBeFilledVariableName"]=array("sock");
2367
		#$conf["mustBeFilledVariableType"],爲必填參數的變數陣列應該爲何種變數形態,形態爲陣列,元素數量需要跟"mustBeFilledVariableName"參數的元素數量一致,例如: $conf["mustBeFilledVariableType"] = array("string",integer,"double","resource","object"); , null代表不指定變數形態.
2368
		$conf["variableCheck::checkArguments"]["mustBeFilledVariableType"]=array("string");
2369
		#$conf["canBeEmptyString"],字串,必填變數內容如果是空字串就不能算是有設置的話,請設為"false",預設爲"true",可以為空字串.
2370
		#$conf["canBeEmptyString"]="false";
2371
		#$conf["canNotBeEmpty"],字串陣列,哪些必填參數的內容不得為空字串或空陣列,僅當$conf["canBeEmptyString"]為"true"時會生效.
2372
		#$conf["canNotBeEmpty"]=array();
2373
		#$conf["canBeEmpty"],字串陣列,哪些必填參數的內容可為空字串或空陣列,僅當$conf["canBeEmptyString"]為"false"時會生效.
2374
		#$conf["canBeEmpty"]=array();
2375
		#$conf["skipableVariableCanNotBeEmpty"],字串陣列,哪些可省略參數不可以為空字串或空陣列.
443 liveuser 2376
		$conf["variableCheck::checkArguments"]["skipableVariableCanNotBeEmpty"]=array("id","cmd","param","escaped","custom");
1 liveuser 2377
		#$conf["skipableVariableName"],陣列字串,爲可省略參數的變數名稱陣列,形態爲陣列變數,例如: $conf["skipableVariableName"] = array("id","account","password");
765 liveuser 2378
		$conf["variableCheck::checkArguments"]["skipableVariableName"]=array("id","cmd","param","escaped","custom","raw");
1 liveuser 2379
		#$conf["skipableVariableType"],陣列字串,爲可省略參數的變數名稱陣列,形態爲陣列變數,例如: $conf["skipableVariableType"] = array("string",integer,"double"); 
765 liveuser 2380
		$conf["variableCheck::checkArguments"]["skipableVariableType"]=array("string","string","array","string","array","string");
1 liveuser 2381
		#$conf["skipableVarDefaultValue"],字串陣列,每個不存在的可省略變數要初始化為什麼,null與代表不指定,若預設值是參數之一,請將$conf["mustBeFilledVar"]改成"\$conf["\mustBeFilledVar\"]".
765 liveuser 2382
		$conf["variableCheck::checkArguments"]["skipableVarDefaultValue"]=array(null,null,null,"false",null,null);
1 liveuser 2383
		#$conf["disallowAllSkipableVarIsEmpty"],字串,是否允許每個可省略參數都為空字串,預設為"true"允許,反之為"false".
2384
		#$conf["disallowAllSkipableVarIsEmpty"]="";
2385
		#$conf["disallowAllSkipableVarIsEmptyArray"],字串,是否允許每個可省略參數都為空陣列,預設為"true"允許,反之為"false".
2386
		#$conf["disallowAllSkipableVarIsEmptyArray"]="";
2387
		#$conf["arrayCountEqualCheck"],字串陣列,為檢查哪些陣列參數的元素數量要一樣,$conf["arrayCountEqualCheck"][$i]=array()為第$i組key為哪些的變數其元素數量要相等.
2388
		#$conf["arrayCountEqualCheck"][]=array();
2389
		#參考資料來源:
2390
		#array_keys=>http://php.net/manual/en/function.array-keys.php
2391
		$checkArguments=variableCheck::checkArguments($conf["variableCheck::checkArguments"]);
2392
		unset($conf["variableCheck::checkArguments"]);
2393
 
2394
		#如果檢查參數失敗
2395
		if($checkArguments["status"]==="false"){
2396
 
2397
			#設置執行失敗
2398
			$result["status"]="false";
2399
 
2400
			#設置錯誤訊息
2401
			$result["error"]=$checkArguments;
2402
 
2403
			#回傳結果
2404
			return $result;
2405
 
2406
			}#if end
2407
 
2408
		#如果檢查參數不通過
2409
		if($checkArguments["passed"]==="false"){
2410
 
2411
			#設置執行失敗
2412
			$result["status"]="false";
2413
 
2414
			#設置錯誤訊息
2415
			$result["error"]=$checkArguments;
2416
 
2417
			#回傳結果
2418
			return $result;
2419
 
2420
			}#if end
2421
 
357 liveuser 2422
		#檢查 unix socket 檔案 $conf["sock"] 是否存在.
386 liveuser 2423
		#函式說明:
2424
		#檢查多個檔案與資料夾是否存在.
2425
		#回傳的結果:
2426
		#$result["status"],執行正常與否,"true"代表正常,"false"代表不正常.
2427
		#$result["error"],錯誤訊息陣列.
2428
		#$resutl["function"],當前執行的涵式名稱.
2429
		#$result["argu"],使用的參數.
2430
		#$result["allExist"],所有檔案皆存在的識別,"true"代表皆存在,"false"代表沒有全部都存在.
2431
		#$result["varName"][$i],爲第$i個資料夾或檔案的路徑與名稱。
2432
		#$result["varNameFullPath"][$i],爲第$i個資料夾或檔案的完整檔案系統路徑與名稱,如果不存在則代表路徑是網址.
2433
		#$result["varNameWebPath"][$i],為第$i個資料夾或檔案的網址
2434
		#$result["varExist"][$i],爲第$i個資料夾或檔案是否存在,"true"代表存在,"false"代表不存在。
2435
		#必填參數:
2436
		#$conf["fileArray"],陣列字串,要檢查是否存在的檔案有哪些,須爲一維陣列數值。
393 liveuser 2437
		$conf["variableCheck::checkArguments"]["fileArray"]=array($conf["sock"]);
386 liveuser 2438
		#$conf["fileArgu"],字串,php變數__FILE__的內容,亦即該檔案在檔案系統的絕對路徑
393 liveuser 2439
		$conf["variableCheck::checkArguments"]["fileArgu"]=__FILE__;
386 liveuser 2440
		#可省略參數:
2441
		#$conf["disableWebSearch"],"字串",是否取消「當檔案找不到時,改用catchWebContent類別的wget函數來檢查檔案是否存在於網路上」的功能,"false"不取消,若要取消該功能請設為"true",若抓到的內容為空字串則會視為檔案不存在,預設為"true".
2442
		#$conf["disableWebSearch"]="false";
2443
		#$conf["userDir"],字串,網頁是否置放於家目錄底下,"true"為是,"false"為不是,預設為"true".
519 liveuser 2444
		$conf["variableCheck::checkArguments"]["userDir"]="false";
386 liveuser 2445
		#$conf["web"],字串,檔案是放在web就是"true",反之為檔案系統"false",預設為"true".
519 liveuser 2446
		$conf["variableCheck::checkArguments"]["web"]="false";
386 liveuser 2447
		#參考資料:
2448
		#http://php.net/manual/en/function.file-exists.php
2449
		#http://php.net/manual/en/control-structures.foreach.php
2450
		#備註:
2451
		#函數file_exists檢查的路徑為檔案系統的路徑
2452
		#$result["varName"][$i]結果未實作
393 liveuser 2453
		$checkMultiFileExist=fileAccess::checkMultiFileExist($conf["variableCheck::checkArguments"]);
2454
		unset($conf["variableCheck::checkArguments"]);
357 liveuser 2455
 
386 liveuser 2456
		#如果檢查失敗
2457
		if($checkMultiFileExist["status"]==="false"){
2458
 
2459
			#設置執行失敗
2460
			$result["status"]="false";
2461
 
2462
			#設置錯誤訊息
2463
			$result["error"]=$checkMultiFileExist;
2464
 
2465
			#回傳結果
2466
			return $result;
2467
 
2468
			}#if end
2469
 
2470
		#如果檢查失敗
2471
		if($checkMultiFileExist["allExist"]==="false"){
2472
 
2473
			#設置執行失敗
2474
			$result["status"]="false";
2475
 
2476
			#設置錯誤訊息
2477
			$result["error"]=$checkMultiFileExist;
2478
 
2479
			#回傳結果
2480
			return $result;
2481
 
2482
			}#if end
2483
 
1 liveuser 2484
		#初始化取得的回應
2485
		$result["content"]="";
2486
 
668 liveuser 2487
		#debug
2488
		#var_dump(__LINE__,"before connect");
2489
 
1 liveuser 2490
		#嘗試30秒內連線到 unix domain socket
852 liveuser 2491
		$fp=@stream_socket_client("unix://".$conf["sock"], $errno, $errstr, 30, STREAM_CLIENT_ASYNC_CONNECT );
1 liveuser 2492
 
2493
		#如果開啟 unix domain socket 失敗
2494
		if(!$fp){
2495
 
2496
			#設置執行錯誤識別
2497
			$result["status"]="false";
2498
 
2499
			#設置錯誤訊息
2500
			$result["error"]=$errstr." (".$errno.")";
2501
 
2502
			#回傳結果
2503
			return $result;
2504
 
2505
			}#if end
2506
 
765 liveuser 2507
		#反之開啟 unix domain socket 成功,且沒有raw參數存在
2508
		else if(!isset($conf["raw"])){
1 liveuser 2509
 
2510
			#初始化要傳送的要求
2511
			$req=array();
2512
 
2513
			#如果有設置 $conf["id"]
2514
			if(isset($conf["id"])){
2515
 
2516
				#設置識別自己的id
2517
				$req["id"]=$conf["id"];
2518
 
2519
				}#if end
2520
 
2521
			#如果有設置 $conf["cmd"]
2522
			if(isset($conf["cmd"])){
2523
 
2524
				#設置要執行的指令
2525
				$req["cmd"]=$conf["cmd"];
2526
 
2527
				}#if end
2528
 
2529
			#如果有設置 $conf["param"]
2530
			if(isset($conf["param"])){
2531
 
2532
				#設置要執行的指令參數
2533
				$req["param"]=$conf["param"];
2534
 
443 liveuser 2535
				#設置參數是否已經escaped
2536
				$req["escaped"]=$conf["escaped"];
2537
 
1 liveuser 2538
				}#if end
386 liveuser 2539
 
387 liveuser 2540
			#如果有設置 $conf["custom"]
2541
			if(isset($conf["custom"])){
2542
 
2543
				#用 $conf["custom"] 來取代 $req
2544
				$req=$conf["custom"];
565 liveuser 2545
 
717 liveuser 2546
				#如果有設置 $conf["id"]
2547
				if(isset($conf["id"])){
2548
 
2549
					#設置識別自己的id
2550
					$req["id"]=$conf["id"];
2551
 
2552
					}#if end
387 liveuser 2553
 
2554
				}#if end
2555
 
668 liveuser 2556
			#debug
2557
			#var_dump(__LINE__,"before write ".json_encode($req));
2558
 
1 liveuser 2559
			#傳送要求
2560
			fwrite($fp,json_encode($req).PHP_EOL);
2561
 
2562
			#結束要求
2563
			fwrite($fp,PHP_EOL.PHP_EOL);
2564
 
2565
			#如果回應為空	
2566
			while(strlen($result["content"])<2){
2567
 
2568
				#當有回應時
2569
				while(!feof($fp)){
2570
 
2571
					#讀取回應
2572
					$tmp=fgets($fp, 1024);
2573
 
2574
					#debug
336 liveuser 2575
					#var_dump($tmp);
1 liveuser 2576
 
668 liveuser 2577
					#debug
2578
					#var_dump(__LINE__,"got ".$tmp);
2579
 
1 liveuser 2580
					#如果讀到 PHP_EOL
2581
					if($tmp===PHP_EOL){
851 liveuser 2582
 
1 liveuser 2583
						#結束讀取回應
851 liveuser 2584
						break 2;
1 liveuser 2585
 
2586
						}#if end
851 liveuser 2587
 
1 liveuser 2588
					#串接回應
2589
					$result["content"]=$result["content"].$tmp;
2590
 
2591
					}#while end
2592
 
668 liveuser 2593
				}#while end
1 liveuser 2594
 
765 liveuser 2595
			#關閉 socket
1 liveuser 2596
			fclose($fp);
2597
 
2598
			}#else end
765 liveuser 2599
 
2600
		#反之有有raw參數存在
2601
		else{
1 liveuser 2602
 
765 liveuser 2603
			#傳送要求
2604
			fwrite($fp,trim($conf["raw"]).PHP_EOL);
2605
 
2606
			#當有回應時
2607
			while(!feof($fp)){
2608
 
2609
				#讀取回應
2610
				$tmp=fgets($fp, 1024);
2611
 
2612
				#debug
2613
				#var_dump($tmp);
2614
 
2615
				#debug
2616
				#var_dump(__LINE__,"got ".$tmp);
2617
 
2618
				#如果讀到 PHP_EOL
2619
				if($tmp===PHP_EOL){
2620
 
2621
					#結束讀取回應
2622
					break;	
2623
 
2624
					}#if end
2625
 
2626
				#串接回應
2627
				$result["content"]=$result["content"].$tmp;
2628
 
2629
				}#while end
2630
 
2631
			#關閉 socket
2632
			fclose($fp);	
2633
 
2634
			}#else end
2635
 
1 liveuser 2636
		#設置執行正常
2637
		$result["status"]="true";
2638
 
2639
		#回傳結果
2640
		return $result;
2641
 
2642
		}#function unixDomainSockClient end
527 liveuser 2643
 
2644
	/*
854 liveuser 2645
	#函式說明:
527 liveuser 2646
	#連線到 usr/bin/qbpwcf-usock.php 產生的  unix domain socket,運行指定的指令.
2647
	#回傳結果:
2648
	#$result["status"],"true"代表執行正常;"false"代表執行不正常.
2649
	#$result["error"],錯誤訊息陣列.
2650
	#$result["function"],當前執行的函式名稱.
2651
	#$result["argu"],使用的參數.
2652
	#$result["content"],執行完指令的結果.
2653
	#必填參數:
2654
	#$conf["fileArgu"],字串,變數__FILE__的內容.
2655
	$conf["fileArgu"]=__FILE__;
2656
	#$conf["command"],字串,要執行的指令名稱.
2657
	$conf["command"]="";
2658
	#可省略參數:
854 liveuser 2659
	#$conf["sock"],字串,要連線的 usr/bin/qbpwcf-sock.php(sock::unixDomainSockServer) 所產生的 unix domain socket 路徑與名稱,預設為 qbpwcf_usock_path.
527 liveuser 2660
	#$conf["sock"]=qbpwcf_usock_path;
2661
	#$conf["argu"],陣列字串,指令搭配的參數,預設為空陣列.
2662
	#$conf["argu"]=array();
851 liveuser 2663
	#$conf["commandIncludeArgu"],字串,是否command含有參數,預設為"false"代表沒有;反之為"true".
2664
	#$conf["commandIncludeArgu"]="false";
2665
	#$conf["commandInBg"],字串,是否要將程序放在背景執行,再取得相關資訊,預設為"false"代表不要;反之為"true".
2666
	#$conf["commandInBg"]="false";
527 liveuser 2667
	#參考資料:
2668
	#無.
2669
	#備註:
2670
	#無.
2671
	*/
2672
	public static function execAnyCmdByQBPWCFunixSocket(&$conf){
2673
 
2674
		#初始化要回傳的結果
2675
		$result=array();
2676
 
2677
		#取得當前執行的函數名稱
2678
		$result["function"]=__FUNCTION__;
1 liveuser 2679
 
527 liveuser 2680
		#如果沒有參數
2681
		if(func_num_args()==0){
2682
 
2683
			#設置執行失敗
2684
			$result["status"]="false";
2685
 
2686
			#設置執行錯誤訊息
2687
			$result["error"]="函數".$result["function"]."需要參數";
2688
 
2689
			#回傳結果
2690
			return $result;
2691
 
2692
			}#if end
2693
 
2694
		#取得參數
2695
		$result["argu"]=$conf;
2696
 
2697
		#如果 $conf 不為陣列
2698
		if(gettype($conf)!="array"){
2699
 
2700
			#設置執行失敗
2701
			$result["status"]="false";
2702
 
2703
			#設置執行錯誤訊息
2704
			$result["error"][]="\$conf變數須為陣列形態";
2705
 
2706
			#如果傳入的參數為 null
2707
			if($conf==null){
2708
 
2709
				#設置執行錯誤訊息
2710
				$result["error"][]="\$conf變數不得為null,請檢查函數「".$result["function"]."」的參數設置有無正確!";
2711
 
2712
				}#if end
2713
 
2714
			#回傳結果
2715
			return $result;
2716
 
2717
			}#if end
2718
 
2719
		#檢查參數
2720
		#函式說明:
2721
		#檢查必填與可省略的參數,可省略參數可指定預設要給與什麼數值內容。
2722
		#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
2723
		#$reuslt["error"],執行不正常結束的錯訊息陣列.
2724
		#$result["function"],當前執行的函式名稱.
2725
		#$result["argu"],設置給予的參數.
2726
		#$result["passed"],識別要檢查的全體變數是否存在以及型態是否正確的變數,"true"代表檢查全部通過;"false"代表檢查不通過
2727
		#$result[$shouldBeCheckedVarName]["varExist"],所檢查的變數是否存在,"false"代表不存在;"true"代表存在
2728
		#$result[$shouldBeCheckedVarName]["varType"],所檢查的變數型態是否正確,"false"代表錯誤;"true"代表正確
2729
		#$result[$shouldBeCheckedVarName]["error"],每個參數設定的錯誤訊息
2730
		#$result["shouldNotBeEmpty"],不應該為空字串或控陣列的變數.
2731
		#$result["argu"],字串陣列,目前輸入的參數名稱陣列.
2732
		#$result["legalVarName"],字串陣列,合法可用的參數名稱陣列.
2733
		#$result["notNeedVar"],字串陣列,多餘的參數名稱.
2734
		#必填寫的參數:
2735
		#$conf["varInput"],陣列變數,要檢查的陣列變數,請在要檢查的參數前面加上&,這樣變動的結果才能被套用。
2736
		$conf["variableCheck::checkArguments"]["varInput"]=&$conf;	
2737
		#$conf["referenceVarKey"],字串,$conf參數後面的key值,用於移除不要的參考陣列.
2738
		$conf["variableCheck::checkArguments"]["referenceVarKey"]="variableCheck::checkArguments";
2739
		#可以省略的參數:
2740
		#$conf["mustBeFilledVariableName"],爲必填參數的變數名稱陣列,形態爲陣列變數,元素數量需要跟"mustBeFilledVariableType"參數的元素數量一致,例如: $conf["mustBeFilledVariableName"] = array("id","account","password");
2741
		$conf["variableCheck::checkArguments"]["mustBeFilledVariableName"]=array("fileArgu","command");
2742
		#$conf["mustBeFilledVariableType"],爲必填參數的變數陣列應該爲何種變數形態,形態爲陣列,元素數量需要跟"mustBeFilledVariableName"參數的元素數量一致,例如: $conf["mustBeFilledVariableType"] = array("string",integer,"double","resource","object"); , null代表不指定變數形態.
2743
		$conf["variableCheck::checkArguments"]["mustBeFilledVariableType"]=array("string","string");
2744
		#$conf["canBeEmptyString"],字串,必填變數內容如果是空字串就不能算是有設置的話,請設為"false",預設爲"true",可以為空字串.
2745
		#$conf["canBeEmptyString"]="false";
2746
		#$conf["canNotBeEmpty"],字串陣列,哪些必填參數的內容不得為空字串或空陣列,僅當$conf["canBeEmptyString"]為"true"時會生效.
2747
		#$conf["canNotBeEmpty"]=array();
2748
		#$conf["canBeEmpty"],字串陣列,哪些必填參數的內容可為空字串或空陣列,僅當$conf["canBeEmptyString"]為"false"時會生效.
2749
		#$conf["canBeEmpty"]=array();
2750
		#$conf["skipableVariableCanNotBeEmpty"],字串陣列,哪些可省略參數不可以為空字串或空陣列.
852 liveuser 2751
		$conf["variableCheck::checkArguments"]["skipableVariableCanNotBeEmpty"]=array("sock");
527 liveuser 2752
		#$conf["skipableVariableName"],陣列字串,爲可省略參數的變數名稱陣列,形態爲陣列變數,例如: $conf["skipableVariableName"] = array("id","account","password");
851 liveuser 2753
		$conf["variableCheck::checkArguments"]["skipableVariableName"]=array("sock","argu","commandIncludeArgu","commandInBg");
527 liveuser 2754
		#$conf["skipableVariableType"],陣列字串,爲可省略參數的變數名稱陣列,形態爲陣列變數,例如: $conf["skipableVariableType"] = array("string",integer,"double"); 
851 liveuser 2755
		$conf["variableCheck::checkArguments"]["skipableVariableType"]=array("string","array","string","string");
527 liveuser 2756
		#$conf["skipableVarDefaultValue"],字串陣列,每個不存在的可省略變數要初始化為什麼,null與代表不指定,若預設值是參數之一,請將$conf["mustBeFilledVar"]改成"\$conf["\mustBeFilledVar\"]".
852 liveuser 2757
		$conf["variableCheck::checkArguments"]["skipableVarDefaultValue"]=array(qbpwcf_usock_path,array(),"false","false");
527 liveuser 2758
		#$conf["disallowAllSkipableVarIsEmpty"],字串,是否允許每個可省略參數都為空字串,預設為"true"允許,反之為"false".
2759
		#$conf["disallowAllSkipableVarIsEmpty"]="";
2760
		#$conf["disallowAllSkipableVarIsEmptyArray"],字串,是否允許每個可省略參數都為空陣列,預設為"true"允許,反之為"false".
2761
		#$conf["disallowAllSkipableVarIsEmptyArray"]="";
2762
		#$conf["arrayCountEqualCheck"],字串陣列,為檢查哪些陣列參數的元素數量要一樣,$conf["arrayCountEqualCheck"][$i]=array()為第$i組key為哪些的變數其元素數量要相等.
2763
		#$conf["arrayCountEqualCheck"][]=array();
2764
		#參考資料來源:
2765
		#array_keys=>http://php.net/manual/en/function.array-keys.php
2766
		$checkArguments=variableCheck::checkArguments($conf["variableCheck::checkArguments"]);
2767
		unset($conf["variableCheck::checkArguments"]);
2768
 
2769
		#如果檢查參數失敗
2770
		if($checkArguments["status"]==="false"){
2771
 
2772
			#設置執行失敗
2773
			$result["status"]="false";
2774
 
2775
			#設置錯誤訊息
2776
			$result["error"]=$checkArguments;
2777
 
2778
			#回傳結果
2779
			return $result;
2780
 
2781
			}#if end
2782
 
2783
		#如果檢查參數不通過
2784
		if($checkArguments["passed"]==="false"){
2785
 
2786
			#設置執行失敗
2787
			$result["status"]="false";
2788
 
2789
			#設置錯誤訊息
2790
			$result["error"]=$checkArguments;
2791
 
2792
			#回傳結果
2793
			return $result;
2794
 
2795
			}#if end
2796
 
851 liveuser 2797
		#如果指令已經包含參數了
2798
		if($conf["commandIncludeArgu"]==="true"){
852 liveuser 2799
 
851 liveuser 2800
			#函式說明:
2801
			#將指令字串解析成陣列,方便給予 external::callShell 使用 
2802
			#回傳結果:
2803
			#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
2804
			#$reuslt["error"],執行不正常結束的錯訊息陣列.
2805
			#$result["function"],當前執行的函式名稱.
2806
			#$result["content"],解析好的指令陣列.
2807
			#$result["cmd"],解析好的指令名稱.
2808
			#$result["argus"],解析好的參數陣列.
2809
			#$result["argu"],所使用的參數.
2810
			#必填參數
2811
			#$conf["cmdStr"],字串,要解析的指令字串
2812
			$conf["cmd::parseCmdString"]["cmdStr"]=$conf["command"];
2813
			#可省略參數:
2814
			#無.
2815
			#參考資料:
2816
			#無.
2817
			#備註:
2818
			#無.
2819
			$parseCmdString=cmd::parseCmdString($conf["cmd::parseCmdString"]);
2820
			unset($conf["cmd::parseCmdString"]);
2821
 
852 liveuser 2822
			#debug
855 liveuser 2823
			var_dump(__LINE__,$parseCmdString);
852 liveuser 2824
 
851 liveuser 2825
			#如果執行失敗
2826
			if($parseCmdString["status"]==="false"){
2827
 
2828
				#設置執行失敗
2829
				$result["status"]="false";
2830
 
2831
				#設置錯誤訊息
2832
				$result["error"]=$parseCmdString;
2833
 
2834
				#回傳結果
2835
				return $result;
2836
 
2837
				}#if end
2838
 
2839
			#取得解析好的指令名稱
2840
			$conf["command"]=$parseCmdString["cmd"];
2841
 
2842
			#取得解析好的參數陣列
2843
			$conf["argu"]=$parseCmdString["argus"];
2844
 
852 liveuser 2845
			#debug
2846
			#var_dump(__LINE__,$parseCmdString);
2847
 
851 liveuser 2848
			}#if end
2849
 
527 liveuser 2850
		#函式說明:
2851
		#呼叫shell執行系統命令,並取得回傳的內容.
2852
		#回傳結果:
2853
		#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
2854
		#$result["error"],錯誤訊息陣列.
2855
		#$result["function"],當前執行的函數名稱.
2856
		#$result["argu"],使用的參數.
2857
		#$result["cmd"],執行的指令內容.
2858
		#$result["fullCmd"],如果參數 $conf["inBackGround"] 為 "true" 則會回傳該值.
2859
		#$result["output"],爲執行完二元碼後的輸出陣列,若 $conf["inBackGround"] 為 "true",則為當下的輸出.
2860
		#$result["tmpFileOutput"],儲存輸出的暫存檔案名稱,若 $conf["inBackGround"] 為 "true" 則會回傳該值.
2861
		#$result["running"],是否還在執行.
2862
		#$result["pid"],pid.
2863
		#$result["statusCode"],執行結束後的代碼.
2864
		#$result["escape"],陣列,儲存重新排序過且已經escape過的指令(key為"cmd")與參數(key為"argu").
2865
		#必填參數:
2866
		#$conf["command"],字串,要執行的指令.
2867
		$conf["external::callShell"]["command"]=$conf["command"];
2868
		#$conf["fileArgu"],字串,變數__FILE__的內容.
2869
		$conf["external::callShell"]["fileArgu"]=$conf["fileArgu"];
2870
		#可省略參數:
2871
		#$conf["argu"],陣列字串,指令搭配的參數,預設為空陣列.
2872
		$conf["external::callShell"]["argu"]=$conf["argu"];
2873
		#$conf["arguIsAddr"],陣列字串,指令搭配的哪些參數為路徑,為路徑的參數會進行轉換以便符合呼叫當前函數的位置,預設不指定,若有3個參數,其中第3個參數為路徑,則表示為array("false","false","true").
2874
		#$conf["arguIsAddr"]=array();
2875
		#$conf["pre"],陣列,要在本指令前執行的每個指令與參數.
2876
		#$conf["pre"][$i]["cmd"],字串,要在本指令前執行的第$i+1個指令.
2877
		#$conf["pre"][$i]["param"],陣列字串,要在本指令前執行的第$i+1個指令的參數.
2878
		#$conf["enablePrintDescription"],字串,是否要印出$conf["printDescription"]的內容,"true"代表要,"false"代表不要,預設為"false".
2879
		#$conf["enablePrintDescription"]="true";
2880
		#$conf["printDescription"],字串,執行該外部程式前要印出來的的文字,預設為$conf["command"]的內容加上使用的$conf["argu"]參數.
2881
		#$conf["printDescription"]="";
2882
		#$conf["escapeshellarg"],字串,是否要啟用過濾參數,用了比較安全,但可能會出錯,"true"為啟用,"false"為不啟用,預設為"false".如果參數為"< 、<< 、> 、>> 、| 、2>&1"之一則不會過濾.
2883
		$conf["external::callShell"]["escapeshellarg"]="true";
2884
		#$conf["thereIsShellVar"],陣列字串,指令搭配的參數"argu",若含有「\'」,則取代為「"」.每個argu參數都要有對應的元素."true"代表要置換.
2885
		#$conf["thereIsShellVar"]=array();
2886
		#$conf["username"],字串,要用什麼使用者來執行,預設為執行php的使用者,該參數不適用於apache環境.
2887
		#$conf["username"]="";
2888
		#$conf["password"],字串,root的使用者密碼,預設不使用密碼,該參數不適用於apache環境.
2889
		#$conf["password"]="";
2890
		#$conf["useScript"],字串,是否要啟用Linux的script指令來記錄輸出,"true"代表要,Fedora的selinux會擋住該操作;"false"代表不要,預設為"false".
2891
		#$conf["useScript"]="";
2892
		#$conf["logFilePath"],字串,當 $conf["useScript"] 為 "true" 時,輸出的內容要暫存到哪裡,預設為 "/tmp/.qbpwcf_tmp/external/callShell/".
2893
		#$conf["logFilePath"]=".qbpwcf_tmp/external/callShell/";
2894
		#$conf["inBackGround"],字串,是否要在背景執行,且不會等待程式執行結束再執行下一個指令,"true"代表是,"false"代表不要,預設為"false",如果$conf["command"]有用「;」區隔的多個指令將會出錯.
2895
		#$conf["inBackGround"]="";
2896
		#$conf["getErr"],字串,"true"代表將錯誤輸出變成標準輸出,反之"false"為不變動.
2897
		#$conf["getErr"]="false";
2898
		#$conf["doNotRun"],字串,"true"代表不執行指令,預設為"false"會執行指令.
2899
		$conf["external::callShell"]["doNotRun"]="true";
2900
		#參考資料:
2901
		#exec=>http://php.net/manual/en/function.exec.php
2902
		#escapeshellcmd=>http://php.net/manual/en/function.escapeshellcmd.php
2903
		#escapeshellarg=>http://php.net/manual/en/function.escapeshellarg.php
2904
		#備註:
2905
		#不是所有指令都能用apache的身份執行,目前已知java,javac指令無法執行,使用root身份可能會被selinux阻擋.
2906
		#若使用的 command、argu 參數,含有 ~ 則會被視為字串,若有需要其於 shell 中代表的家目錄位置,可用 fileAccess::tildeToPath 來進行轉換.
2907
		$callShell=external::callShell($conf["external::callShell"]);
2908
		unset($conf["external::callShell"]);
2909
 
852 liveuser 2910
		#debug
855 liveuser 2911
		var_dump(__LINE__,$callShell);
852 liveuser 2912
 
527 liveuser 2913
		#如果檢查參數作業出錯
2914
		if($callShell["status"]=="false"){
2915
 
2916
			#設置執行錯誤識別
2917
			$result["status"]="false";
2918
 
2919
			#設置錯誤訊息
2920
			$result["error"]=$callShell;
2921
 
2922
			#回傳結果
2923
			return $result;
2924
 
2925
			}#if end
2926
 
2927
		#函式說明:
2928
		#連線到 unixDomainSockServer 提供的 unix domain socket.
2929
		#回傳結果:
2930
		#$result["status"],"true"代表執行正常;"false"代表執行不正常.
2931
		#$result["error"],錯誤訊息陣列.
2932
		#$result["function"],當前執行的函式名稱.
2933
		#$result["content"],取得的回應.
2934
		#必填參數:
2935
		#$conf["sock"],字串,要連線的unix domain socket.
2936
		$conf["sock::unixDomainSockClient"]["sock"]=$conf["sock"];
2937
		#可省略參數:
2938
		#$conf["id"],字串,取得的id,若無此值,則會得到新的數值.
2939
		#$conf["id"]="";
2940
		#$conf["cmd"],字串,要執行的指令,當$conf["id"]參數合法時,才會執行.
2941
		$conf["sock::unixDomainSockClient"]["cmd"]=$callShell["escape"]["cmd"];
2942
		#$conf["param"],參數陣列.
2943
		$conf["sock::unixDomainSockClient"]["param"]=$callShell["escape"]["argu"];
2944
		#$conf["escaped"],字串,param參數是否已經escaped了,預設為"false",反之為"true".
2945
		$conf["sock::unixDomainSockClient"]["escaped"]="true";
851 liveuser 2946
		#$conf["custom"],陣列,要客制化傳輸的內容,會覆蓋以上除了$conf["id"]以外的可省略參數.
2947
 
2948
		#如果要在背景執行指令
2949
		if($conf["commandInBg"]==="true" && isset($conf["sock::unixDomainSockClient"]["cmd"]) ){
2950
 
2951
			#設定要在背景執行的指令
852 liveuser 2952
			$conf["sock::unixDomainSockClient"]["custom"]["cmdInBg"]=$conf["sock::unixDomainSockClient"]["cmd"];
851 liveuser 2953
 
852 liveuser 2954
			#設定要在背景執行的指令
854 liveuser 2955
			$conf["sock::unixDomainSockClient"]["custom"]["param"]=$conf["sock::unixDomainSockClient"]["param"];
852 liveuser 2956
 
851 liveuser 2957
			#移除不要的參數
852 liveuser 2958
			unset($conf["sock::unixDomainSockClient"]["cmd"]);
2959
 
2960
			#移除不要的參數
2961
			unset($conf["sock::unixDomainSockClient"]["param"]);
2962
 
2963
			#保存 custom 參數
2964
			$custom=$conf["sock::unixDomainSockClient"]["custom"];
851 liveuser 2965
 
852 liveuser 2966
			#debug
2967
			#var_dump(__LINE__,$custom);
2968
 
851 liveuser 2969
			}#if end
2970
 
2971
		#$conf["raw"],字串,要直接傳送的字串內容,會忽略其他可省略參數.
2972
		#$conf["raw"]="";
527 liveuser 2973
		#參考資料:
2974
		#http://php.net/manual/en/function.stream-socket-client.php
2975
		#http://php.net/manual/en/function.stream-get-contents.php
2976
		#備註:
2977
		#無.
2978
		$paramsOfUnixDomainSockClient=$conf["sock::unixDomainSockClient"];
852 liveuser 2979
		$unixDomainSockClient=sock::unixDomainSockClient($paramsOfUnixDomainSockClient);
2980
		unset($paramsOfUnixDomainSockClient);
527 liveuser 2981
 
2982
		#如果執行失敗
2983
		if($unixDomainSockClient["status"]==="false"){
2984
 
2985
			#設置執行錯誤識別
2986
			$result["status"]="false";
2987
 
2988
			#設置錯誤訊息
2989
			$result["error"]=$unixDomainSockClient;
2990
 
2991
			#回傳結果
2992
			return $result;
2993
 
2994
			}#if end
2995
 
852 liveuser 2996
		#debug
2997
		#var_dump(__LINE__,$unixDomainSockClient);
2998
 
2999
		#如果不是 json 字串
3000
		if(json_validate(trim($unixDomainSockClient["content"]))==="false"){
3001
 
3002
			#設置執行錯誤識別
3003
			$result["status"]="false";
3004
 
3005
			#設置錯誤訊息
3006
			$result["error"][]=trim($unixDomainSockClient["content"])." is not json string!";
3007
 
3008
			#設置錯誤訊息
3009
			$result["error"][]=$unixDomainSockClient;
3010
 
3011
			#回傳結果
3012
			return $result;
3013
 
3014
			}#if end
3015
 
527 liveuser 3016
		#取得json回應
852 liveuser 3017
		$jsonRes=json_decode(trim($unixDomainSockClient["content"]));
527 liveuser 3018
 
852 liveuser 3019
		#debug
3020
		#var_dump(__LINE__,$jsonRes);
3021
 
527 liveuser 3022
		#如果執行失敗
3023
		if($jsonRes===null){
3024
 
3025
			#設置執行錯誤識別
3026
			$result["status"]="false";
3027
 
3028
			#設置錯誤訊息
3029
			$result["error"]=$unixDomainSockClient;
3030
 
3031
			#回傳結果
3032
			return $result;
3033
 
3034
			}#if end
3035
 
3036
		#如果沒有產生新id
3037
		if(!isset($jsonRes->id)){
3038
 
3039
			#設置執行錯誤識別
3040
			$result["status"]="false";
3041
 
3042
			#設置錯誤訊息
3043
			$result["error"]=$unixDomainSockClient;
3044
 
3045
			#回傳結果
3046
			return $result;
3047
 
3048
			}#if end
3049
 
3050
		#用新的id再傳送一次要求給 qbpwcf_usock_path
852 liveuser 3051
		$paramsOfUnixDomainSockClient=$conf["sock::unixDomainSockClient"];
3052
		$paramsOfUnixDomainSockClient["id"]=$jsonRes->id;
3053
		#var_dump(__LINE__,$paramsOfUnixDomainSockClient);
527 liveuser 3054
		$unixDomainSockClient=sock::unixDomainSockClient($paramsOfUnixDomainSockClient);
3055
		unset($paramsOfUnixDomainSockClient);
3056
 
3057
		#如果執行失敗
3058
		if($unixDomainSockClient["status"]==="false"){
3059
 
3060
			#設置執行錯誤識別
3061
			$result["status"]="false";
3062
 
3063
			#設置錯誤訊息
3064
			$result["error"]=$unixDomainSockClient;
3065
 
3066
			#回傳結果
3067
			return $result;
3068
 
3069
			}#if end
3070
 
852 liveuser 3071
		#debug
3072
		#var_dump(__LINE__,$unixDomainSockClient["content"]);
3073
 
3074
		#如果輸出非 json 
3075
		if(json_validate(trim($unixDomainSockClient["content"]))===false){
3076
 
3077
			#設置錯誤識別
3078
			$result["status"]="false";
3079
 
3080
			#設置錯誤訊息
3081
			$result["error"][]="got not json output";
3082
 
3083
			#設置錯誤訊息
3084
			$result["error"][]=json_last_error().":".json_last_error_msg();
3085
 
3086
			#回傳結果
3087
			return $result;
3088
 
3089
			}#if end
3090
 
527 liveuser 3091
		#取得json回應
3092
		$jsonRes=(array)json_decode($unixDomainSockClient["content"]);
3093
 
3094
		#如果執行失敗
3095
		if($jsonRes===null){
3096
 
3097
			#設置執行錯誤識別
3098
			$result["status"]="false";
3099
 
3100
			#設置錯誤訊息
3101
			$result["error"]=$unixDomainSockClient;
3102
 
3103
			#回傳結果
3104
			return $result;
3105
 
3106
			}#if end
3107
 
3108
		#如果執行指令失敗
3109
		if($jsonRes["status"]==="false"){
3110
 
3111
			#設置執行錯誤識別
3112
			$result["status"]="false";
3113
 
3114
			#設置錯誤訊息
3115
			$result["error"]=$jsonRes["error"];
3116
 
3117
			#回傳結果
3118
			return $result;
3119
 
3120
			}#if end
3121
 
3122
		#執行正常
3123
		$result["status"]="true";
3124
 
3125
		#設置執行的結果
852 liveuser 3126
		$result["content"]=$jsonRes;
527 liveuser 3127
 
3128
		#回傳結果
3129
		return $result;
3130
 
3131
		}#public function execAnyCmdByQBPWCFunixSocket end
3132
 
1 liveuser 3133
	/*
854 liveuser 3134
	#函式說明:
3135
	#詢問透過 sock::unixDomainSockServer 執行的程序狀況
724 liveuser 3136
	#回傳結果:
3137
	#$result["status"],"true"代表執行正常;"false"代表執行不正常.
3138
	#$result["error"],錯誤訊息陣列.
3139
	#$result["function"],當前執行的函式名稱.
3140
	#$result["argu"],使用的參數.
854 liveuser 3141
	#$result["content"],陣列,程序的資訊.
3142
	#$result["content"]["pid"],字串,程序的pid.
3143
	#$result["content"]["running"],字串,是否正常執行中.
3144
	#$result["content"]["statusCode"],字串,回傳給 shell 的代碼.
3145
	#$result["content"]["input"],字串,輸入的內容.
3146
	#$result["content"]["output"],字串,標準輸出的內容.
3147
	#$result["content"]["error"],字串,錯誤輸出的內容.
3148
	#必填參數:
3149
	#$conf["uuid"],字串,proc的uuid.
3150
	$conf["uuid"]="";
3151
	#可省略參數:
3152
	#$conf["sock"],字串,要連線的 usr/bin/qbpwcf-sock.php(sock::unixDomainSockServer) 所產生的 unix domain socket 路徑與名稱,預設為 qbpwcf_usock_path.
3153
	#$conf["sock"]=qbpwcf_usock_path;
3154
	#參考資料:
3155
	#無.
3156
	#備註:
3157
	#無.
3158
	*/
3159
	public static function getProcInfo(&$conf){
3160
 
3161
		#初始化要回傳的結果
3162
		$result=array();
3163
 
3164
		#取得當前執行的函數名稱
3165
		$result["function"]=__FUNCTION__;
3166
 
3167
		#如果沒有參數
3168
		if(func_num_args()==0){
3169
 
3170
			#設置執行失敗
3171
			$result["status"]="false";
3172
 
3173
			#設置執行錯誤訊息
3174
			$result["error"]="函數".$result["function"]."需要參數";
3175
 
3176
			#回傳結果
3177
			return $result;
3178
 
3179
			}#if end
3180
 
3181
		#取得參數
3182
		$result["argu"]=$conf;
3183
 
3184
		#如果 $conf 不為陣列
3185
		if(gettype($conf)!="array"){
3186
 
3187
			#設置執行失敗
3188
			$result["status"]="false";
3189
 
3190
			#設置執行錯誤訊息
3191
			$result["error"][]="\$conf變數須為陣列形態";
3192
 
3193
			#如果傳入的參數為 null
3194
			if($conf==null){
3195
 
3196
				#設置執行錯誤訊息
3197
				$result["error"][]="\$conf變數不得為null,請檢查函數「".$result["function"]."」的參數設置有無正確!";
3198
 
3199
				}#if end
3200
 
3201
			#回傳結果
3202
			return $result;
3203
 
3204
			}#if end
3205
 
3206
		#檢查參數
3207
		#函式說明:
3208
		#檢查必填與可省略的參數,可省略參數可指定預設要給與什麼數值內容。
3209
		#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
3210
		#$reuslt["error"],執行不正常結束的錯訊息陣列.
3211
		#$result["function"],當前執行的函式名稱.
3212
		#$result["argu"],設置給予的參數.
3213
		#$result["passed"],識別要檢查的全體變數是否存在以及型態是否正確的變數,"true"代表檢查全部通過;"false"代表檢查不通過
3214
		#$result[$shouldBeCheckedVarName]["varExist"],所檢查的變數是否存在,"false"代表不存在;"true"代表存在
3215
		#$result[$shouldBeCheckedVarName]["varType"],所檢查的變數型態是否正確,"false"代表錯誤;"true"代表正確
3216
		#$result[$shouldBeCheckedVarName]["error"],每個參數設定的錯誤訊息
3217
		#$result["shouldNotBeEmpty"],不應該為空字串或控陣列的變數.
3218
		#$result["argu"],字串陣列,目前輸入的參數名稱陣列.
3219
		#$result["legalVarName"],字串陣列,合法可用的參數名稱陣列.
3220
		#$result["notNeedVar"],字串陣列,多餘的參數名稱.
3221
		#必填寫的參數:
3222
		#$conf["varInput"],陣列變數,要檢查的陣列變數,請在要檢查的參數前面加上&,這樣變動的結果才能被套用。
3223
		$conf["variableCheck::checkArguments"]["varInput"]=&$conf;	
3224
		#$conf["referenceVarKey"],字串,$conf參數後面的key值,用於移除不要的參考陣列.
3225
		$conf["variableCheck::checkArguments"]["referenceVarKey"]="variableCheck::checkArguments";
3226
		#可以省略的參數:
3227
		#$conf["mustBeFilledVariableName"],爲必填參數的變數名稱陣列,形態爲陣列變數,元素數量需要跟"mustBeFilledVariableType"參數的元素數量一致,例如: $conf["mustBeFilledVariableName"] = array("id","account","password");
3228
		$conf["variableCheck::checkArguments"]["mustBeFilledVariableName"]=array("uuid");
3229
		#$conf["mustBeFilledVariableType"],爲必填參數的變數陣列應該爲何種變數形態,形態爲陣列,元素數量需要跟"mustBeFilledVariableName"參數的元素數量一致,例如: $conf["mustBeFilledVariableType"] = array("string",integer,"double","resource","object"); , null代表不指定變數形態.
3230
		$conf["variableCheck::checkArguments"]["mustBeFilledVariableType"]=array("string");
3231
		#$conf["canBeEmptyString"],字串,必填變數內容如果是空字串就不能算是有設置的話,請設為"false",預設爲"true",可以為空字串.
3232
		#$conf["canBeEmptyString"]="false";
3233
		#$conf["canNotBeEmpty"],字串陣列,哪些必填參數的內容不得為空字串或空陣列,僅當$conf["canBeEmptyString"]為"true"時會生效.
3234
		#$conf["canNotBeEmpty"]=array();
3235
		#$conf["canBeEmpty"],字串陣列,哪些必填參數的內容可為空字串或空陣列,僅當$conf["canBeEmptyString"]為"false"時會生效.
3236
		#$conf["canBeEmpty"]=array();
3237
		#$conf["skipableVariableCanNotBeEmpty"],字串陣列,哪些可省略參數不可以為空字串或空陣列.
3238
		$conf["variableCheck::checkArguments"]["skipableVariableCanNotBeEmpty"]=array("sock");
3239
		#$conf["skipableVariableName"],陣列字串,爲可省略參數的變數名稱陣列,形態爲陣列變數,例如: $conf["skipableVariableName"] = array("id","account","password");
3240
		$conf["variableCheck::checkArguments"]["skipableVariableName"]=array("sock");
3241
		#$conf["skipableVariableType"],陣列字串,爲可省略參數的變數名稱陣列,形態爲陣列變數,例如: $conf["skipableVariableType"] = array("string",integer,"double"); 
3242
		$conf["variableCheck::checkArguments"]["skipableVariableType"]=array("string");
3243
		#$conf["skipableVarDefaultValue"],字串陣列,每個不存在的可省略變數要初始化為什麼,null與代表不指定,若預設值是參數之一,請將$conf["mustBeFilledVar"]改成"\$conf["\mustBeFilledVar\"]".
3244
		$conf["variableCheck::checkArguments"]["skipableVarDefaultValue"]=array(qbpwcf_usock_path);
3245
		#$conf["disallowAllSkipableVarIsEmpty"],字串,是否允許每個可省略參數都為空字串,預設為"true"允許,反之為"false".
3246
		#$conf["disallowAllSkipableVarIsEmpty"]="";
3247
		#$conf["disallowAllSkipableVarIsEmptyArray"],字串,是否允許每個可省略參數都為空陣列,預設為"true"允許,反之為"false".
3248
		#$conf["disallowAllSkipableVarIsEmptyArray"]="";
3249
		#$conf["arrayCountEqualCheck"],字串陣列,為檢查哪些陣列參數的元素數量要一樣,$conf["arrayCountEqualCheck"][$i]=array()為第$i組key為哪些的變數其元素數量要相等.
3250
		#$conf["arrayCountEqualCheck"][]=array();
3251
		#參考資料來源:
3252
		#array_keys=>http://php.net/manual/en/function.array-keys.php
3253
		$checkArguments=variableCheck::checkArguments($conf["variableCheck::checkArguments"]);
3254
		unset($conf["variableCheck::checkArguments"]);
3255
 
3256
		#如果檢查參數失敗
3257
		if($checkArguments["status"]==="false"){
3258
 
3259
			#設置執行失敗
3260
			$result["status"]="false";
3261
 
3262
			#設置錯誤訊息
3263
			$result["error"]=$checkArguments;
3264
 
3265
			#回傳結果
3266
			return $result;
3267
 
3268
			}#if end
3269
 
3270
		#如果檢查參數不通過
3271
		if($checkArguments["passed"]==="false"){
3272
 
3273
			#設置執行失敗
3274
			$result["status"]="false";
3275
 
3276
			#設置錯誤訊息
3277
			$result["error"]=$checkArguments;
3278
 
3279
			#回傳結果
3280
			return $result;
3281
 
3282
			}#if end
3283
 
3284
		函式說明:
3285
		#連線到 unixDomainSockServer 提供的 unix domain socket.
3286
		#回傳結果:
3287
		#$result["status"],"true"代表執行正常;"false"代表執行不正常.
3288
		#$result["error"],錯誤訊息陣列.
3289
		#$result["function"],當前執行的函式名稱.
3290
		#$result["content"],取得的回應.
3291
		#必填參數:
3292
		#$conf["sock"],字串,要連線的unix domain socket.
3293
		$conf["sock::unixDomainSockClient"]["sock"]=$conf["sock"];
3294
		#可省略參數:
3295
		#$conf["id"],字串,取得的id,若無此值,則會得到新的數值.
3296
		#$conf["id"]="";
3297
		#$conf["cmd"],字串,要執行的指令,當$conf["id"]參數合法時,才會執行.
3298
		#$conf["cmd"]="";
3299
		#$conf["param"],參數陣列.
3300
		#$conf["param"]=array();
3301
		#$conf["escaped"],字串,param參數是否已經escaped了,預設為"false",反之為"true".
3302
		#$conf["escaped"]="true";
3303
		#$conf["custom"],陣列,要客制化傳輸的內容,會覆蓋以上除了$conf["id"]以外的可省略參數.
3304
		$conf["sock::unixDomainSockClient"]["custom"]=array("QueryProcByUUID"=>$conf["uuid"]);
3305
		#$conf["raw"],字串,要直接傳送的字串內容,會忽略其他可省略參數.
3306
		#$conf["raw"]="";
3307
		#參考資料:
3308
		#http://php.net/manual/en/function.stream-socket-client.php
3309
		#http://php.net/manual/en/function.stream-get-contents.php
3310
		#備註:
3311
		#無.
3312
		$paramsOfUnixDomainSockClient=$conf["sock::unixDomainSockClient"];
3313
		$unixDomainSockClient=sock::unixDomainSockClient($paramsOfUnixDomainSockClient);
3314
		unset($paramsOfUnixDomainSockClient);
3315
 
3316
		#如果執行失敗
3317
		if($unixDomainSockClient["status"]==="false"){
3318
 
3319
			#設置執行錯誤識別
3320
			$result["status"]="false";
3321
 
3322
			#設置錯誤訊息
3323
			$result["error"]=$unixDomainSockClient;
3324
 
3325
			#回傳結果
3326
			return $result;
3327
 
3328
			}#if end
3329
 
3330
		#debug
3331
		#var_dump(__LINE__,$unixDomainSockClient);
3332
 
3333
		#如果不是 json 字串
3334
		if(json_validate(trim($unixDomainSockClient["content"]))==="false"){
3335
 
3336
			#設置執行錯誤識別
3337
			$result["status"]="false";
3338
 
3339
			#設置錯誤訊息
3340
			$result["error"][]=trim($unixDomainSockClient["content"])." is not json string!";
3341
 
3342
			#設置錯誤訊息
3343
			$result["error"][]=$unixDomainSockClient;
3344
 
3345
			#回傳結果
3346
			return $result;
3347
 
3348
			}#if end
3349
 
3350
		#取得json回應
3351
		$jsonRes=json_decode(trim($unixDomainSockClient["content"]));
3352
 
3353
		#debug
3354
		#var_dump(__LINE__,$jsonRes);
3355
 
3356
		#如果執行失敗
3357
		if($jsonRes===null){
3358
 
3359
			#設置執行錯誤識別
3360
			$result["status"]="false";
3361
 
3362
			#設置錯誤訊息
3363
			$result["error"]=$unixDomainSockClient;
3364
 
3365
			#回傳結果
3366
			return $result;
3367
 
3368
			}#if end
3369
 
3370
		#如果沒有產生新id
3371
		if(!isset($jsonRes->id)){
3372
 
3373
			#設置執行錯誤識別
3374
			$result["status"]="false";
3375
 
3376
			#設置錯誤訊息
3377
			$result["error"]=$unixDomainSockClient;
3378
 
3379
			#回傳結果
3380
			return $result;
3381
 
3382
			}#if end
3383
 
3384
		#用新的id再傳送一次要求給 qbpwcf_usock_path
3385
		$paramsOfUnixDomainSockClient=$conf["sock::unixDomainSockClient"];
3386
		$paramsOfUnixDomainSockClient["id"]=$jsonRes->id;
3387
		$unixDomainSockClient=sock::unixDomainSockClient($paramsOfUnixDomainSockClient);
3388
		unset($paramsOfUnixDomainSockClient);
3389
 
3390
		#如果執行失敗
3391
		if($unixDomainSockClient["status"]==="false"){
3392
 
3393
			#設置執行錯誤識別
3394
			$result["status"]="false";
3395
 
3396
			#設置錯誤訊息
3397
			$result["error"]=$unixDomainSockClient;
3398
 
3399
			#回傳結果
3400
			return $result;
3401
 
3402
			}#if end
3403
 
3404
		#debug
3405
		#var_dump(__LINE__,$unixDomainSockClient["content"]);
3406
 
3407
		#如果輸出非 json 
3408
		if(json_validate(trim($unixDomainSockClient["content"]))===false){
3409
 
3410
			#設置錯誤識別
3411
			$result["status"]="false";
3412
 
3413
			#設置錯誤訊息
3414
			$result["error"][]="got not json output";
3415
 
3416
			#設置錯誤訊息
3417
			$result["error"][]=json_last_error().":".json_last_error_msg();
3418
 
3419
			#設置原始訊息
3420
			$result["error"][]="ori res:".$unixDomainSockClient["content"];
3421
 
3422
			#回傳結果
3423
			return $result;
3424
 
3425
			}#if end
3426
 
3427
		#取得json回應
3428
		$jsonRes=(array)json_decode($unixDomainSockClient["content"]);
3429
 
3430
		#如果執行失敗
3431
		if($jsonRes===null){
3432
 
3433
			#設置執行錯誤識別
3434
			$result["status"]="false";
3435
 
3436
			#設置錯誤訊息
3437
			$result["error"]=$unixDomainSockClient;
3438
 
3439
			#回傳結果
3440
			return $result;
3441
 
3442
			}#if end
3443
 
3444
		#如果執行指令失敗
3445
		if($jsonRes["status"]==="false"){
3446
 
3447
			#設置執行錯誤識別
3448
			$result["status"]="false";
3449
 
3450
			#設置錯誤訊息
3451
			$result["error"]=$jsonRes["error"];
3452
 
3453
			#回傳結果
3454
			return $result;
3455
 
3456
			}#if end
3457
 
3458
		#移除不需要的元素
3459
		unset($jsonRes["status"]);
3460
 
3461
		#執行正常
3462
		$result["status"]="true";
3463
 
3464
		#$result["content"],陣列,程序的資訊.
3465
		#$result["content"]["pid"],字串,程序的pid.
3466
		#$result["content"]["running"],字串,是否正常執行中.
3467
		#$result["content"]["statusCode"],字串,回傳給 shell 的代碼.
3468
		#$result["content"]["input"],字串,輸入的內容.
3469
		#$result["content"]["output"],字串,標準輸出的內容.
3470
		#$result["content"]["error"],字串,錯誤輸出的內容.
3471
 
3472
		#初始執行的結果
3473
		$result["content"]=$jsonRes;
3474
 
3475
		#回傳結果
3476
		return $result;
3477
 
3478
		}#function getProcInfo end
3479
 
3480
	/*
3481
	#函式說明:
3482
	#傳送 raw 訊息到  unix domain socket.
3483
	#回傳結果:
3484
	#$result["status"],"true"代表執行正常;"false"代表執行不正常.
3485
	#$result["error"],錯誤訊息陣列.
3486
	#$result["function"],當前執行的函式名稱.
3487
	#$result["argu"],使用的參數.
724 liveuser 3488
	#$result["content"],得到的回應.
3489
	#必填參數:
3490
	#$conf["msg"],字串,要傳送的訊息.
3491
	$conf["msg"]="";
854 liveuser 3492
	#$conf["sock"],字串,要連線的的 unix domain socket 路徑與名稱
724 liveuser 3493
	#$conf["sock"]="";
3494
	#可省略參數:
3495
	#無.
3496
	#參考資料:
3497
	#無.
3498
	#備註:
3499
	#無.
3500
	*/
3501
	public static function sendRawMsgUnixSocket(&$conf){
3502
 
3503
		#初始化要回傳的結果
3504
		$result=array();
3505
 
3506
		#取得當前執行的函數名稱
3507
		$result["function"]=__FUNCTION__;
3508
 
3509
		#如果沒有參數
3510
		if(func_num_args()==0){
3511
 
3512
			#設置執行失敗
3513
			$result["status"]="false";
3514
 
3515
			#設置執行錯誤訊息
3516
			$result["error"]="函數".$result["function"]."需要參數";
3517
 
3518
			#回傳結果
3519
			return $result;
3520
 
3521
			}#if end
3522
 
3523
		#取得參數
3524
		$result["argu"]=$conf;
3525
 
3526
		#如果 $conf 不為陣列
3527
		if(gettype($conf)!="array"){
3528
 
3529
			#設置執行失敗
3530
			$result["status"]="false";
3531
 
3532
			#設置執行錯誤訊息
3533
			$result["error"][]="\$conf變數須為陣列形態";
3534
 
3535
			#如果傳入的參數為 null
3536
			if($conf==null){
3537
 
3538
				#設置執行錯誤訊息
3539
				$result["error"][]="\$conf變數不得為null,請檢查函數「".$result["function"]."」的參數設置有無正確!";
3540
 
3541
				}#if end
3542
 
3543
			#回傳結果
3544
			return $result;
3545
 
3546
			}#if end
3547
 
3548
		#函式說明:
3549
		#檢查必填與可省略的參數,可省略參數可指定預設要給與什麼數值內容.
3550
		#回傳結果:
3551
		#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
3552
		#$result["error"],執行不正常結束的錯訊息陣列.
3553
		#$result["simpleError"],簡單表示的錯誤訊息.
3554
		#$result["function"],當前執行的函式名稱.
3555
		#$result["argu"],設置給予的參數.
3556
		#$result["passed"],識別要檢查的全體變數是否存在以及型態是否正確的變數,"true"代表檢查全部通過;"false"代表檢查不通過
3557
		#$result[$shouldBeCheckedVarName]["varExist"],所檢查的變數是否存在,"false"代表不存在;"true"代表存在
3558
		#$result[$shouldBeCheckedVarName]["varType"],所檢查的變數型態是否正確,"false"代表錯誤;"true"代表正確
3559
		#$result[$shouldBeCheckedVarName]["error"],每個參數設定的錯誤訊息
3560
		#$result["shouldNotBeEmpty"],不應該為空字串或控陣列的變數.
3561
		#$result["argu"],字串陣列,目前輸入的參數名稱陣列.
3562
		#$result["legalVarName"],字串陣列,合法可用的參數名稱陣列.
3563
		#$result["notNeedVar"],字串陣列,多餘的參數名稱.
3564
		#必填參數:
3565
		#$conf["varInput"],陣列變數,要檢查的陣列變數,請在要檢查的參數前面加上&,這樣變動的結果才能被套用。
3566
		$conf["variableCheck::checkArguments"]["varInput"]=&$conf;
3567
		#$conf["referenceVarKey"],字串,$conf參數後面的key值,用於移除不要的參考陣列.
3568
		$conf["variableCheck::checkArguments"]["referenceVarKey"]="variableCheck::checkArguments";
3569
		#可省略參數:
3570
		#$conf["mustBeFilledVariableName"],爲必填參數的變數名稱陣列,形態爲陣列變數,元素數量需要跟"mustBeFilledVariableType"參數的元素數量一致,例如: $conf["mustBeFilledVariableName"] = array("id","account","password");
3571
		$conf["variableCheck::checkArguments"]["mustBeFilledVariableName"]=array("msg","sock");
3572
		#$conf["mustBeFilledVariableType"],爲必填參數的變數陣列應該爲何種變數形態,形態爲陣列,元素數量需要跟"mustBeFilledVariableName"參數的元素數量一致,例如: $conf["mustBeFilledVariableType"] = array("string",integer,"double","resource","object"); , null代表不指定變數形態.
3573
		$conf["variableCheck::checkArguments"]["mustBeFilledVariableType"]=array("string","string");
3574
		#$conf["canBeEmptyString"],字串,必填變數內容如果是空字串就不能算是有設置的話,請設為"false",預設爲"true",可以為空字串.
3575
		#$conf["canBeEmptyString"]="false";
3576
		#$conf["canNotBeEmpty"],字串陣列,哪些必填參數的內容不得為空字串或空陣列,僅當$conf["canBeEmptyString"]為"true"時會生效.
3577
		#$conf["canNotBeEmpty"]=array();
3578
		#$conf["canBeEmpty"],字串陣列,哪些必填參數的內容可為空字串或空陣列,僅當$conf["canBeEmptyString"]為"false"時會生效.
3579
		#$conf["canBeEmpty"]=array();
3580
		#$conf["skipableVariableCanNotBeEmpty"],字串陣列,哪些可省略參數不可以為空字串或空陣列.
3581
		#$conf["variableCheck::checkArguments"]["skipableVariableCanNotBeEmpty"]=array("sock");
3582
		#$conf["skipableVariableName"],陣列字串,爲可省略參數的變數名稱陣列,形態爲陣列變數,例如: $conf["skipableVariableName"] = array("id","account","password");
3583
		#$conf["variableCheck::checkArguments"]["skipableVariableName"]=array("sock");
3584
		#$conf["skipableVariableType"],陣列字串,爲可省略參數的變數名稱陣列,形態爲陣列變數,例如: $conf["skipableVariableType"] = array("string",integer,"double");
3585
		#$conf["variableCheck::checkArguments"]["skipableVariableType"]=array("string");
3586
		#$conf["skipableVarDefaultValue"],字串陣列,每個不存在的可省略變數要初始化為什麼,null與代表不指定,若預設值是參數之一,請將$conf["mustBeFilledVar"]改成"\$conf["\mustBeFilledVar\"]".
3587
		#$conf["variableCheck::checkArguments"]["skipableVarDefaultValue"]=array(qbpwcf_usock_path);
3588
		#$conf["disallowAllSkipableVarIsEmpty"],字串,是否允許每個可省略參數都為空字串,預設為"true"允許,反之為"false".
3589
		#$conf["disallowAllSkipableVarIsEmpty"]="";
3590
		#$conf["disallowAllSkipableVarIsEmptyArray"],字串,是否允許每個可省略參數都為空陣列,預設為"true"允許,反之為"false".
3591
		#$conf["disallowAllSkipableVarIsEmptyArray"]="";
3592
		#$conf["disallowAllSkipableVarNotExist"],字串,是否不允許每個可省略參數都不存在,預設為"false"代表允許,反之為"true".
3593
		#$conf["disallowAllSkipableVarNotExist"]="";
3594
		#$conf["arrayCountEqualCheck"],字串陣列,為檢查哪些陣列參數的元素數量要一樣,$conf["arrayCountEqualCheck"][$i]=array()為第$i組key為哪些的變數其元素數量要相等.
3595
		#$conf["arrayCountEqualCheck"][]=array();
3596
		#參考資料:
3597
		#array_keys=>http://php.net/manual/en/function.array-keys.php
3598
		#備註:
3599
		#無.
3600
		$checkArguments=variableCheck::checkArguments($conf["variableCheck::checkArguments"]);
3601
		unset($conf["variableCheck::checkArguments"]);
3602
 
3603
		#如果執行失敗
3604
		if($checkArguments["status"]==="false"){
3605
 
3606
			#設置執行錯誤識別
3607
			$result["status"]="false";
3608
 
3609
			#設置錯誤訊息
3610
			$result["error"]=$checkArguments["error"];
3611
 
3612
			#回傳結果
3613
			return $result;
3614
 
3615
			}#if end
3616
 
3617
		#如果檢查不通過
3618
		if($checkArguments["status"]==="false"){
3619
 
3620
			#設置執行錯誤識別
3621
			$result["status"]="false";
3622
 
3623
			#設置錯誤訊息
3624
			$result["error"]=$checkArguments["error"];
3625
 
3626
			#回傳結果
3627
			return $result;
3628
 
3629
			}#if end
3630
 
3631
		#讓存放unix domain socket的路徑存在
3632
		#函式說明:
3633
		#確保路徑存在.
3634
		#回傳結果:
3635
		#$result["status"],執行正常與否,"true"代表正常,"false"代表不正常.
3636
		#$result["error"],錯誤訊息陣列.
3637
		#$resutl["function"],當前執行的涵式名稱.
3638
		#$result["path"],建立好的路徑字串.
3639
		#$result["fileName"],檔案名稱,若 $conf["haveFileName"] 為 "true" 則會回傳.
3640
		#$result["argu"],使用的參數.
3641
		#必填參數:
3642
		#$conf["path"],要檢查的路徑
3643
		$conf["fileAccess::validatePath"]["path"]=$conf["sock"];
3644
		#$conf["fileArgu"],字串,php變數__FILE__的內容,亦即該檔案在檔案系統的絕對路徑
3645
		$conf["fileAccess::validatePath"]["fileArgu"]=__FILE__;
3646
		#可省略參數:
3647
		#$conf["haveFileName"],字串,"true"代表有$conf["path"]檔案名稱,"false"代表$conf["path"]為純路徑,預設為"false".
3648
		$conf["fileAccess::validatePath"]["haveFileName"]="true";
3649
		#$conf["dirPermission"],字串,新建資料夾的權限設定,預設爲0770,亦即擁有者,同群組者可以讀,寫,存取,其他人無法使用.
3650
		#$conf["dirPermission"]="";
3651
		#$conf["web"],是否為檔案系統,"true"為網頁路徑,"false"為網頁系統,預設為"false".
3652
		$conf["fileAccess::validatePath"]["web"]="false";
3653
		#參考資料:
3654
		#無.
3655
		#備註:
3656
		#無.
3657
		$validatePath=fileAccess::validatePath($conf["fileAccess::validatePath"]);
3658
		unset($conf["fileAccess::validatePath"]);
3659
 
3660
		#如果執行失敗
3661
		if($validatePath["status"]==="false"){
3662
 
3663
			#設置錯誤識別
3664
			$result["status"]="false";
3665
 
3666
			#設置錯誤訊息
3667
			$result["error"]=$validatePath;
3668
 
3669
			#回傳結果
3670
			return $result;
3671
 
3672
			}#if end
3673
 
3674
		#變更 working dir
3675
		$chdir=chdir($validatePath["path"]);
3676
 
3677
		#嘗試30秒內連線到 unix domain socket
3678
		$fp=stream_socket_client("unix://".$validatePath["fileName"], $errno, $errstr, 30, STREAM_CLIENT_ASYNC_CONNECT );
3679
 
3680
		#如果開啟 unix domain socket 失敗
3681
		if(!$fp){
3682
 
3683
			#設置執行錯誤識別
3684
			$result["status"]="false";
3685
 
3686
			#設置錯誤訊息
3687
			$result["error"]=$errstr." (".$errno.")";
3688
 
3689
			#回傳結果
3690
			return $result;
3691
 
3692
			}#if end
3693
 
3694
		#傳遞訊息
3695
		$fwrite=fwrite($fp,$conf["msg"]);
3696
 
3697
		#如果傳遞失敗
3698
		if($fwrite===false){
3699
 
3700
			#關閉unix domain socket
3701
			@fclose($fp);
3702
 
3703
			#設置執行失敗
3704
			$result["status"]="false";
3705
 
3706
			#設置執行錯誤訊息
3707
			$result["error"][]="傳遞訊息(".$conf["msg"].")失敗";
3708
 
3709
			#回傳結果
3710
			return $result;
3711
 
3712
			}#if end
3713
 
3714
		#設置執行正常
3715
		$result["status"]="true";
3716
 
3717
		#回傳結果
3718
		return $result;
3719
 
3720
		}#function sendRawMsgUnixSocket
3721
 
3722
	/*
705 liveuser 3723
	#連線到 sock::unixDomainSocketServer 產生的  unix domain socket,傳送指定的訊息.
3724
	#回傳結果:
3725
	#$result["status"],"true"代表執行正常;"false"代表執行不正常.
3726
	#$result["error"],錯誤訊息陣列.
3727
	#$result["function"],當前執行的函式名稱.
3728
	#$result["argu"],使用的參數.
3729
	#$result["content"],得到的回應.
3730
	#必填參數:
3731
	#$conf["msg"],陣列,要傳送的訊息,其主$conf["msg"]["id"],是無法指定的.
3732
	$conf["msg"]=array();
3733
	#可省略參數:
3734
	#$conf["sock"],字串,要連線的 usr/bin/qbpwcf-sock.php 所產生的 unix domain socket 路徑與名稱,預設為 qbpwcf_usock_path.
3735
	#$conf["sock"]=qbpwcf_usock_path;
3736
	#參考資料:
3737
	#無.
3738
	#備註:
3739
	#無.
3740
	*/
3741
	public static function sendAnyMsgToQBPWCFunixSocket(&$conf){
3742
 
3743
		#初始化要回傳的結果
3744
		$result=array();
3745
 
3746
		#取得當前執行的函數名稱
3747
		$result["function"]=__FUNCTION__;
3748
 
3749
		#如果沒有參數
3750
		if(func_num_args()==0){
3751
 
3752
			#設置執行失敗
3753
			$result["status"]="false";
3754
 
3755
			#設置執行錯誤訊息
3756
			$result["error"]="函數".$result["function"]."需要參數";
3757
 
3758
			#回傳結果
3759
			return $result;
3760
 
3761
			}#if end
3762
 
3763
		#取得參數
3764
		$result["argu"]=$conf;
3765
 
3766
		#如果 $conf 不為陣列
3767
		if(gettype($conf)!="array"){
3768
 
3769
			#設置執行失敗
3770
			$result["status"]="false";
3771
 
3772
			#設置執行錯誤訊息
3773
			$result["error"][]="\$conf變數須為陣列形態";
3774
 
3775
			#如果傳入的參數為 null
3776
			if($conf==null){
3777
 
3778
				#設置執行錯誤訊息
3779
				$result["error"][]="\$conf變數不得為null,請檢查函數「".$result["function"]."」的參數設置有無正確!";
3780
 
3781
				}#if end
3782
 
3783
			#回傳結果
3784
			return $result;
3785
 
3786
			}#if end
3787
 
3788
		#函式說明:
3789
		#檢查必填與可省略的參數,可省略參數可指定預設要給與什麼數值內容.
3790
		#回傳結果:
3791
		#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
3792
		#$result["error"],執行不正常結束的錯訊息陣列.
3793
		#$result["simpleError"],簡單表示的錯誤訊息.
3794
		#$result["function"],當前執行的函式名稱.
3795
		#$result["argu"],設置給予的參數.
3796
		#$result["passed"],識別要檢查的全體變數是否存在以及型態是否正確的變數,"true"代表檢查全部通過;"false"代表檢查不通過
3797
		#$result[$shouldBeCheckedVarName]["varExist"],所檢查的變數是否存在,"false"代表不存在;"true"代表存在
3798
		#$result[$shouldBeCheckedVarName]["varType"],所檢查的變數型態是否正確,"false"代表錯誤;"true"代表正確
3799
		#$result[$shouldBeCheckedVarName]["error"],每個參數設定的錯誤訊息
3800
		#$result["shouldNotBeEmpty"],不應該為空字串或控陣列的變數.
3801
		#$result["argu"],字串陣列,目前輸入的參數名稱陣列.
3802
		#$result["legalVarName"],字串陣列,合法可用的參數名稱陣列.
3803
		#$result["notNeedVar"],字串陣列,多餘的參數名稱.
3804
		#必填參數:
3805
		#$conf["varInput"],陣列變數,要檢查的陣列變數,請在要檢查的參數前面加上&,這樣變動的結果才能被套用。
3806
		$conf["variableCheck::checkArguments"]["varInput"]=&$conf;
3807
		#$conf["referenceVarKey"],字串,$conf參數後面的key值,用於移除不要的參考陣列.
3808
		$conf["variableCheck::checkArguments"]["referenceVarKey"]="variableCheck::checkArguments";
3809
		#可省略參數:
3810
		#$conf["mustBeFilledVariableName"],爲必填參數的變數名稱陣列,形態爲陣列變數,元素數量需要跟"mustBeFilledVariableType"參數的元素數量一致,例如: $conf["mustBeFilledVariableName"] = array("id","account","password");
3811
		$conf["variableCheck::checkArguments"]["mustBeFilledVariableName"]=array("msg");
3812
		#$conf["mustBeFilledVariableType"],爲必填參數的變數陣列應該爲何種變數形態,形態爲陣列,元素數量需要跟"mustBeFilledVariableName"參數的元素數量一致,例如: $conf["mustBeFilledVariableType"] = array("string",integer,"double","resource","object"); , null代表不指定變數形態.
3813
		$conf["variableCheck::checkArguments"]["mustBeFilledVariableType"]=array("array");
3814
		#$conf["canBeEmptyString"],字串,必填變數內容如果是空字串就不能算是有設置的話,請設為"false",預設爲"true",可以為空字串.
3815
		#$conf["canBeEmptyString"]="false";
3816
		#$conf["canNotBeEmpty"],字串陣列,哪些必填參數的內容不得為空字串或空陣列,僅當$conf["canBeEmptyString"]為"true"時會生效.
3817
		#$conf["canNotBeEmpty"]=array();
3818
		#$conf["canBeEmpty"],字串陣列,哪些必填參數的內容可為空字串或空陣列,僅當$conf["canBeEmptyString"]為"false"時會生效.
3819
		#$conf["canBeEmpty"]=array();
3820
		#$conf["skipableVariableCanNotBeEmpty"],字串陣列,哪些可省略參數不可以為空字串或空陣列.
3821
		$conf["variableCheck::checkArguments"]["skipableVariableCanNotBeEmpty"]=array("sock");
3822
		#$conf["skipableVariableName"],陣列字串,爲可省略參數的變數名稱陣列,形態爲陣列變數,例如: $conf["skipableVariableName"] = array("id","account","password");
3823
		$conf["variableCheck::checkArguments"]["skipableVariableName"]=array("sock");
3824
		#$conf["skipableVariableType"],陣列字串,爲可省略參數的變數名稱陣列,形態爲陣列變數,例如: $conf["skipableVariableType"] = array("string",integer,"double");
3825
		$conf["variableCheck::checkArguments"]["skipableVariableType"]=array("string");
3826
		#$conf["skipableVarDefaultValue"],字串陣列,每個不存在的可省略變數要初始化為什麼,null與代表不指定,若預設值是參數之一,請將$conf["mustBeFilledVar"]改成"\$conf["\mustBeFilledVar\"]".
3827
		$conf["variableCheck::checkArguments"]["skipableVarDefaultValue"]=array(qbpwcf_usock_path);
3828
		#$conf["disallowAllSkipableVarIsEmpty"],字串,是否允許每個可省略參數都為空字串,預設為"true"允許,反之為"false".
3829
		#$conf["disallowAllSkipableVarIsEmpty"]="";
3830
		#$conf["disallowAllSkipableVarIsEmptyArray"],字串,是否允許每個可省略參數都為空陣列,預設為"true"允許,反之為"false".
3831
		#$conf["disallowAllSkipableVarIsEmptyArray"]="";
3832
		#$conf["disallowAllSkipableVarNotExist"],字串,是否不允許每個可省略參數都不存在,預設為"false"代表允許,反之為"true".
3833
		#$conf["disallowAllSkipableVarNotExist"]="";
3834
		#$conf["arrayCountEqualCheck"],字串陣列,為檢查哪些陣列參數的元素數量要一樣,$conf["arrayCountEqualCheck"][$i]=array()為第$i組key為哪些的變數其元素數量要相等.
3835
		#$conf["arrayCountEqualCheck"][]=array();
3836
		#參考資料:
3837
		#array_keys=>http://php.net/manual/en/function.array-keys.php
3838
		#備註:
3839
		#無.
3840
		$checkArguments=variableCheck::checkArguments($conf["variableCheck::checkArguments"]);
3841
		unset($conf["variableCheck::checkArguments"]);
3842
 
3843
		#如果執行失敗
3844
		if($checkArguments["status"]==="false"){
3845
 
3846
			#設置執行錯誤識別
3847
			$result["status"]="false";
3848
 
3849
			#設置錯誤訊息
3850
			$result["error"]=$checkArguments["error"];
3851
 
3852
			#回傳結果
3853
			return $result;
3854
 
3855
			}#if end
3856
 
3857
		#如果檢查不通過
3858
		if($checkArguments["status"]==="false"){
3859
 
3860
			#設置執行錯誤識別
3861
			$result["status"]="false";
3862
 
3863
			#設置錯誤訊息
3864
			$result["error"]=$checkArguments["error"];
3865
 
3866
			#回傳結果
3867
			return $result;
3868
 
3869
			}#if end
3870
 
3871
		#函式說明:
3872
		#連線到 unixDomainSockServer 提供的 unix domain socket.
3873
		#回傳結果:
3874
		#$result["status"],"true"代表執行正常;"false"代表執行不正常.
3875
		#$result["error"],錯誤訊息陣列.
3876
		#$result["function"],當前執行的函式名稱.
3877
		#$result["content"],取得的回應,讀到EOL,才會結束.
3878
		#必填參數:
3879
		#$conf["sock"],字串,要連線的unix domain socket.
3880
		$conf["sock::unixDomainSockClient"]["sock"]=$conf["sock"];
3881
		#可省略參數:
3882
		#$conf["id"],字串,取得的id,若無此值,則會得到新的數值.
3883
		#$conf["id"]="";
3884
		#$conf["cmd"],字串,要執行的指令,當$conf["id"]參數合法時,才會執行.
3885
		#$conf["cmd"]="";
3886
		#$conf["param"],參數陣列.
3887
		#$conf["param"]=array();
3888
		#$conf["escaped"],字串,param參數是否已經escaped了,預設為"false",反之為"true".
3889
		#$conf["escaped"]="true";
3890
		#$conf["custom"],陣列,要客制化傳輸的內容,會覆蓋以上除了$conf["id"]以外的可省略參數.
3891
		$conf["sock::unixDomainSockClient"]["custom"]=$conf["msg"];
3892
		#參考資料:
3893
		#http://php.net/manual/en/function.stream-socket-client.php
3894
		#http://php.net/manual/en/function.stream-get-contents.php
3895
		#備註:
3896
		#無.
3897
		$paramsOfUnixDomainSockClient=$conf["sock::unixDomainSockClient"];
3898
		$unixDomainSockClient=sock::unixDomainSockClient($conf["sock::unixDomainSockClient"]);
3899
		unset($conf["sock::unixDomainSockClient"]);
3900
 
3901
		#如果執行失敗
3902
		if($unixDomainSockClient["status"]==="false"){
3903
 
3904
			#設置執行錯誤識別
3905
			$result["status"]="false";
3906
 
3907
			#設置錯誤訊息
3908
			$result["error"]=$unixDomainSockClient;
3909
 
3910
			#回傳結果
3911
			return $result;
3912
 
3913
			}#if end
3914
 
3915
		#取得json回應
3916
		$jsonRes=json_decode($unixDomainSockClient["content"]);
3917
 
3918
		#如果執行失敗
3919
		if($jsonRes===null){
3920
 
3921
			#設置執行錯誤識別
3922
			$result["status"]="false";
3923
 
3924
			#設置錯誤訊息
3925
			$result["error"]=$unixDomainSockClient;
3926
 
3927
			#回傳結果
3928
			return $result;
3929
 
3930
			}#if end
3931
 
3932
		#如果沒有產生新id
3933
		if(!isset($jsonRes->id)){
3934
 
3935
			#設置執行錯誤識別
3936
			$result["status"]="false";
3937
 
3938
			#設置錯誤訊息
3939
			$result["error"]=$unixDomainSockClient;
3940
 
3941
			#回傳結果
3942
			return $result;
3943
 
3944
			}#if end
3945
 
3946
		#用新的id再傳送一次要求給 qbpwcf_usock_path
3947
		$paramsOfUnixDomainSockClient["id"]=$jsonRes->id;		
3948
		$unixDomainSockClient=sock::unixDomainSockClient($paramsOfUnixDomainSockClient);
3949
		unset($paramsOfUnixDomainSockClient);
3950
 
3951
		#如果執行失敗
3952
		if($unixDomainSockClient["status"]==="false"){
3953
 
3954
			#設置執行錯誤識別
3955
			$result["status"]="false";
3956
 
3957
			#設置錯誤訊息
3958
			$result["error"]=$unixDomainSockClient;
3959
 
3960
			#回傳結果
3961
			return $result;
3962
 
3963
			}#if end
3964
 
3965
		#取得回應
3966
		$result["content"]=$unixDomainSockClient["content"];
3967
 
3968
		#設置執行正常
3969
		$result["status"]="true";
3970
 
3971
		#回傳結果
3972
		return $result;
3973
 
3974
		}#function sendAnyMsgToQBPWCFunixSocket end
3975
 
3976
	/*
1 liveuser 3977
	#函式說明:
3978
	#重複連線到 unixDomainSockServer 提供的 unix domain socket, 避免其 listen timeout, 並清除逾時的連線.
3979
	#回傳結果:
3980
	#$result["status"],"true"代表執行正常;"false"代表執行不正常.
3981
	#$result["error"],錯誤訊息陣列.
3982
	#$result["function"],當前執行的函式名稱.
3983
	#必填參數:
3984
	#$conf["sock"],字串,要連線的unix domain socket.
3985
	$conf["sock"]="";
216 liveuser 3986
	#可省略參數:
3987
	#無.
3988
	#參考資料:
3989
	#無.
3990
	#備註:
3991
	#無.
1 liveuser 3992
	*/
216 liveuser 3993
	public static function keepAliveUnixDomainSockConnection(&$conf){
1 liveuser 3994
 
3995
		#初始化要回傳的結果
3996
		$result=array();
3997
 
3998
		#取得當前執行的函數名稱
3999
		$result["function"]=__FUNCTION__;
4000
 
4001
		#如果沒有參數
4002
		if(func_num_args()==0){
4003
 
4004
			#設置執行失敗
4005
			$result["status"]="false";
4006
 
4007
			#設置執行錯誤訊息
4008
			$result["error"]="函數".$result["function"]."需要參數";
4009
 
4010
			#回傳結果
4011
			return $result;
4012
 
4013
			}#if end
4014
 
4015
		#涵式說明:
4016
		#判斷當前環境為web還是cmd
4017
		#回傳結果:
4018
		#$result,"web"或"cmd"
4019
		if(csInformation::getEnv()==="web"){
4020
 
4021
			#設置執行失敗
4022
			$result["status"]="false";
4023
 
4024
			#設置執行錯誤訊息
4025
			$result["error"][]="函數 ".$result["function"]." 僅能在命令列環境下運行!";
4026
 
4027
			#回傳結果
4028
			return $result;
4029
 
4030
			}#if end
4031
 
4032
		#取得參數
4033
		$result["argu"]=$conf;
4034
 
4035
		#如果 $conf 不為陣列
4036
		if(gettype($conf)!="array"){
4037
 
4038
			#設置執行失敗
4039
			$result["status"]="false";
4040
 
4041
			#設置執行錯誤訊息
4042
			$result["error"][]="\$conf變數須為陣列形態";
4043
 
4044
			#如果傳入的參數為 null
4045
			if($conf==null){
4046
 
4047
				#設置執行錯誤訊息
4048
				$result["error"][]="\$conf變數不得為null,請檢查函數「".$result["function"]."」的參數設置有無正確!";
4049
 
4050
				}#if end
4051
 
4052
			#回傳結果
4053
			return $result;
4054
 
4055
			}#if end
4056
 
4057
		#檢查參數
4058
		#函式說明:
4059
		#檢查必填與可省略的參數,可省略參數可指定預設要給與什麼數值內容。
4060
		#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
4061
		#$reuslt["error"],執行不正常結束的錯訊息陣列.
4062
		#$result["function"],當前執行的函式名稱.
4063
		#$result["argu"],設置給予的參數.
4064
		#$result["passed"],識別要檢查的全體變數是否存在以及型態是否正確的變數,"true"代表檢查全部通過;"false"代表檢查不通過
4065
		#$result[$shouldBeCheckedVarName]["varExist"],所檢查的變數是否存在,"false"代表不存在;"true"代表存在
4066
		#$result[$shouldBeCheckedVarName]["varType"],所檢查的變數型態是否正確,"false"代表錯誤;"true"代表正確
4067
		#$result[$shouldBeCheckedVarName]["error"],每個參數設定的錯誤訊息
4068
		#$result["shouldNotBeEmpty"],不應該為空字串或控陣列的變數.
4069
		#$result["argu"],字串陣列,目前輸入的參數名稱陣列.
4070
		#$result["legalVarName"],字串陣列,合法可用的參數名稱陣列.
4071
		#$result["notNeedVar"],字串陣列,多餘的參數名稱.
4072
		#必填寫的參數:
4073
		#$conf["varInput"],陣列變數,要檢查的陣列變數,請在要檢查的參數前面加上&,這樣變動的結果才能被套用。
4074
		$conf["variableCheck::checkArguments"]["varInput"]=&$conf;	
4075
		#$conf["referenceVarKey"],字串,$conf參數後面的key值,用於移除不要的參考陣列.
4076
		$conf["variableCheck::checkArguments"]["referenceVarKey"]="variableCheck::checkArguments";
4077
		#可以省略的參數:
4078
		#$conf["mustBeFilledVariableName"],爲必填參數的變數名稱陣列,形態爲陣列變數,元素數量需要跟"mustBeFilledVariableType"參數的元素數量一致,例如: $conf["mustBeFilledVariableName"] = array("id","account","password");
4079
		$conf["variableCheck::checkArguments"]["mustBeFilledVariableName"]=array("sock");
4080
		#$conf["mustBeFilledVariableType"],爲必填參數的變數陣列應該爲何種變數形態,形態爲陣列,元素數量需要跟"mustBeFilledVariableName"參數的元素數量一致,例如: $conf["mustBeFilledVariableType"] = array("string",integer,"double","resource","object"); , null代表不指定變數形態.
4081
		$conf["variableCheck::checkArguments"]["mustBeFilledVariableType"]=array("string");
4082
		#$conf["canBeEmptyString"],字串,必填變數內容如果是空字串就不能算是有設置的話,請設為"false",預設爲"true",可以為空字串.
4083
		#$conf["canBeEmptyString"]="false";
4084
		#$conf["canNotBeEmpty"],字串陣列,哪些必填參數的內容不得為空字串或空陣列,僅當$conf["canBeEmptyString"]為"true"時會生效.
4085
		#$conf["canNotBeEmpty"]=array();
4086
		#$conf["canBeEmpty"],字串陣列,哪些必填參數的內容可為空字串或空陣列,僅當$conf["canBeEmptyString"]為"false"時會生效.
4087
		#$conf["canBeEmpty"]=array();
4088
		#$conf["skipableVariableCanNotBeEmpty"],字串陣列,哪些可省略參數不可以為空字串或空陣列.
4089
		#$conf["variableCheck::checkArguments"]["skipableVariableCanNotBeEmpty"]=array("id","cmd","param","clear");
4090
		#$conf["skipableVariableName"],陣列字串,爲可省略參數的變數名稱陣列,形態爲陣列變數,例如: $conf["skipableVariableName"] = array("id","account","password");
4091
		#$conf["variableCheck::checkArguments"]["skipableVariableName"]=array("id","cmd","param","clear");
4092
		#$conf["skipableVariableType"],陣列字串,爲可省略參數的變數名稱陣列,形態爲陣列變數,例如: $conf["skipableVariableType"] = array("string",integer,"double"); 
4093
		#$conf["variableCheck::checkArguments"]["skipableVariableType"]=array("string","string","array","string");
4094
		#$conf["skipableVarDefaultValue"],字串陣列,每個不存在的可省略變數要初始化為什麼,null與代表不指定,若預設值是參數之一,請將$conf["mustBeFilledVar"]改成"\$conf["\mustBeFilledVar\"]".
4095
		#$conf["variableCheck::checkArguments"]["skipableVarDefaultValue"]=array();
4096
		#$conf["disallowAllSkipableVarIsEmpty"],字串,是否允許每個可省略參數都為空字串,預設為"true"允許,反之為"false".
4097
		#$conf["disallowAllSkipableVarIsEmpty"]="";
4098
		#$conf["disallowAllSkipableVarIsEmptyArray"],字串,是否允許每個可省略參數都為空陣列,預設為"true"允許,反之為"false".
4099
		#$conf["disallowAllSkipableVarIsEmptyArray"]="";
4100
		#$conf["arrayCountEqualCheck"],字串陣列,為檢查哪些陣列參數的元素數量要一樣,$conf["arrayCountEqualCheck"][$i]=array()為第$i組key為哪些的變數其元素數量要相等.
4101
		#$conf["arrayCountEqualCheck"][]=array();
4102
		#參考資料來源:
4103
		#array_keys=>http://php.net/manual/en/function.array-keys.php
4104
		$checkArguments=variableCheck::checkArguments($conf["variableCheck::checkArguments"]);
4105
		unset($conf["variableCheck::checkArguments"]);
4106
 
4107
		#如果檢查參數失敗
4108
		if($checkArguments["status"]==="false"){
4109
 
4110
			#設置執行失敗
4111
			$result["status"]="false";
4112
 
4113
			#設置錯誤訊息
4114
			$result["error"]=$checkArguments;
4115
 
4116
			#回傳結果
4117
			return $result;
4118
 
4119
			}#if end
4120
 
4121
		#如果檢查參數不通過
4122
		if($checkArguments["passed"]==="false"){
4123
 
4124
			#設置執行失敗
4125
			$result["status"]="false";
4126
 
4127
			#設置錯誤訊息
4128
			$result["error"]=$checkArguments;
4129
 
4130
			#回傳結果
4131
			return $result;
4132
 
4133
			}#if end
4134
 
4135
		#函式說明:
4136
		#連線到 unixDomainSockServer 提供的 unix domain socket.
4137
		#回傳結果:
4138
		#$result["status"],"true"代表執行正常;"false"代表執行不正常.
4139
		#$result["error"],錯誤訊息陣列.
4140
		#$result["function"],當前執行的函式名稱.
4141
		#$result["content"],取得的回應.
4142
		#必填參數:
4143
		#$conf["sock"],字串,要連線的unix domain socket.
4144
		$conf["sock::unixDomainSockClient"]["sock"]=$conf["sock"];
4145
		#可省略參數:
4146
		#$conf["id"],字串,取得的id,若無此值,則會得到新的數值.
4147
		#$conf["id"]="";
4148
		#$conf["cmd"],字串,要執行的指令.
4149
		#$conf["cmd"]="";
4150
		#$conf["param"],參數陣列.
4151
		#$conf["param"]=array();
4152
		#參考資料:
4153
		#http://php.net/manual/en/function.stream-socket-client.php
4154
		#http://php.net/manual/en/function.stream-get-contents.php
4155
		$unixDomainSockClient=sock::unixDomainSockClient($conf["sock::unixDomainSockClient"]);
4156
		unset($conf["sock::unixDomainSockClient"]);
4157
 
4158
		#建立連線失敗
4159
		if($unixDomainSockClient["status"]==="false"){
4160
 
4161
			#設置執行失敗
4162
			$result["status"]="false";
4163
 
4164
			#設置執行錯誤訊息
4165
			$result["error"]=$unixDomainSockClient;
4166
 
4167
			#回傳結果
4168
			return $result;
4169
 
4170
			}#if end
4171
 
4172
		#取得回應	
4173
		$res=$unixDomainSockClient["content"];
4174
 
4175
		#解析回應
4176
		$res=json_decode(trim($res));
4177
 
4178
		#如果解析失敗
4179
		if($res===false){
4180
 
4181
			#設置執行失敗
4182
			$result["status"]="false";
4183
 
4184
			#設置執行錯誤訊息
4185
			$result["error"][]="解析回應失敗";
4186
 
4187
			#回傳結果
4188
			return $result;
4189
 
4190
			}#if end
4191
 
4192
		#取得id	
4193
		$id=$res->id;
4194
 
4195
		#無窮迴圈
4196
		while(true){
4197
 
4198
			#函式說明:
4199
			#連線到 unixDomainSockServer 提供的 unix domain socket.
4200
			#回傳結果:
4201
			#$result["status"],"true"代表執行正常;"false"代表執行不正常.
4202
			#$result["error"],錯誤訊息陣列.
4203
			#$result["function"],當前執行的函式名稱.
4204
			#$result["content"],取得的回應.
4205
			#必填參數:
4206
			#$conf["sock"],字串,要連線的unix domain socket.
4207
			$conf["sock::unixDomainSockClient"]["sock"]=$conf["sock"];
4208
			#可省略參數:
4209
			#$conf["id"],字串,取得的id,若無此值,則會得到新的數值.
4210
			$conf["sock::unixDomainSockClient"]["id"]=$id;
4211
			#$conf["cmd"],字串,要執行的指令.
4212
			#$conf["cmd"]="";
4213
			#$conf["param"],參數陣列.
4214
			#$conf["param"]=array();
4215
			#參考資料:
4216
			#http://php.net/manual/en/function.stream-socket-client.php
4217
			#http://php.net/manual/en/function.stream-get-contents.php
4218
			$unixDomainSockClient=sock::unixDomainSockClient($conf["sock::unixDomainSockClient"]);
4219
			unset($conf["sock::unixDomainSockClient"]);
4220
 
4221
			#建立連線失敗
4222
			if($unixDomainSockClient["status"]==="false"){
4223
 
4224
				#設置執行失敗
4225
				$result["status"]="false";
4226
 
4227
				#設置執行錯誤訊息
4228
				$result["error"]=$unixDomainSockClient;
4229
 
4230
				#回傳結果
4231
				return $result;
4232
 
4233
				}#if end
4234
 
4235
			#取得回應	
4236
			$res=$unixDomainSockClient["content"];
4237
 
4238
			#解析回應
4239
			$res=json_decode($res);
4240
 
4241
			#如果解析失敗
4242
			if($res===false){
4243
 
4244
				#設置執行失敗
4245
				$result["status"]="false";
4246
 
4247
				#設置執行錯誤訊息
4248
				$result["error"][]="解析回應失敗";
4249
 
4250
				#回傳結果
4251
				return $result;
4252
 
4253
				}#if end
4254
 
4255
			#show res
4256
			var_dump($res);
4257
 
4258
			#停止執行
4259
			sleep(60);
4260
 
4261
			}#while end
4262
 
4263
		#設置執行不正常
4264
		$result["status"]="false";
4265
 
4266
		#設置錯誤訊息
4267
		$result["error"][]="程式不應該中斷";
4268
 
4269
		#回傳結果
4270
		return $reuslt;
4271
 
4272
		}#function keepAliveUnixDomainSockConnection end
4273
 
4274
	/*
4275
	#函式說明:
4276
	#tcp client
4277
	#回傳結果:
4278
	#$result["status"],"true"代表執行正常;"false"代表執行不正常.
4279
	#$result["error"],錯誤訊息陣列.
4280
	#$result["function"],當前執行的函式名稱.
4281
	#$result["argu"],使用的參數.
4282
	#$result["content"],取得的回應內容.
4283
	#必填參數:
4284
	#$conf["port"],整數,tcp server listen port.
4285
	$conf["port"]=;
4286
	#$conf["dataToSend"],字串,要傳送的資訊.
4287
	$conf["dataToSend"]="";
4288
	#可省略參數:
4289
	#$conf["ip"],整數字串,tcp serer listen ip, default is 127.0.0.1.
4290
	#$conf["ip"]="127.0.0.1";
98 liveuser 4291
	#$conf["sec"],整數,等待回應的秒數,預設為5秒.
4292
	#$conf["sec"]=5;
4293
	#$conf["microSec"],整數,等待回應的毫秒數,預設為0毫秒
4294
	#$conf["microSec"]=0;
1 liveuser 4295
	#參考資料:
4296
	#https://www.php.net/manual/en/sockets.examples.php
98 liveuser 4297
	#https://www.php.net/manual/en/function.socket-get-option.php
57 liveuser 4298
	#備註:
4299
	#無.
1 liveuser 4300
	*/
4301
	public static function tcpClient(&$conf){
4302
 
4303
		#初始化要回傳的結果
4304
		$result=array();
4305
 
4306
		#取得當前執行的函數名稱
4307
		$result["function"]=__FUNCTION__;
4308
 
4309
		#如果沒有參數
4310
		if(func_num_args()==0){
4311
 
4312
			#設置執行失敗
4313
			$result["status"]="false";
4314
 
4315
			#設置執行錯誤訊息
4316
			$result["error"]="函數".$result["function"]."需要參數";
4317
 
4318
			#回傳結果
4319
			return $result;
4320
 
4321
			}#if end
4322
 
4323
		#涵式說明:
4324
		#判斷當前環境為web還是cmd
4325
		#回傳結果:
4326
		#$result,"web"或"cmd"
4327
		if(csInformation::getEnv()==="web"){
4328
 
4329
			#設置執行失敗
4330
			$result["status"]="false";
4331
 
4332
			#設置執行錯誤訊息
4333
			$result["error"][]="函數 ".$result["function"]." 僅能在命令列環境下運行!";
4334
 
4335
			#回傳結果
4336
			return $result;
4337
 
4338
			}#if end
4339
 
4340
		#取得參數
4341
		$result["argu"]=$conf;
4342
 
4343
		#如果 $conf 不為陣列
4344
		if(gettype($conf)!="array"){
4345
 
4346
			#設置執行失敗
4347
			$result["status"]="false";
4348
 
4349
			#設置執行錯誤訊息
4350
			$result["error"][]="\$conf變數須為陣列形態";
4351
 
4352
			#如果傳入的參數為 null
4353
			if($conf==null){
4354
 
4355
				#設置執行錯誤訊息
4356
				$result["error"][]="\$conf變數不得為null,請檢查函數「".$result["function"]."」的參數設置有無正確!";
4357
 
4358
				}#if end
4359
 
4360
			#回傳結果
4361
			return $result;
4362
 
4363
			}#if end
4364
 
4365
		#初始化取得的回應
4366
		$result["content"]="";	
4367
 
4368
		#檢查參數
4369
		#函式說明:
4370
		#檢查必填與可省略的參數,可省略參數可指定預設要給與什麼數值內容。
4371
		#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
4372
		#$reuslt["error"],執行不正常結束的錯訊息陣列.
4373
		#$result["function"],當前執行的函式名稱.
4374
		#$result["argu"],設置給予的參數.
4375
		#$result["passed"],識別要檢查的全體變數是否存在以及型態是否正確的變數,"true"代表檢查全部通過;"false"代表檢查不通過
4376
		#$result[$shouldBeCheckedVarName]["varExist"],所檢查的變數是否存在,"false"代表不存在;"true"代表存在
4377
		#$result[$shouldBeCheckedVarName]["varType"],所檢查的變數型態是否正確,"false"代表錯誤;"true"代表正確
4378
		#$result[$shouldBeCheckedVarName]["error"],每個參數設定的錯誤訊息
4379
		#$result["shouldNotBeEmpty"],不應該為空字串或控陣列的變數.
4380
		#$result["argu"],字串陣列,目前輸入的參數名稱陣列.
4381
		#$result["legalVarName"],字串陣列,合法可用的參數名稱陣列.
4382
		#$result["notNeedVar"],字串陣列,多餘的參數名稱.
4383
		#必填寫的參數:
4384
		#$conf["varInput"],陣列變數,要檢查的陣列變數,請在要檢查的參數前面加上&,這樣變動的結果才能被套用。
4385
		$conf["variableCheck::checkArguments"]["varInput"]=&$conf;	
4386
		#$conf["referenceVarKey"],字串,$conf參數後面的key值,用於移除不要的參考陣列.
4387
		$conf["variableCheck::checkArguments"]["referenceVarKey"]="variableCheck::checkArguments";
4388
		#可以省略的參數:
4389
		#$conf["mustBeFilledVariableName"],爲必填參數的變數名稱陣列,形態爲陣列變數,元素數量需要跟"mustBeFilledVariableType"參數的元素數量一致,例如: $conf["mustBeFilledVariableName"] = array("id","account","password");
4390
		$conf["variableCheck::checkArguments"]["mustBeFilledVariableName"]=array("port","dataToSend");
4391
		#$conf["mustBeFilledVariableType"],爲必填參數的變數陣列應該爲何種變數形態,形態爲陣列,元素數量需要跟"mustBeFilledVariableName"參數的元素數量一致,例如: $conf["mustBeFilledVariableType"] = array("string",integer,"double","resource","object"); , null代表不指定變數形態.
4392
		$conf["variableCheck::checkArguments"]["mustBeFilledVariableType"]=array("integer","string");
4393
		#$conf["canBeEmptyString"],字串,必填變數內容如果是空字串就不能算是有設置的話,請設為"false",預設爲"true",可以為空字串.
4394
		$conf["variableCheck::checkArguments"]["canBeEmptyString"]="false";
4395
		#$conf["canNotBeEmpty"],字串陣列,哪些必填參數的內容不得為空字串或空陣列,僅當$conf["canBeEmptyString"]為"true"時會生效.
4396
		#$conf["canNotBeEmpty"]=array();
4397
		#$conf["canBeEmpty"],字串陣列,哪些必填參數的內容可為空字串或空陣列,僅當$conf["canBeEmptyString"]為"false"時會生效.
4398
		#$conf["canBeEmpty"]=array();
4399
		#$conf["skipableVariableCanNotBeEmpty"],字串陣列,哪些可省略參數不可以為空字串或空陣列.
4400
		$conf["variableCheck::checkArguments"]["skipableVariableCanNotBeEmpty"]=array("ip");
4401
		#$conf["skipableVariableName"],陣列字串,爲可省略參數的變數名稱陣列,形態爲陣列變數,例如: $conf["skipableVariableName"] = array("id","account","password");
98 liveuser 4402
		$conf["variableCheck::checkArguments"]["skipableVariableName"]=array("ip","sec","microSec");
1 liveuser 4403
		#$conf["skipableVariableType"],陣列字串,爲可省略參數的變數名稱陣列,形態爲陣列變數,例如: $conf["skipableVariableType"] = array("string",integer,"double"); 
98 liveuser 4404
		$conf["variableCheck::checkArguments"]["skipableVariableType"]=array("string","integer","integer");
1 liveuser 4405
		#$conf["skipableVarDefaultValue"],字串陣列,每個不存在的可省略變數要初始化為什麼,null與代表不指定,若預設值是參數之一,請將$conf["mustBeFilledVar"]改成"\$conf["\mustBeFilledVar\"]".
98 liveuser 4406
		$conf["variableCheck::checkArguments"]["skipableVarDefaultValue"]=array("127.0.0.1",5,0);
1 liveuser 4407
		#$conf["disallowAllSkipableVarIsEmpty"],字串,是否允許每個可省略參數都為空字串,預設為"true"允許,反之為"false".
4408
		#$conf["disallowAllSkipableVarIsEmpty"]="";
4409
		#$conf["disallowAllSkipableVarIsEmptyArray"],字串,是否允許每個可省略參數都為空陣列,預設為"true"允許,反之為"false".
4410
		#$conf["disallowAllSkipableVarIsEmptyArray"]="";
4411
		#$conf["arrayCountEqualCheck"],字串陣列,為檢查哪些陣列參數的元素數量要一樣,$conf["arrayCountEqualCheck"][$i]=array()為第$i組key為哪些的變數其元素數量要相等.
4412
		#$conf["arrayCountEqualCheck"][]=array();
4413
		#參考資料來源:
4414
		#array_keys=>http://php.net/manual/en/function.array-keys.php
4415
		$checkArguments=variableCheck::checkArguments($conf["variableCheck::checkArguments"]);
4416
		unset($conf["variableCheck::checkArguments"]);
4417
 
4418
		#如果檢查參數失敗
4419
		if($checkArguments["status"]==="false"){
4420
 
4421
			#設置執行失敗
4422
			$result["status"]="false";
4423
 
4424
			#設置錯誤訊息
4425
			$result["error"]=$checkArguments;
4426
 
4427
			#回傳結果
4428
			return $result;
4429
 
4430
			}#if end
4431
 
4432
		#如果檢查參數不通過
4433
		if($checkArguments["passed"]==="false"){
4434
 
4435
			#設置執行失敗
4436
			$result["status"]="false";
4437
 
4438
			#設置錯誤訊息
4439
			$result["error"]=$checkArguments;
4440
 
4441
			#回傳結果
4442
			return $result;
4443
 
4444
			}#if end
4445
 
4446
		#建立 tcp socket client	
4447
		$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
4448
 
98 liveuser 4449
		#設置接收資料的最長等待時間
4450
		socket_set_option($socket, SOL_SOCKET, SO_RCVTIMEO, array("sec"=>$conf["sec"],"usec"=>$conf["microSec"]));
4451
 
1 liveuser 4452
		#如果建立 socket 失敗
4453
		if ($socket === false) {
4454
 
4455
			#設置執行失敗
4456
			$result["status"]="false";
4457
 
4458
			#設置錯誤訊息
4459
			$result["error"][]="socket_create() failed: reason: " . socket_strerror(socket_last_error());
4460
 
4461
			#回傳結果
4462
			return $result;
4463
 
4464
			}#if end 
4465
 
4466
		#連線到 tcp socket server	
4467
		$socket_connect = socket_connect($socket, $conf["ip"], $conf["port"]);
4468
 
4469
		#如果連線到 tcp socket server 失敗
4470
		if ($socket_connect === false) {
4471
 
4472
			#設置執行失敗
4473
			$result["status"]="false";
4474
 
4475
	    		#設置錯誤訊息
4476
			$result["error"][]="socket_connect() failed. Reason: ($result) " . socket_strerror(socket_last_error($socket));
4477
 
4478
			#回傳結果
4479
			return $result;
4480
 
4481
			}#if end
4482
 
4483
		#傳送訊息到 tcp server
4484
		socket_write($socket, $conf["dataToSend"].PHP_EOL, strlen($conf["dataToSend"].PHP_EOL));
155 liveuser 4485
 
1 liveuser 4486
		#取得回應
4487
		while ($out = socket_read($socket, 2048)) {
155 liveuser 4488
 
4489
			#設置取得的回應
4490
			$result["content"]=$result["content"].$out;
4491
 
4492
			#debug
4493
			#echo $result["content"];
4494
 
1 liveuser 4495
			}#while end
4496
 
4497
		#關閉socket
4498
		socket_close($socket);
4499
 
4500
		#設置處理正常
4501
		$result["status"]="true";
4502
 
4503
		#回傳結果
4504
		return $result;	
4505
 
4506
		}#function tcpClient end
4507
 
4508
	/*
4509
	#函式說明:
4510
	#udp client
4511
	#回傳結果:
4512
	#$result["status"],"true"代表執行正常;"false"代表執行不正常.
4513
	#$result["error"],錯誤訊息陣列.
4514
	#$result["function"],當前執行的函式名稱.
4515
	#$result["argu"],使用的參數.
4516
	#$result["content"],取得的回應內容字串,為每個回應的內容直接串接.
4517
	#$result["contentArray"],取得的回應字串陣列,為每個回應的內容,各別儲存成陣列中的元素.
4518
	#$result["sock"],可重複使用的socket資源.
4519
	#必填參數:
4520
	#$conf["port"],整數,target port.
4521
	$conf["port"]=;
4522
	#$conf["dataToSend"],陣列字串,要傳送的多個訊息,每個訊息傳送結束後才會讀取回應.
4523
	$conf["dataToSend"]=array("");
4524
	#可省略參數:
4525
	#$conf["ip"],整數字串,tcp serer listen ip, default is 127.0.0.1.
4526
	#$conf["ip"]="127.0.0.1";
4527
	#$conf["timeout"],整數,預設為10秒,代表接收訊息的等待時間上限.
4528
	#$conf["timeout"]=10;
4529
	#$conf["secSleepAfterSend"],整數,預設為1秒.
4530
	#$conf["secSleepAfterSend"]=1;
4531
	#$conf["closeAtEnd"],字串,預設為"true",代表函式結束後要斷開連線.
4532
	#$conf["closeAtEnd"]="true";
4533
	#$conf["sock"],resource,要重複使用的socket資源,預設不指定.
4534
	#$conf["sock"]=;
4535
	#參考資料:
4536
	#https://www.php.net/manual/en/sockets.examples.php
57 liveuser 4537
	#備註:
4538
	#無.
1 liveuser 4539
	*/
4540
	public static function udpClient(&$conf){
4541
 
4542
		#初始化要回傳的結果
4543
		$result=array();
4544
 
4545
		#取得當前執行的函數名稱
4546
		$result["function"]=__FUNCTION__;
4547
 
4548
		#如果沒有參數
4549
		if(func_num_args()==0){
4550
 
4551
			#設置執行失敗
4552
			$result["status"]="false";
4553
 
4554
			#設置執行錯誤訊息
4555
			$result["error"]="函數".$result["function"]."需要參數";
4556
 
4557
			#回傳結果
4558
			return $result;
4559
 
4560
			}#if end
4561
 
4562
		#涵式說明:
4563
		#判斷當前環境為web還是cmd
4564
		#回傳結果:
4565
		#$result,"web"或"cmd"
4566
		if(csInformation::getEnv()==="web"){
4567
 
4568
			#設置執行失敗
4569
			$result["status"]="false";
4570
 
4571
			#設置執行錯誤訊息
4572
			$result["error"][]="函數 ".$result["function"]." 僅能在命令列環境下運行!";
4573
 
4574
			#回傳結果
4575
			return $result;
4576
 
4577
			}#if end
4578
 
4579
		#取得參數
4580
		$result["argu"]=$conf;
4581
 
4582
		#如果 $conf 不為陣列
4583
		if(gettype($conf)!="array"){
4584
 
4585
			#設置執行失敗
4586
			$result["status"]="false";
4587
 
4588
			#設置執行錯誤訊息
4589
			$result["error"][]="\$conf變數須為陣列形態";
4590
 
4591
			#如果傳入的參數為 null
4592
			if($conf==null){
4593
 
4594
				#設置執行錯誤訊息
4595
				$result["error"][]="\$conf變數不得為null,請檢查函數「".$result["function"]."」的參數設置有無正確!";
4596
 
4597
				}#if end
4598
 
4599
			#回傳結果
4600
			return $result;
4601
 
4602
			}#if end
4603
 
4604
		#初始化取得的回應
4605
		$result["content"]="";	
4606
 
4607
		#檢查參數
4608
		#函式說明:
4609
		#檢查必填與可省略的參數,可省略參數可指定預設要給與什麼數值內容。
4610
		#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
4611
		#$reuslt["error"],執行不正常結束的錯訊息陣列.
4612
		#$result["function"],當前執行的函式名稱.
4613
		#$result["argu"],設置給予的參數.
4614
		#$result["passed"],識別要檢查的全體變數是否存在以及型態是否正確的變數,"true"代表檢查全部通過;"false"代表檢查不通過
4615
		#$result[$shouldBeCheckedVarName]["varExist"],所檢查的變數是否存在,"false"代表不存在;"true"代表存在
4616
		#$result[$shouldBeCheckedVarName]["varType"],所檢查的變數型態是否正確,"false"代表錯誤;"true"代表正確
4617
		#$result[$shouldBeCheckedVarName]["error"],每個參數設定的錯誤訊息
4618
		#$result["shouldNotBeEmpty"],不應該為空字串或控陣列的變數.
4619
		#$result["argu"],字串陣列,目前輸入的參數名稱陣列.
4620
		#$result["legalVarName"],字串陣列,合法可用的參數名稱陣列.
4621
		#$result["notNeedVar"],字串陣列,多餘的參數名稱.
4622
		#必填寫的參數:
4623
		#$conf["varInput"],陣列變數,要檢查的陣列變數,請在要檢查的參數前面加上&,這樣變動的結果才能被套用。
4624
		$conf["variableCheck::checkArguments"]["varInput"]=&$conf;	
4625
		#$conf["referenceVarKey"],字串,$conf參數後面的key值,用於移除不要的參考陣列.
4626
		$conf["variableCheck::checkArguments"]["referenceVarKey"]="variableCheck::checkArguments";
4627
		#可以省略的參數:
4628
		#$conf["mustBeFilledVariableName"],爲必填參數的變數名稱陣列,形態爲陣列變數,元素數量需要跟"mustBeFilledVariableType"參數的元素數量一致,例如: $conf["mustBeFilledVariableName"] = array("id","account","password");
4629
		$conf["variableCheck::checkArguments"]["mustBeFilledVariableName"]=array("port","dataToSend");
4630
		#$conf["mustBeFilledVariableType"],爲必填參數的變數陣列應該爲何種變數形態,形態爲陣列,元素數量需要跟"mustBeFilledVariableName"參數的元素數量一致,例如: $conf["mustBeFilledVariableType"] = array("string",integer,"double","resource","object"); , null代表不指定變數形態.
4631
		$conf["variableCheck::checkArguments"]["mustBeFilledVariableType"]=array("integer","array");
4632
		#$conf["canBeEmptyString"],字串,必填變數內容如果是空字串就不能算是有設置的話,請設為"false",預設爲"true",可以為空字串.
4633
		$conf["variableCheck::checkArguments"]["canBeEmptyString"]="false";
4634
		#$conf["canNotBeEmpty"],字串陣列,哪些必填參數的內容不得為空字串或空陣列,僅當$conf["canBeEmptyString"]為"true"時會生效.
4635
		#$conf["canNotBeEmpty"]=array();
4636
		#$conf["canBeEmpty"],字串陣列,哪些必填參數的內容可為空字串或空陣列,僅當$conf["canBeEmptyString"]為"false"時會生效.
4637
		#$conf["canBeEmpty"]=array();
4638
		#$conf["skipableVariableCanNotBeEmpty"],字串陣列,哪些可省略參數不可以為空字串或空陣列.
4639
		$conf["variableCheck::checkArguments"]["skipableVariableCanNotBeEmpty"]=array("ip","secSleepAfterSend","closeAtEnd","timeout");
4640
		#$conf["skipableVariableName"],陣列字串,爲可省略參數的變數名稱陣列,形態爲陣列變數,例如: $conf["skipableVariableName"] = array("id","account","password");
4641
		$conf["variableCheck::checkArguments"]["skipableVariableName"]=array("ip","secSleepAfterSend","closeAtEnd","sock","timeout");
4642
		#$conf["skipableVariableType"],陣列字串,爲可省略參數的變數名稱陣列,形態爲陣列變數,例如: $conf["skipableVariableType"] = array("string",integer,"double"); 
21 liveuser 4643
		$conf["variableCheck::checkArguments"]["skipableVariableType"]=array("string","integer","string","object","integer");
1 liveuser 4644
		#$conf["skipableVarDefaultValue"],字串陣列,每個不存在的可省略變數要初始化為什麼,null與代表不指定,若預設值是參數之一,請將$conf["mustBeFilledVar"]改成"\$conf["\mustBeFilledVar\"]".
4645
		$conf["variableCheck::checkArguments"]["skipableVarDefaultValue"]=array("127.0.0.1",1,"false",null,10);
4646
		#$conf["disallowAllSkipableVarIsEmpty"],字串,是否允許每個可省略參數都為空字串,預設為"true"允許,反之為"false".
4647
		#$conf["disallowAllSkipableVarIsEmpty"]="";
4648
		#$conf["disallowAllSkipableVarIsEmptyArray"],字串,是否允許每個可省略參數都為空陣列,預設為"true"允許,反之為"false".
4649
		#$conf["disallowAllSkipableVarIsEmptyArray"]="";
4650
		#$conf["arrayCountEqualCheck"],字串陣列,為檢查哪些陣列參數的元素數量要一樣,$conf["arrayCountEqualCheck"][$i]=array()為第$i組key為哪些的變數其元素數量要相等.
4651
		#$conf["arrayCountEqualCheck"][]=array();
4652
		#參考資料來源:
4653
		#array_keys=>http://php.net/manual/en/function.array-keys.php
4654
		$checkArguments=variableCheck::checkArguments($conf["variableCheck::checkArguments"]);
4655
		unset($conf["variableCheck::checkArguments"]);
4656
 
4657
		#如果檢查參數失敗
4658
		if($checkArguments["status"]==="false"){
4659
 
4660
			#設置執行失敗
4661
			$result["status"]="false";
4662
 
4663
			#設置錯誤訊息
4664
			$result["error"]=$checkArguments;
4665
 
4666
			#回傳結果
4667
			return $result;
4668
 
4669
			}#if end
4670
 
4671
		#如果檢查參數不通過
4672
		if($checkArguments["passed"]==="false"){
4673
 
4674
			#設置執行失敗
4675
			$result["status"]="false";
4676
 
4677
			#設置錯誤訊息
4678
			$result["error"]=$checkArguments;
4679
 
4680
			#回傳結果
4681
			return $result;
4682
 
4683
			}#if end
4684
 
4685
		#如果沒有指定要用既有的 socket 
4686
		if(!isset($conf["sock"])){
4687
 
4688
			#建立 udp socket client	
4689
			$socket = socket_create(AF_INET, SOCK_DGRAM, SOL_UDP);
4690
 
4691
			#設置 timeout 為 $conf["timeout"] 秒
4692
			$timeout = array('sec'=>$conf["timeout"],'usec'=>0);
4693
 			socket_set_option($socket,SOL_SOCKET,SO_RCVTIMEO,$timeout);
4694
 
4695
 			#如果建立 socket 失敗
4696
			if ($socket === false) {
4697
 
4698
				#設置執行失敗
4699
				$result["status"]="false";
4700
 
4701
				#設置錯誤訊息
4702
				$result["error"][]="socket_create() failed: reason: " . socket_strerror(socket_last_error());
4703
 
4704
				#回傳結果
4705
				return $result;
4706
 
4707
				}#if end 
4708
 
4709
			#連線到 udp socket server	
4710
			$socket_connect = socket_connect($socket, $conf["ip"], $conf["port"]);
4711
 
4712
			#如果連線到 udp socket server 失敗
4713
			if ($socket_connect === false) {
4714
 
4715
				#設置執行失敗
4716
				$result["status"]="false";
4717
 
21 liveuser 4718
				#設置錯誤訊息
1 liveuser 4719
				$result["error"][]="socket_connect() failed. Reason: ($result) " . socket_strerror(socket_last_error($socket));
4720
 
4721
				#回傳結果
4722
				return $result;
4723
 
4724
				}#if end
4725
 
4726
			}#if end	
4727
 
4728
		#反之
4729
		else{
21 liveuser 4730
			#取得要重複使用的socket
1 liveuser 4731
			$socket=&$conf["sock"];
4732
 
4733
			}#else end
4734
 
4735
		#有幾個訊息就跑幾次
4736
		for($i=0;$i<count($conf["dataToSend"]);$i++){
4737
 
4738
			#傳送訊息到 tcp server
4739
			socket_write($socket, $conf["dataToSend"][$i], strlen($conf["dataToSend"][$i]));
4740
 
4741
			#取得回應
4742
			while ($out = socket_read($socket, 2048)) {
5 liveuser 4743
 
4744
				#設置取得的回應,儲存到陣列裡面.
4745
				$result["contentArray"][]=$out;
4746
 
4747
				#設置取得的回應,儲存成字串,串接在一塊.
4748
				$result["content"]=$result["content"].$out;
4749
 
1 liveuser 4750
				}#while end
4751
 
4752
			#如果有多個訊息要傳遞,且不是最後一個訊息
4753
			if(count($conf["dataToSend"])>1 && $i!==count($conf["dataToSend"])-1){
4754
 
4755
				#休息一下
4756
				sleep($conf["secSleepAfterSend"]);
4757
 
4758
				}#if end
4759
 
4760
			}#for end
4761
 
4762
		#如果要關閉連線
4763
		if($conf["closeAtEnd"]==="true"){
4764
 
4765
			#關閉socket
4766
			socket_close($socket);
4767
 
4768
			}#if end
4769
 
4770
		#取得使用的socket
4771
		$result["sock"]=$socket;	
4772
 
4773
		#設置處理正常
4774
		$result["status"]="true";
4775
 
4776
		#回傳結果
4777
		return $result;	
5 liveuser 4778
 
1 liveuser 4779
		}#function udpClient end
4780
 
4781
	/*
4782
	#函式說明:
4783
	#建立tcp server
4784
	#必填參數:
4785
	#$conf["port"],整數,tcp server listen port.
4786
	$conf["port"]=;
4787
	#可省略參數:
4788
	#$conf["ip"],整數字串,tcp server listen ip, default is 0.0.0.0.
4789
	#$conf["ip"]="0.0.0.0";
4790
	#$conf["processFuncs"],字串陣列,要將收到的訊息作什麼事情的函式們,預設為空陣列,裡面若是自己建立的涵式,可這樣呼叫"\qbpwcf\your function name".
4791
	#$conf["processFuncs"]=array();
4792
	#$conf["serverFuncs"],字串陣列,於idle時,server要執行的函式們,預設為空陣列.
4793
	#$conf["serverFuncs"]=array();
4794
	#$conf["welcomeMsg"],字串,是否要顯示歡迎訊息,預設為"true"代表要顯示歡迎訊息;"false"代表不要顯示歡迎訊息.
4795
	#$conf["welcomeMsg"]="true";
4796
	#$conf["socketSelectTimeountSec"],整數,代表要等候幾秒才抓取有異動的連線,預設為0代表立即抓取有異動的連線,但是會吃很多cpu.
4797
	#$conf["socketSelectTimeountSec"]=0;
4798
	#$conf["socketSelectTimeountUsec"],整數,代表要等候幾微秒才抓取有異動的連線,預設不使用.
4799
	#$conf["socketSelectTimeountUsec"]=5000;
216 liveuser 4800
	#參考資料:
4801
	#無.
57 liveuser 4802
	#備註:
4803
	#無.
1 liveuser 4804
	*/
4805
	public static function tcpServer(&$conf){
4806
 
4807
		#初始化要回傳的結果
4808
		$result=array();
4809
 
4810
		#取得當前執行的函數名稱
4811
		$result["function"]=__FUNCTION__;
4812
 
4813
		#如果沒有參數
4814
		if(func_num_args()==0){
4815
 
4816
			#設置執行失敗
4817
			$result["status"]="false";
4818
 
4819
			#設置執行錯誤訊息
4820
			$result["error"]="函數".$result["function"]."需要參數";
4821
 
4822
			#回傳結果
4823
			return $result;
4824
 
4825
			}#if end
4826
 
4827
		#涵式說明:
4828
		#判斷當前環境為web還是cmd
4829
		#回傳結果:
4830
		#$result,"web"或"cmd"
4831
		if(csInformation::getEnv()==="web"){
4832
 
4833
			#設置執行失敗
4834
			$result["status"]="false";
4835
 
4836
			#設置執行錯誤訊息
4837
			$result["error"][]="函數 ".$result["function"]." 僅能在命令列環境下運行!";
4838
 
4839
			#回傳結果
4840
			return $result;
4841
 
4842
			}#if end
4843
 
4844
		#取得參數
4845
		$result["argu"]=$conf;
4846
 
4847
		#如果 $conf 不為陣列
4848
		if(gettype($conf)!="array"){
4849
 
4850
			#設置執行失敗
4851
			$result["status"]="false";
4852
 
4853
			#設置執行錯誤訊息
4854
			$result["error"][]="\$conf變數須為陣列形態";
4855
 
4856
			#如果傳入的參數為 null
4857
			if($conf==null){
4858
 
4859
				#設置執行錯誤訊息
4860
				$result["error"][]="\$conf變數不得為null,請檢查函數「".$result["function"]."」的參數設置有無正確!";
4861
 
4862
				}#if end
4863
 
4864
			#回傳結果
4865
			return $result;
4866
 
4867
			}#if end
4868
 
4869
		#檢查參數
4870
		#函式說明:
4871
		#檢查必填與可省略的參數,可省略參數可指定預設要給與什麼數值內容。
4872
		#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
4873
		#$reuslt["error"],執行不正常結束的錯訊息陣列.
4874
		#$result["function"],當前執行的函式名稱.
4875
		#$result["argu"],設置給予的參數.
4876
		#$result["passed"],識別要檢查的全體變數是否存在以及型態是否正確的變數,"true"代表檢查全部通過;"false"代表檢查不通過
4877
		#$result[$shouldBeCheckedVarName]["varExist"],所檢查的變數是否存在,"false"代表不存在;"true"代表存在
4878
		#$result[$shouldBeCheckedVarName]["varType"],所檢查的變數型態是否正確,"false"代表錯誤;"true"代表正確
4879
		#$result[$shouldBeCheckedVarName]["error"],每個參數設定的錯誤訊息
4880
		#$result["shouldNotBeEmpty"],不應該為空字串或控陣列的變數.
4881
		#$result["argu"],字串陣列,目前輸入的參數名稱陣列.
4882
		#$result["legalVarName"],字串陣列,合法可用的參數名稱陣列.
4883
		#$result["notNeedVar"],字串陣列,多餘的參數名稱.
4884
		#必填寫的參數:
4885
		#$conf["varInput"],陣列變數,要檢查的陣列變數,請在要檢查的參數前面加上&,這樣變動的結果才能被套用。
4886
		$conf["variableCheck::checkArguments"]["varInput"]=&$conf;	
4887
		#$conf["referenceVarKey"],字串,$conf參數後面的key值,用於移除不要的參考陣列.
4888
		$conf["variableCheck::checkArguments"]["referenceVarKey"]="variableCheck::checkArguments";
4889
		#可以省略的參數:
4890
		#$conf["mustBeFilledVariableName"],爲必填參數的變數名稱陣列,形態爲陣列變數,元素數量需要跟"mustBeFilledVariableType"參數的元素數量一致,例如: $conf["mustBeFilledVariableName"] = array("id","account","password");
4891
		$conf["variableCheck::checkArguments"]["mustBeFilledVariableName"]=array("port");
4892
		#$conf["mustBeFilledVariableType"],爲必填參數的變數陣列應該爲何種變數形態,形態爲陣列,元素數量需要跟"mustBeFilledVariableName"參數的元素數量一致,例如: $conf["mustBeFilledVariableType"] = array("string",integer,"double","resource","object"); , null代表不指定變數形態.
4893
		$conf["variableCheck::checkArguments"]["mustBeFilledVariableType"]=array("integer");
4894
		#$conf["canBeEmptyString"],字串,必填變數內容如果是空字串就不能算是有設置的話,請設為"false",預設爲"true",可以為空字串.
4895
		#$conf["canBeEmptyString"]="false";
4896
		#$conf["canNotBeEmpty"],字串陣列,哪些必填參數的內容不得為空字串或空陣列,僅當$conf["canBeEmptyString"]為"true"時會生效.
4897
		#$conf["canNotBeEmpty"]=array();
4898
		#$conf["canBeEmpty"],字串陣列,哪些必填參數的內容可為空字串或空陣列,僅當$conf["canBeEmptyString"]為"false"時會生效.
4899
		#$conf["canBeEmpty"]=array();
4900
		#$conf["skipableVariableCanNotBeEmpty"],字串陣列,哪些可省略參數不可以為空字串或空陣列.
4901
		$conf["variableCheck::checkArguments"]["skipableVariableCanNotBeEmpty"]=array("ip","welcomeMsg");
4902
		#$conf["skipableVariableName"],陣列字串,爲可省略參數的變數名稱陣列,形態爲陣列變數,例如: $conf["skipableVariableName"] = array("id","account","password");
4903
		$conf["variableCheck::checkArguments"]["skipableVariableName"]=array("ip","processFuncs","welcomeMsg","socketSelectTimeountSec","socketSelectTimeountUsec","serverFuncs");
4904
		#$conf["skipableVariableType"],陣列字串,爲可省略參數的變數名稱陣列,形態爲陣列變數,例如: $conf["skipableVariableType"] = array("string",integer,"double"); 
4905
		$conf["variableCheck::checkArguments"]["skipableVariableType"]=array("string","array","string","integer","integer","array");
4906
		#$conf["skipableVarDefaultValue"],字串陣列,每個不存在的可省略變數要初始化為什麼,null與代表不指定,若預設值是參數之一,請將$conf["mustBeFilledVar"]改成"\$conf["\mustBeFilledVar\"]".
4907
		$conf["variableCheck::checkArguments"]["skipableVarDefaultValue"]=array("0.0.0.0",array(),"true",0,null,null);
4908
		#$conf["disallowAllSkipableVarIsEmpty"],字串,是否允許每個可省略參數都為空字串,預設為"true"允許,反之為"false".
4909
		#$conf["disallowAllSkipableVarIsEmpty"]="";
4910
		#$conf["disallowAllSkipableVarIsEmptyArray"],字串,是否允許每個可省略參數都為空陣列,預設為"true"允許,反之為"false".
4911
		#$conf["disallowAllSkipableVarIsEmptyArray"]="";
4912
		#$conf["arrayCountEqualCheck"],字串陣列,為檢查哪些陣列參數的元素數量要一樣,$conf["arrayCountEqualCheck"][$i]=array()為第$i組key為哪些的變數其元素數量要相等.
4913
		#$conf["arrayCountEqualCheck"][]=array();
4914
		#參考資料來源:
4915
		#array_keys=>http://php.net/manual/en/function.array-keys.php
4916
		$checkArguments=variableCheck::checkArguments($conf["variableCheck::checkArguments"]);
4917
		unset($conf["variableCheck::checkArguments"]);
4918
 
4919
		#如果檢查參數失敗
4920
		if($checkArguments["status"]==="false"){
4921
 
4922
			#設置執行失敗
4923
			$result["status"]="false";
4924
 
4925
			#設置錯誤訊息
4926
			$result["error"]=$checkArguments;
4927
 
4928
			#回傳結果
4929
			return $result;
4930
 
4931
			}#if end
4932
 
4933
		#如果檢查參數不通過
4934
		if($checkArguments["passed"]==="false"){
4935
 
4936
			#設置執行失敗
4937
			$result["status"]="false";
4938
 
4939
			#設置錯誤訊息
4940
			$result["error"]=$checkArguments;
4941
 
4942
			#回傳結果
4943
			return $result;
4944
 
4945
			}#if end
4946
 
4947
		#程式不會 timeout
4948
		set_time_limit(0);
4949
 
4950
		#Turn on implicit output flushing so we see what we're getting as it comes in.
4951
		ob_implicit_flush();
4952
 
4953
		#set listen ip and port
4954
		$address = $conf["ip"];
4955
 
4956
		#set listen port
4957
		$port = $conf["port"];
4958
 
4959
		//如果建立 socket 失敗
4960
		if (($sock = socket_create(AF_INET, SOCK_STREAM, SOL_TCP)) === false) {
4961
 
4962
		    	echo "socket_create() failed: reason: " . socket_strerror(socket_last_error()) . PHP_EOL;
4963
 
4964
			}#if end
4965
 
4966
		//如果 bind socket 失敗
4967
		if (socket_bind($sock, $address, $port) === false) {
4968
 
4969
		    	echo "socket_bind() failed: reason: " . socket_strerror(socket_last_error($sock)) . PHP_EOL;
4970
 
4971
			}#if end
4972
 
4973
		//如果 socket listen 超過 5 秒仍未成功
4974
		if (socket_listen($sock, 5) === false) {
4975
 
4976
		    	echo "socket_listen() failed: reason: " . socket_strerror(socket_last_error($sock)) . PHP_EOL;
4977
 
4978
			}#if end
4979
 
4980
		// create a list of all the clients that will be connected to us..
4981
    		// add the listening socket to this list
4982
    		$clients = array("serverSock"=>$sock);
4983
 
4984
		#無窮迴圈
4985
		do {
4986
			#each resource
4987
			foreach($clients as $rk=>$csock){
4988
 
4989
				#if not socket resource
4990
				if(get_resource_type($csock)!=="Socket"){
4991
 
4992
					#delete
4993
					unset($clients[$rk]);
4994
 
4995
					}#if end
4996
 
4997
				}#foreach end
4998
 
4999
			#found server sock
5000
			$serverSock=false;
5001
 
5002
			#each resource
5003
			foreach($clients as $rk=>$csock){
5004
 
5005
				#if not socket resource
5006
				if($rk==="serverSock"){
5007
 
5008
					#found server sock
5009
					$serverSock=true;
5010
 
5011
					}#if end
5012
 
5013
				}#if end
5014
 
5015
			#not found server sock
5016
			if(!$serverSock){
5017
 
5018
				#end
5019
				exit;
5020
 
5021
				}#if end
5022
 
5023
			#for socket select
5024
			$read   = $clients;
5025
			$write  = NULL;
5026
			$except = NULL;
5027
 
5028
			#如果沒設定微妙
5029
			if(!isset($conf["socketSelectTimeountUsec"])){			
5030
 
5031
				#get interesting socket	
5032
				$num_changed_sockets = socket_select($read, $write, $except, $conf["socketSelectTimeountSec"]);
5033
 
5034
				}#if end
5035
 
5036
			#反之有設定微妙
5037
			else{
5038
 
5039
				#get interesting socket
5040
				$num_changed_sockets = socket_select($read, $write, $except, $conf["socketSelectTimeountSec"], $conf["socketSelectTimeountUsec"]);
5041
 
5042
				}#else end
5043
 
5044
			#socket_select failed
5045
			if ($num_changed_sockets === false) {
5046
 
5047
				#NOTICE to server
5048
				echo "socket_select failed".PHP_EOL;
5049
 
5050
				} 
5051
 
5052
			#At least at one of the sockets something interesting happened
5053
			else if ($num_changed_sockets > 0) {
5054
 
5055
				/* debug		
5056
				echo "At least at one of the sockets something interesting happened".PHP_EOL;
5057
				echo "\$read:".PHP_EOL;var_dump($read);
5058
				echo "\$write:".PHP_EOL;var_dump($write);
5059
				echo "\$except:".PHP_EOL;var_dump($except);
5060
				*/
5061
 
5062
				// check if there is a client trying to connect
5063
				if (in_array($sock, $read)) {
5064
 
5065
					#accept the client, and add him to the $clients array
5066
				   	$clients[] = $newsock = socket_accept($sock);
5067
 
5068
				   	#如果要顯示歡迎訊息
5069
					if($conf["welcomeMsg"]==="true"){
5070
 
5071
				   		#send the client a welcome message
5072
				   		socket_write($newsock, "Welcome to QBPWCF tcpServer".PHP_EOL.
5073
				   		"There are ".(count($clients) - 1)." client(s) connected to the server".PHP_EOL);
5074
 
5075
				   		}#if end
5076
 
5077
					#嘗試取得遠端的ip與port
5078
					#參考資料:https://www.php.net/manual/en/function.socket-getpeername.php
5079
				 	@socket_getpeername($newsock, $ip);
5080
 
5081
					#如果有抓到 $ip
5082
					if(isset($ip)){
5083
 
5084
						#提示有新的使用者
5085
						echo "New client connected: ".$ip.PHP_EOL;
5086
 
5087
						}#if end
5088
 
5089
					// remove the listening socket from the clients-with-data array
5090
					$key = array_search($sock, $read);
5091
					unset($read[$key]);
5092
 
5093
					}
5094
 
5095
				#message received
5096
				else{
5097
 
5098
					// loop through all the clients that have data to read from
5099
					foreach ($read as $read_sock) {
5100
 
5101
						// read until newline or 1024 bytes
5102
						// socket_read while show errors when the client is disconnected, so silence the error messages
5103
						$data = @socket_read($read_sock, 1024, PHP_NORMAL_READ);
5104
 
5105
						// check if the client is disconnected
5106
						if ($data === false) 
5107
						{
5108
							// remove client for $clients array
5109
							$key = array_search($read_sock, $clients);
5110
							unset($clients[$key]);
5111
							echo "client disconnected.".PHP_EOL;
5112
 
5113
							// continue to the next client to read from, if any
5114
							continue;
5115
						}
5116
 
5117
						// trim off the trailing/beginning white spaces
5118
						$data = trim($data);
5119
 
5120
						// check if there is any data after trimming off the spaces
5121
						if(!empty($data)){
5122
 
5123
							// send this to all the clients in the $clients array (except the first one, which is a listening socket)
5124
							foreach ($clients as $send_sock) {
5125
 
5126
								// if its the listening sock or the client that we got the message from, go to the next one in the list
5127
 
5128
								#如果是Server Socket	
5129
								if ($send_sock === $sock){
5130
 
5131
									#server debug
5132
									echo "reveiced:".$data.PHP_EOL;													
5133
 
5134
									#針對每個用來處理輸入字串的函式
5135
									foreach($conf["processFuncs"] as $proFunc){
5136
 
5137
										#呼叫函式,參數為輸入的字串data跟client socket, server socket, 每個 socket
5138
										#https://www.php.net/manual/en/function.call-user-func.php
5139
										$param=array("data"=>$data,"serverSock"=>$sock,"clientSock"=>$read_sock,"allSockArray"=>$clients);
5140
										$params=array();
5141
										$params[]=&$param;										
5142
										$result=call_user_func_array($proFunc,$params);						
5143
 
5144
										#如果有回傳結果
5145
										if($result!==NULL){
5146
 
5147
											#如果執行出錯
5148
											if($result["status"]==="false"){
5149
 
5150
												#印出結果
5151
												var_dump($result);
5152
 
5153
												}
5154
 
5155
											}
5156
 
5157
										}
5158
									}
5159
 
5160
								/*
5161
								#如果是Sender Socket
5162
								else if ($send_sock === $read_sock){
5163
 
5164
									continue;
5165
 
5166
									}
5167
								*/						   
5168
 
5169
								/*
5170
								#msg to others/broadcast
5171
								else{
5172
 
5173
						    			// write the message to the client -- add a newline character to the end of the message
5174
						    			socket_write($send_sock, $data.PHP_EOL);
5175
 
5176
									}//end of broadcast
5177
								*/						   
5178
 
5179
								} //foreach end
5180
 
5181
							}#if end
5182
 
5183
						} // end of reading foreach
5184
 
5185
					}#msg received end
5186
 
5187
				}#something happen end
5188
 
5189
			#反之沒有用戶插手
5190
			else{
5191
				#提示idle
852 liveuser 5192
				#echo "idle:".time().PHP_EOL;
1 liveuser 5193
 
5194
				#如果沒有設置 $conf["serverFuncs"]
5195
				if(!isset($conf["serverFuncs"])){
5196
 
5197
					#設置為空陣列
5198
					$conf["serverFuncs"]=array();
5199
 
5200
					}#if end
5201
 
5202
				#針對每個用來處理輸入字串的函式
5203
				foreach($conf["serverFuncs"] as $proFunc){
5204
 
5205
					#呼叫函式,參數為輸入的字串data跟client socket, server socket, 每個 socket
5206
					#https://www.php.net/manual/en/function.call-user-func.php
5207
					$result=call_user_func_array($proFunc,array());						
5208
 
5209
					#如果有回傳結果
5210
					if($result!==NULL){
5211
 
5212
						#如果執行出錯
5213
						if($result["status"]==="false"){
5214
 
5215
							#印出結果
5216
							var_dump($result);
5217
 
5218
							}//if end
5219
 
5220
						}//if end
5221
 
5222
					}//foreach end
5223
 
5224
				}#else end
5225
 
5226
			} while (true);
5227
 
5228
		#關閉listen的socket
5229
		socket_close($sock);
5230
 
5231
		}
5232
		#function tcpServer end
5233
 
5234
	/*
5235
	#函式說明:
5236
	#建立 udp server
5237
	#必填參數:
5238
	#$conf["port"],整數,udp server listen port.
5239
	$conf["port"]=;
5240
	#可省略參數:
5241
	#$conf["ip"],整數字串,udp serer listen ip, default is 0.0.0.0.
5242
	#$conf["ip"]="0.0.0.0";
5243
	#$conf["processFuncs"],字串陣列,要將收到的訊息作什麼事情的函式們,預設為空陣列.
5244
	#$conf["processFuncs"]=array();
5245
	#$conf["welcomeMsg"],字串,是否要顯示歡迎訊息,預設為"true"代表要顯示歡迎訊息;"false"代表不要顯示歡迎訊息.
5246
	#$conf["welcomeMsg"]="true";
5247
	#$conf["socketSelectTimeountSec"],整數,代表要等候幾秒才抓取有異動的連線,預設為0代表立即抓取有異動的連線,但是會吃很多cpu.
5248
	#$conf["socketSelectTimeountSec"]=0;
5249
	#$conf["socketSelectTimeountUsec"],整數,代表要等候幾微秒才抓取有異動的連線,預設不使用.
5250
	#$conf["socketSelectTimeountUsec"]=5000;
5251
	#參考資料:
5252
	#https://www.jianshu.com/p/097463d08664
57 liveuser 5253
	#備註:
5254
	#無.
1 liveuser 5255
	*/
5256
	public static function udpServer(&$conf){
5257
 
5258
		#初始化要回傳的結果
5259
		$result=array();
5260
 
5261
		#取得當前執行的函數名稱
5262
		$result["function"]=__FUNCTION__;
5263
 
5264
		#如果沒有參數
5265
		if(func_num_args()==0){
5266
 
5267
			#設置執行失敗
5268
			$result["status"]="false";
5269
 
5270
			#設置執行錯誤訊息
5271
			$result["error"]="函數".$result["function"]."需要參數";
5272
 
5273
			#回傳結果
5274
			return $result;
5275
 
5276
			}#if end
5277
 
5278
		#涵式說明:
5279
		#判斷當前環境為web還是cmd
5280
		#回傳結果:
5281
		#$result,"web"或"cmd"
5282
		if(csInformation::getEnv()==="web"){
5283
 
5284
			#設置執行失敗
5285
			$result["status"]="false";
5286
 
5287
			#設置執行錯誤訊息
5288
			$result["error"][]="函數 ".$result["function"]." 僅能在命令列環境下運行!";
5289
 
5290
			#回傳結果
5291
			return $result;
5292
 
5293
			}#if end
5294
 
5295
		#取得參數
5296
		$result["argu"]=$conf;
5297
 
5298
		#如果 $conf 不為陣列
5299
		if(gettype($conf)!="array"){
5300
 
5301
			#設置執行失敗
5302
			$result["status"]="false";
5303
 
5304
			#設置執行錯誤訊息
5305
			$result["error"][]="\$conf變數須為陣列形態";
5306
 
5307
			#如果傳入的參數為 null
5308
			if($conf==null){
5309
 
5310
				#設置執行錯誤訊息
5311
				$result["error"][]="\$conf變數不得為null,請檢查函數「".$result["function"]."」的參數設置有無正確!";
5312
 
5313
				}#if end
5314
 
5315
			#回傳結果
5316
			return $result;
5317
 
5318
			}#if end
5319
 
5320
		#檢查參數
5321
		#函式說明:
5322
		#檢查必填與可省略的參數,可省略參數可指定預設要給與什麼數值內容。
5323
		#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
5324
		#$reuslt["error"],執行不正常結束的錯訊息陣列.
5325
		#$result["function"],當前執行的函式名稱.
5326
		#$result["argu"],設置給予的參數.
5327
		#$result["passed"],識別要檢查的全體變數是否存在以及型態是否正確的變數,"true"代表檢查全部通過;"false"代表檢查不通過
5328
		#$result[$shouldBeCheckedVarName]["varExist"],所檢查的變數是否存在,"false"代表不存在;"true"代表存在
5329
		#$result[$shouldBeCheckedVarName]["varType"],所檢查的變數型態是否正確,"false"代表錯誤;"true"代表正確
5330
		#$result[$shouldBeCheckedVarName]["error"],每個參數設定的錯誤訊息
5331
		#$result["shouldNotBeEmpty"],不應該為空字串或控陣列的變數.
5332
		#$result["argu"],字串陣列,目前輸入的參數名稱陣列.
5333
		#$result["legalVarName"],字串陣列,合法可用的參數名稱陣列.
5334
		#$result["notNeedVar"],字串陣列,多餘的參數名稱.
5335
		#必填寫的參數:
5336
		#$conf["varInput"],陣列變數,要檢查的陣列變數,請在要檢查的參數前面加上&,這樣變動的結果才能被套用。
5337
		$conf["variableCheck::checkArguments"]["varInput"]=&$conf;	
5338
		#$conf["referenceVarKey"],字串,$conf參數後面的key值,用於移除不要的參考陣列.
5339
		$conf["variableCheck::checkArguments"]["referenceVarKey"]="variableCheck::checkArguments";
5340
		#可以省略的參數:
5341
		#$conf["mustBeFilledVariableName"],爲必填參數的變數名稱陣列,形態爲陣列變數,元素數量需要跟"mustBeFilledVariableType"參數的元素數量一致,例如: $conf["mustBeFilledVariableName"] = array("id","account","password");
5342
		$conf["variableCheck::checkArguments"]["mustBeFilledVariableName"]=array("port");
5343
		#$conf["mustBeFilledVariableType"],爲必填參數的變數陣列應該爲何種變數形態,形態爲陣列,元素數量需要跟"mustBeFilledVariableName"參數的元素數量一致,例如: $conf["mustBeFilledVariableType"] = array("string",integer,"double","resource","object"); , null代表不指定變數形態.
5344
		$conf["variableCheck::checkArguments"]["mustBeFilledVariableType"]=array("integer");
5345
		#$conf["canBeEmptyString"],字串,必填變數內容如果是空字串就不能算是有設置的話,請設為"false",預設爲"true",可以為空字串.
5346
		#$conf["canBeEmptyString"]="false";
5347
		#$conf["canNotBeEmpty"],字串陣列,哪些必填參數的內容不得為空字串或空陣列,僅當$conf["canBeEmptyString"]為"true"時會生效.
5348
		#$conf["canNotBeEmpty"]=array();
5349
		#$conf["canBeEmpty"],字串陣列,哪些必填參數的內容可為空字串或空陣列,僅當$conf["canBeEmptyString"]為"false"時會生效.
5350
		#$conf["canBeEmpty"]=array();
5351
		#$conf["skipableVariableCanNotBeEmpty"],字串陣列,哪些可省略參數不可以為空字串或空陣列.
5352
		$conf["variableCheck::checkArguments"]["skipableVariableCanNotBeEmpty"]=array("ip","welcomeMsg","socketSelectTimeountUsec");
5353
		#$conf["skipableVariableName"],陣列字串,爲可省略參數的變數名稱陣列,形態爲陣列變數,例如: $conf["skipableVariableName"] = array("id","account","password");
5354
		$conf["variableCheck::checkArguments"]["skipableVariableName"]=array("ip","processFuncs","welcomeMsg","socketSelectTimeountSec","socketSelectTimeountUsec");
5355
		#$conf["skipableVariableType"],陣列字串,爲可省略參數的變數名稱陣列,形態爲陣列變數,例如: $conf["skipableVariableType"] = array("string",integer,"double"); 
5356
		$conf["variableCheck::checkArguments"]["skipableVariableType"]=array("string","array","string","integer","integer");
5357
		#$conf["skipableVarDefaultValue"],字串陣列,每個不存在的可省略變數要初始化為什麼,null與代表不指定,若預設值是參數之一,請將$conf["mustBeFilledVar"]改成"\$conf["\mustBeFilledVar\"]".
5358
		$conf["variableCheck::checkArguments"]["skipableVarDefaultValue"]=array("0.0.0.0",array(),"true",0,null);
5359
		#$conf["disallowAllSkipableVarIsEmpty"],字串,是否允許每個可省略參數都為空字串,預設為"true"允許,反之為"false".
5360
		#$conf["disallowAllSkipableVarIsEmpty"]="";
5361
		#$conf["disallowAllSkipableVarIsEmptyArray"],字串,是否允許每個可省略參數都為空陣列,預設為"true"允許,反之為"false".
5362
		#$conf["disallowAllSkipableVarIsEmptyArray"]="";
5363
		#$conf["arrayCountEqualCheck"],字串陣列,為檢查哪些陣列參數的元素數量要一樣,$conf["arrayCountEqualCheck"][$i]=array()為第$i組key為哪些的變數其元素數量要相等.
5364
		#$conf["arrayCountEqualCheck"][]=array();
5365
		#參考資料來源:
5366
		#array_keys=>http://php.net/manual/en/function.array-keys.php
5367
		$checkArguments=variableCheck::checkArguments($conf["variableCheck::checkArguments"]);
5368
		unset($conf["variableCheck::checkArguments"]);
5369
 
5370
		#如果檢查參數失敗
5371
		if($checkArguments["status"]==="false"){
5372
 
5373
			#設置執行失敗
5374
			$result["status"]="false";
5375
 
5376
			#設置錯誤訊息
5377
			$result["error"]=$checkArguments;
5378
 
5379
			#回傳結果
5380
			return $result;
5381
 
5382
			}#if end
5383
 
5384
		#如果檢查參數不通過
5385
		if($checkArguments["passed"]==="false"){
5386
 
5387
			#設置執行失敗
5388
			$result["status"]="false";
5389
 
5390
			#設置錯誤訊息
5391
			$result["error"]=$checkArguments;
5392
 
5393
			#回傳結果
5394
			return $result;
5395
 
5396
			}#if end
5397
 
5398
		#Allow the script to hang around waiting for connections.
5399
		set_time_limit(0);
5400
 
5401
		#Turn on implicit output flushing so we see what we're getting as it comes in.
5402
		ob_implicit_flush();
5403
 
5404
		#set listen ip and port
5405
		$address = $conf["ip"];
5406
 
5407
		#set listen port
5408
		$port = $conf["port"];
5409
 
5410
		//如果建立 socket 失敗
5411
		if (($sock = socket_create(AF_INET, SOCK_DGRAM, SOL_UDP)) === false) {
5412
 
5413
		    	echo "socket_create() failed: reason: " . socket_strerror(socket_last_error()) . PHP_EOL;
5414
 
5415
			}#if end
5416
 
5417
		//如果 bind socket 失敗
5418
		if (socket_bind($sock, $address, $port) === false) {
5419
 
5420
		    	echo "socket_bind() failed: reason: " . socket_strerror(socket_last_error($sock)) . PHP_EOL;
5421
 
5422
			}#if end
5423
 
5424
		// create a list of all the clients that will be connected to us..
5425
    		// add the listening socket to this list
5426
    		$clients = array("serverSock"=>$sock);
5427
 
5428
		#無窮迴圈
5429
		do {
5430
			#each resource
5431
			foreach($clients as $rk=>$csock){
5432
 
5433
				#if not socket resource				
5434
				if(gettype($csock)==="boolean"){
5435
 
5436
					#delete
5437
					unset($clients[$rk]);
5438
 
5439
					}
5440
 
5441
				#if not socket resource
5442
				else if(get_resource_type($csock)!=="Socket"){
5443
 
5444
					#delete
5445
					unset($clients[$rk]);
5446
 
5447
					}									
5448
				}
5449
 
5450
			#found server sock
5451
			$serverSock=false;
5452
 
5453
			#each resource
5454
			foreach($clients as $rk=>$csock){
5455
 
5456
				#if not socket resource
5457
				if($rk==="serverSock"){
5458
 
5459
					#found server sock
5460
					$serverSock=true;
5461
 
5462
					}					
5463
				}
5464
 
5465
			#not found server sock
5466
			if(!$serverSock){
5467
 
5468
				#end
5469
				exit;
5470
 
5471
				}
5472
 
5473
			#for socket select
5474
			$read   = $clients;
5475
			$write  = NULL;
5476
			$except = NULL;
5477
 
5478
			#如果未設置 $conf["socketSelectTimeountUsec"]
5479
			if(!isset($conf["socketSelectTimeountUsec"])){
5480
 
5481
				#get interesting socket
5482
				$num_changed_sockets = socket_select($read, $write, $except, $conf["socketSelectTimeountSec"]);
5483
 
5484
				}#if end
5485
 
5486
			#反之有設置 $conf["socketSelectTimeountUsec"]
5487
			else{
5488
 
5489
				#get interesting socket
5490
				$num_changed_sockets = socket_select($read, $write, $except, $conf["socketSelectTimeountSec"], $conf["socketSelectTimeountUsec"]);
5491
 
5492
				}#else end
5493
 
5494
			#socket_select failed
5495
			if ($num_changed_sockets === false) {
5496
 
5497
				#NOTICE to server
5498
				echo "socket_select failed".PHP_EOL;
5499
 
5500
				}#if end
5501
 
5502
			#At least at one of the sockets something interesting happened
5503
			else if ($num_changed_sockets > 0) {
5504
 
5505
				// check if there is a client trying to connect
5506
				if (in_array($sock, $read)) {
5507
 
5508
					#accept the client, and add him to the $clients array
5509
				   	$receivedBytes=socket_recvfrom($sock,$data,1024,0,$remote_ip,$remote_port);	
5510
					$key=$remote_ip.":".$remote_port;
5511
					$clients[$key] = $newsock = $sock;
5512
 
5513
					#如果要顯示歡迎訊息
5514
					if($conf["welcomeMsg"]==="true"){
5515
 
5516
						# send the client a welcome message
5517
					   	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);
5518
 
5519
						}#if end
5520
 
5521
					#debug
5522
					echo "client connected:".$key.PHP_EOL;
5523
					echo "client sended:".$data;
5524
					echo "all client:".PHP_EOL;
5525
					var_dump($clients);				
5526
 
5527
					#針對每個用來處理輸入字串的函式
5528
					foreach($conf["processFuncs"] as $proFunc){
5529
 
5530
						#呼叫函式,參數為輸入的字串data跟client socket, server socket, 每個 socket
5531
						#https://www.php.net/manual/en/function.call-user-func.php
5532
						$param=array("data"=>trim($data),"serverSock"=>$sock,"clientKey"=>$key,"allSockArray"=>&$clients);
5533
						$params=array();
5534
						$params[]=&$param;										
5535
						$result=call_user_func_array($proFunc,$params);						
5536
 
5537
						#如果有回傳結果
5538
						if($result!==NULL){
5539
 
5540
							#如果執行出錯
5541
							if($result["status"]==="false"){
5542
 
5543
								#印出結果
5544
								var_dump($result);
5545
 
5546
								}
5547
 
5548
							}
5549
 
5550
						}
5551
 
854 liveuser 5552
					#debug
1 liveuser 5553
					echo "last all client:".PHP_EOL;
5554
					var_dump($clients);
5555
 
854 liveuser 5556
					# remove the listening socket from the clients-with-data array
5557
					$key = array_search($sock, $read);
5558
					unset($read[$key]);
1 liveuser 5559
 
5560
					}#if end
5561
 
5562
				}#something happen end
5563
 
5564
			} while (true);
5565
 
5566
		#關閉listen的socket
5567
		socket_close($sock);
5568
 
5569
		}
5570
		#function tcpServer end
5571
 
5572
	/*
216 liveuser 5573
	#函式說明:
5574
	#針對收到的內容,原封不動地傳回給用戶.
5575
	#必填參數:
1 liveuser 5576
	#$conf["data"],字串,要處理的內容.
5577
	$conf["data"]="";
5578
	#$conf["clientSock"],resource socket.
5579
	$conf["clientSock"]=;
5580
	#$conf["serverSock"],resource socket.
5581
	$conf["serverSock"]=;
5582
	#$conf["allSockArray"],resource陣列.
5583
	$conf["allSockArray"]=array();
216 liveuser 5584
	#可省略參數:
5585
	#無.
5586
	#參考資料:
5587
	#無.
57 liveuser 5588
	#備註:
5589
	#無.
1 liveuser 5590
	*/
5591
	public function echoService(&$conf){
5592
 
5593
		#初始化要回傳的結果
5594
		$result=array();
5595
 
5596
		#取得當前執行的函數名稱
5597
		$result["function"]=__FUNCTION__;
5598
 
5599
		#如果沒有參數
5600
		if(func_num_args()==0){
5601
 
5602
			#設置執行失敗
5603
			$result["status"]="false";
5604
 
5605
			#設置執行錯誤訊息
5606
			$result["error"]="函數".$result["function"]."需要參數";
5607
 
5608
			#回傳結果
5609
			return $result;
5610
 
5611
			}#if end
5612
 
5613
		#涵式說明:
5614
		#判斷當前環境為web還是cmd
5615
		#回傳結果:
5616
		#$result,"web"或"cmd"
5617
		if(csInformation::getEnv()==="web"){
5618
 
5619
			#設置執行失敗
5620
			$result["status"]="false";
5621
 
5622
			#設置執行錯誤訊息
5623
			$result["error"][]="函數 ".$result["function"]." 僅能在命令列環境下運行!";
5624
 
5625
			#回傳結果
5626
			return $result;
5627
 
5628
			}#if end
5629
 
5630
		#取得參數
5631
		$result["argu"]=$conf;
5632
 
5633
		#如果 $conf 不為陣列
5634
		if(gettype($conf)!="array"){
5635
 
5636
			#設置執行失敗
5637
			$result["status"]="false";
5638
 
5639
			#設置執行錯誤訊息
5640
			$result["error"][]="\$conf變數須為陣列形態";
5641
 
5642
			#如果傳入的參數為 null
5643
			if($conf==null){
5644
 
5645
				#設置執行錯誤訊息
5646
				$result["error"][]="\$conf變數不得為null,請檢查函數「".$result["function"]."」的參數設置有無正確!";
5647
 
5648
				}#if end
5649
 
5650
			#回傳結果
5651
			return $result;
5652
 
5653
			}#if end
5654
 
5655
		#檢查參數
5656
		#函式說明:
5657
		#檢查必填與可省略的參數,可省略參數可指定預設要給與什麼數值內容。
5658
		#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
5659
		#$reuslt["error"],執行不正常結束的錯訊息陣列.
5660
		#$result["function"],當前執行的函式名稱.
5661
		#$result["argu"],設置給予的參數.
5662
		#$result["passed"],識別要檢查的全體變數是否存在以及型態是否正確的變數,"true"代表檢查全部通過;"false"代表檢查不通過
5663
		#$result[$shouldBeCheckedVarName]["varExist"],所檢查的變數是否存在,"false"代表不存在;"true"代表存在
5664
		#$result[$shouldBeCheckedVarName]["varType"],所檢查的變數型態是否正確,"false"代表錯誤;"true"代表正確
5665
		#$result[$shouldBeCheckedVarName]["error"],每個參數設定的錯誤訊息
5666
		#$result["shouldNotBeEmpty"],不應該為空字串或控陣列的變數.
5667
		#$result["argu"],字串陣列,目前輸入的參數名稱陣列.
5668
		#$result["legalVarName"],字串陣列,合法可用的參數名稱陣列.
5669
		#$result["notNeedVar"],字串陣列,多餘的參數名稱.
5670
		#必填寫的參數:
5671
		#$conf["varInput"],陣列變數,要檢查的陣列變數,請在要檢查的參數前面加上&,這樣變動的結果才能被套用。
5672
		$conf["variableCheck::checkArguments"]["varInput"]=&$conf;	
5673
		#$conf["referenceVarKey"],字串,$conf參數後面的key值,用於移除不要的參考陣列.
5674
		$conf["variableCheck::checkArguments"]["referenceVarKey"]="variableCheck::checkArguments";
5675
		#可以省略的參數:
5676
		#$conf["mustBeFilledVariableName"],爲必填參數的變數名稱陣列,形態爲陣列變數,元素數量需要跟"mustBeFilledVariableType"參數的元素數量一致,例如: $conf["mustBeFilledVariableName"] = array("id","account","password");
5677
		$conf["variableCheck::checkArguments"]["mustBeFilledVariableName"]=array("data","clientSock","serverSock","allSockArray");
5678
		#$conf["mustBeFilledVariableType"],爲必填參數的變數陣列應該爲何種變數形態,形態爲陣列,元素數量需要跟"mustBeFilledVariableName"參數的元素數量一致,例如: $conf["mustBeFilledVariableType"] = array("string",integer,"double","resource","object"); , null代表不指定變數形態.
5679
		$conf["variableCheck::checkArguments"]["mustBeFilledVariableType"]=array("string","resource","resource","array");
5680
		#$conf["canBeEmptyString"],字串,必填變數內容如果是空字串就不能算是有設置的話,請設為"false",預設爲"true",可以為空字串.
5681
		#$conf["canBeEmptyString"]="false";
5682
		#$conf["canNotBeEmpty"],字串陣列,哪些必填參數的內容不得為空字串或空陣列,僅當$conf["canBeEmptyString"]為"true"時會生效.
5683
		#$conf["canNotBeEmpty"]=array();
5684
		#$conf["canBeEmpty"],字串陣列,哪些必填參數的內容可為空字串或空陣列,僅當$conf["canBeEmptyString"]為"false"時會生效.
5685
		#$conf["canBeEmpty"]=array();
5686
		#$conf["skipableVariableCanNotBeEmpty"],字串陣列,哪些可省略參數不可以為空字串或空陣列.
5687
		#$conf["variableCheck::checkArguments"]["skipableVariableCanNotBeEmpty"]=array("ip");
5688
		#$conf["skipableVariableName"],陣列字串,爲可省略參數的變數名稱陣列,形態爲陣列變數,例如: $conf["skipableVariableName"] = array("id","account","password");
5689
		#$conf["variableCheck::checkArguments"]["skipableVariableName"]=array("ip","processFuncs");
5690
		#$conf["skipableVariableType"],陣列字串,爲可省略參數的變數名稱陣列,形態爲陣列變數,例如: $conf["skipableVariableType"] = array("string",integer,"double"); 
5691
		#$conf["variableCheck::checkArguments"]["skipableVariableType"]=array("string","array");
5692
		#$conf["skipableVarDefaultValue"],字串陣列,每個不存在的可省略變數要初始化為什麼,null與代表不指定,若預設值是參數之一,請將$conf["mustBeFilledVar"]改成"\$conf["\mustBeFilledVar\"]".
5693
		#$conf["variableCheck::checkArguments"]["skipableVarDefaultValue"]=array("0.0.0.0",array());
5694
		#$conf["disallowAllSkipableVarIsEmpty"],字串,是否允許每個可省略參數都為空字串,預設為"true"允許,反之為"false".
5695
		#$conf["disallowAllSkipableVarIsEmpty"]="";
5696
		#$conf["disallowAllSkipableVarIsEmptyArray"],字串,是否允許每個可省略參數都為空陣列,預設為"true"允許,反之為"false".
5697
		#$conf["disallowAllSkipableVarIsEmptyArray"]="";
5698
		#$conf["arrayCountEqualCheck"],字串陣列,為檢查哪些陣列參數的元素數量要一樣,$conf["arrayCountEqualCheck"][$i]=array()為第$i組key為哪些的變數其元素數量要相等.
5699
		#$conf["arrayCountEqualCheck"][]=array();
5700
		#參考資料來源:
5701
		#array_keys=>http://php.net/manual/en/function.array-keys.php
5702
		$checkArguments=variableCheck::checkArguments($conf["variableCheck::checkArguments"]);
5703
		unset($conf["variableCheck::checkArguments"]);
5704
 
5705
		#如果檢查參數失敗
5706
		if($checkArguments["status"]==="false"){
5707
 
5708
			#設置執行失敗
5709
			$result["status"]="false";
5710
 
5711
			#設置錯誤訊息
5712
			$result["error"]=$checkArguments;
5713
 
5714
			#回傳結果
5715
			return $result;
5716
 
5717
			}#if end
5718
 
5719
		#如果檢查參數不通過
5720
		if($checkArguments["passed"]==="false"){
5721
 
5722
			#設置執行失敗
5723
			$result["status"]="false";
5724
 
5725
			#設置錯誤訊息
5726
			$result["error"]=$checkArguments;
5727
 
5728
			#回傳結果
5729
			return $result;
5730
 
5731
			}#if end
5732
 
5733
		#將內容原封不動還給 client
5734
		@socket_write($conf["clientSock"], $conf["data"].PHP_EOL);
5735
 
5736
		}#function echoService end
5737
 
5738
	/*
57 liveuser 5739
	#函式說明:
5740
	#針對收到的內容,原封不動地傳回給用戶.協定為UDP.
5741
	#回傳結果:
5742
	#無.
5743
	#必填參數:
1 liveuser 5744
	#$conf["data"],字串,要處理的內容.
5745
	$conf["data"]="";
5746
	#$conf["clientKey"],resource socket key
5747
	$conf["clientKey"]=;
5748
	#$conf["serverSock"],resource socket.
5749
	$conf["serverSock"]=;
5750
	#$conf["allSockArray"],resource陣列.
5751
	$conf["allSockArray"]=array();
57 liveuser 5752
	#可省略參數:
5753
	#無.
216 liveuser 5754
	#參考資料:
5755
	#無.
57 liveuser 5756
	#備註:
5757
	#無.
1 liveuser 5758
	*/
5759
	public function echoServiceU(&$conf){
5760
 
5761
		#初始化要回傳的結果
5762
		$result=array();
5763
 
5764
		#取得當前執行的函數名稱
5765
		$result["function"]=__FUNCTION__;
5766
 
5767
		#如果沒有參數
5768
		if(func_num_args()==0){
5769
 
5770
			#設置執行失敗
5771
			$result["status"]="false";
5772
 
5773
			#設置執行錯誤訊息
5774
			$result["error"]="函數".$result["function"]."需要參數";
5775
 
5776
			#回傳結果
5777
			return $result;
5778
 
5779
			}#if end
5780
 
5781
		#涵式說明:
5782
		#判斷當前環境為web還是cmd
5783
		#回傳結果:
5784
		#$result,"web"或"cmd"
5785
		if(csInformation::getEnv()==="web"){
5786
 
5787
			#設置執行失敗
5788
			$result["status"]="false";
5789
 
5790
			#設置執行錯誤訊息
5791
			$result["error"][]="函數 ".$result["function"]." 僅能在命令列環境下運行!";
5792
 
5793
			#回傳結果
5794
			return $result;
5795
 
5796
			}#if end
5797
 
5798
		#取得參數
5799
		$result["argu"]=$conf;
5800
 
5801
		#如果 $conf 不為陣列
5802
		if(gettype($conf)!="array"){
5803
 
5804
			#設置執行失敗
5805
			$result["status"]="false";
5806
 
5807
			#設置執行錯誤訊息
5808
			$result["error"][]="\$conf變數須為陣列形態";
5809
 
5810
			#如果傳入的參數為 null
5811
			if($conf==null){
5812
 
5813
				#設置執行錯誤訊息
5814
				$result["error"][]="\$conf變數不得為null,請檢查函數「".$result["function"]."」的參數設置有無正確!";
5815
 
5816
				}#if end
5817
 
5818
			#回傳結果
5819
			return $result;
5820
 
5821
			}#if end
5822
 
5823
		#檢查參數
5824
		#函式說明:
5825
		#檢查必填與可省略的參數,可省略參數可指定預設要給與什麼數值內容。
5826
		#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
5827
		#$reuslt["error"],執行不正常結束的錯訊息陣列.
5828
		#$result["function"],當前執行的函式名稱.
5829
		#$result["argu"],設置給予的參數.
5830
		#$result["passed"],識別要檢查的全體變數是否存在以及型態是否正確的變數,"true"代表檢查全部通過;"false"代表檢查不通過
5831
		#$result[$shouldBeCheckedVarName]["varExist"],所檢查的變數是否存在,"false"代表不存在;"true"代表存在
5832
		#$result[$shouldBeCheckedVarName]["varType"],所檢查的變數型態是否正確,"false"代表錯誤;"true"代表正確
5833
		#$result[$shouldBeCheckedVarName]["error"],每個參數設定的錯誤訊息
5834
		#$result["shouldNotBeEmpty"],不應該為空字串或控陣列的變數.
5835
		#$result["argu"],字串陣列,目前輸入的參數名稱陣列.
5836
		#$result["legalVarName"],字串陣列,合法可用的參數名稱陣列.
5837
		#$result["notNeedVar"],字串陣列,多餘的參數名稱.
5838
		#必填寫的參數:
5839
		#$conf["varInput"],陣列變數,要檢查的陣列變數,請在要檢查的參數前面加上&,這樣變動的結果才能被套用。
5840
		$conf["variableCheck::checkArguments"]["varInput"]=&$conf;	
5841
		#$conf["referenceVarKey"],字串,$conf參數後面的key值,用於移除不要的參考陣列.
5842
		$conf["variableCheck::checkArguments"]["referenceVarKey"]="variableCheck::checkArguments";
5843
		#可以省略的參數:
5844
		#$conf["mustBeFilledVariableName"],爲必填參數的變數名稱陣列,形態爲陣列變數,元素數量需要跟"mustBeFilledVariableType"參數的元素數量一致,例如: $conf["mustBeFilledVariableName"] = array("id","account","password");
5845
		$conf["variableCheck::checkArguments"]["mustBeFilledVariableName"]=array("data","clientKey","serverSock","allSockArray");
5846
		#$conf["mustBeFilledVariableType"],爲必填參數的變數陣列應該爲何種變數形態,形態爲陣列,元素數量需要跟"mustBeFilledVariableName"參數的元素數量一致,例如: $conf["mustBeFilledVariableType"] = array("string",integer,"double","resource","object"); , null代表不指定變數形態.
5847
		$conf["variableCheck::checkArguments"]["mustBeFilledVariableType"]=array("string","string","resource","array");
5848
		#$conf["canBeEmptyString"],字串,必填變數內容如果是空字串就不能算是有設置的話,請設為"false",預設爲"true",可以為空字串.
5849
		#$conf["canBeEmptyString"]="false";
5850
		#$conf["canNotBeEmpty"],字串陣列,哪些必填參數的內容不得為空字串或空陣列,僅當$conf["canBeEmptyString"]為"true"時會生效.
5851
		#$conf["canNotBeEmpty"]=array();
5852
		#$conf["canBeEmpty"],字串陣列,哪些必填參數的內容可為空字串或空陣列,僅當$conf["canBeEmptyString"]為"false"時會生效.
5853
		#$conf["canBeEmpty"]=array();
5854
		#$conf["skipableVariableCanNotBeEmpty"],字串陣列,哪些可省略參數不可以為空字串或空陣列.
5855
		#$conf["variableCheck::checkArguments"]["skipableVariableCanNotBeEmpty"]=array("ip");
5856
		#$conf["skipableVariableName"],陣列字串,爲可省略參數的變數名稱陣列,形態爲陣列變數,例如: $conf["skipableVariableName"] = array("id","account","password");
5857
		#$conf["variableCheck::checkArguments"]["skipableVariableName"]=array("ip","processFuncs");
5858
		#$conf["skipableVariableType"],陣列字串,爲可省略參數的變數名稱陣列,形態爲陣列變數,例如: $conf["skipableVariableType"] = array("string",integer,"double"); 
5859
		#$conf["variableCheck::checkArguments"]["skipableVariableType"]=array("string","array");
5860
		#$conf["skipableVarDefaultValue"],字串陣列,每個不存在的可省略變數要初始化為什麼,null與代表不指定,若預設值是參數之一,請將$conf["mustBeFilledVar"]改成"\$conf["\mustBeFilledVar\"]".
5861
		#$conf["variableCheck::checkArguments"]["skipableVarDefaultValue"]=array("0.0.0.0",array());
5862
		#$conf["disallowAllSkipableVarIsEmpty"],字串,是否允許每個可省略參數都為空字串,預設為"true"允許,反之為"false".
5863
		#$conf["disallowAllSkipableVarIsEmpty"]="";
5864
		#$conf["disallowAllSkipableVarIsEmptyArray"],字串,是否允許每個可省略參數都為空陣列,預設為"true"允許,反之為"false".
5865
		#$conf["disallowAllSkipableVarIsEmptyArray"]="";
5866
		#$conf["arrayCountEqualCheck"],字串陣列,為檢查哪些陣列參數的元素數量要一樣,$conf["arrayCountEqualCheck"][$i]=array()為第$i組key為哪些的變數其元素數量要相等.
5867
		#$conf["arrayCountEqualCheck"][]=array();
5868
		#參考資料來源:
5869
		#array_keys=>http://php.net/manual/en/function.array-keys.php
5870
		$checkArguments=variableCheck::checkArguments($conf["variableCheck::checkArguments"]);
5871
		unset($conf["variableCheck::checkArguments"]);
5872
 
5873
		#如果檢查參數失敗
5874
		if($checkArguments["status"]==="false"){
5875
 
5876
			#設置執行失敗
5877
			$result["status"]="false";
5878
 
5879
			#設置錯誤訊息
5880
			$result["error"]=$checkArguments;
5881
 
5882
			#回傳結果
5883
			return $result;
5884
 
5885
			}#if end
5886
 
5887
		#如果檢查參數不通過
5888
		if($checkArguments["passed"]==="false"){
5889
 
5890
			#設置執行失敗
5891
			$result["status"]="false";
5892
 
5893
			#設置錯誤訊息
5894
			$result["error"]=$checkArguments;
5895
 
5896
			#回傳結果
5897
			return $result;
5898
 
5899
			}#if end
5900
 
5901
		#將內容原封不動還給 client
5902
		$strArray=explode(":",$conf["clientKey"]);
5903
		$remote_ip=$strArray[0];
5904
		$remote_port=$strArray[1];
5905
		socket_sendto($conf["serverSock"], $conf["data"].PHP_EOL, 1024, 0, $remote_ip, $remote_port);
5906
 
5907
		}#function echoServiceU end
5908
 
5909
	/*
57 liveuser 5910
	#函式說明:
5911
	#針對收到的內容,若是"quit"則斷開用戶的連線,若是"shutdown"則關閉Server Listen的socket.
5912
	#回傳結果:
5913
	#無.
5914
	#必填參數:
1 liveuser 5915
	#$conf["data"],字串,要處理的內容.
5916
	$conf["data"]="";
5917
	#$conf["clientSock"],resource socket.
5918
	$conf["clientSock"]=;
5919
	#$conf["serverSock"],resource socket.
5920
	$conf["serverSock"]=;
5921
	#$conf["allSockArray"],resource陣列.
5922
	$conf["allSockArray"]=array();
57 liveuser 5923
	#可省略參數:
5924
	#無.
216 liveuser 5925
	#參考資料:
5926
	#無.
57 liveuser 5927
	#備註:
5928
	#無.
1 liveuser 5929
	*/
5930
	public function endService(&$conf){
5931
 
5932
		#初始化要回傳的結果
5933
		$result=array();
5934
 
5935
		#取得當前執行的函數名稱
5936
		$result["function"]=__FUNCTION__;
5937
 
5938
		#如果沒有參數
5939
		if(func_num_args()==0){
5940
 
5941
			#設置執行失敗
5942
			$result["status"]="false";
5943
 
5944
			#設置執行錯誤訊息
5945
			$result["error"]="函數".$result["function"]."需要參數";
5946
 
5947
			#回傳結果
5948
			return $result;
5949
 
5950
			}#if end
5951
 
5952
		#涵式說明:
5953
		#判斷當前環境為web還是cmd
5954
		#回傳結果:
5955
		#$result,"web"或"cmd"
5956
		if(csInformation::getEnv()==="web"){
5957
 
5958
			#設置執行失敗
5959
			$result["status"]="false";
5960
 
5961
			#設置執行錯誤訊息
5962
			$result["error"][]="函數 ".$result["function"]." 僅能在命令列環境下運行!";
5963
 
5964
			#回傳結果
5965
			return $result;
5966
 
5967
			}#if end
5968
 
5969
		#取得參數
5970
		$result["argu"]=$conf;
5971
 
5972
		#如果 $conf 不為陣列
5973
		if(gettype($conf)!="array"){
5974
 
5975
			#設置執行失敗
5976
			$result["status"]="false";
5977
 
5978
			#設置執行錯誤訊息
5979
			$result["error"][]="\$conf變數須為陣列形態";
5980
 
5981
			#如果傳入的參數為 null
5982
			if($conf==null){
5983
 
5984
				#設置執行錯誤訊息
5985
				$result["error"][]="\$conf變數不得為null,請檢查函數「".$result["function"]."」的參數設置有無正確!";
5986
 
5987
				}#if end
5988
 
5989
			#回傳結果
5990
			return $result;
5991
 
5992
			}#if end
5993
 
5994
		#檢查參數
5995
		#函式說明:
5996
		#檢查必填與可省略的參數,可省略參數可指定預設要給與什麼數值內容。
5997
		#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
5998
		#$reuslt["error"],執行不正常結束的錯訊息陣列.
5999
		#$result["function"],當前執行的函式名稱.
6000
		#$result["argu"],設置給予的參數.
6001
		#$result["passed"],識別要檢查的全體變數是否存在以及型態是否正確的變數,"true"代表檢查全部通過;"false"代表檢查不通過
6002
		#$result[$shouldBeCheckedVarName]["varExist"],所檢查的變數是否存在,"false"代表不存在;"true"代表存在
6003
		#$result[$shouldBeCheckedVarName]["varType"],所檢查的變數型態是否正確,"false"代表錯誤;"true"代表正確
6004
		#$result[$shouldBeCheckedVarName]["error"],每個參數設定的錯誤訊息
6005
		#$result["shouldNotBeEmpty"],不應該為空字串或控陣列的變數.
6006
		#$result["argu"],字串陣列,目前輸入的參數名稱陣列.
6007
		#$result["legalVarName"],字串陣列,合法可用的參數名稱陣列.
6008
		#$result["notNeedVar"],字串陣列,多餘的參數名稱.
6009
		#必填寫的參數:
6010
		#$conf["varInput"],陣列變數,要檢查的陣列變數,請在要檢查的參數前面加上&,這樣變動的結果才能被套用。
6011
		$conf["variableCheck::checkArguments"]["varInput"]=&$conf;	
6012
		#$conf["referenceVarKey"],字串,$conf參數後面的key值,用於移除不要的參考陣列.
6013
		$conf["variableCheck::checkArguments"]["referenceVarKey"]="variableCheck::checkArguments";
6014
		#可以省略的參數:
6015
		#$conf["mustBeFilledVariableName"],爲必填參數的變數名稱陣列,形態爲陣列變數,元素數量需要跟"mustBeFilledVariableType"參數的元素數量一致,例如: $conf["mustBeFilledVariableName"] = array("id","account","password");
6016
		$conf["variableCheck::checkArguments"]["mustBeFilledVariableName"]=array("data","clientSock","serverSock","allSockArray");
6017
		#$conf["mustBeFilledVariableType"],爲必填參數的變數陣列應該爲何種變數形態,形態爲陣列,元素數量需要跟"mustBeFilledVariableName"參數的元素數量一致,例如: $conf["mustBeFilledVariableType"] = array("string",integer,"double","resource","object"); , null代表不指定變數形態.
6018
		$conf["variableCheck::checkArguments"]["mustBeFilledVariableType"]=array("string","resource","resource","array");
6019
		#$conf["canBeEmptyString"],字串,必填變數內容如果是空字串就不能算是有設置的話,請設為"false",預設爲"true",可以為空字串.
6020
		#$conf["canBeEmptyString"]="false";
6021
		#$conf["canNotBeEmpty"],字串陣列,哪些必填參數的內容不得為空字串或空陣列,僅當$conf["canBeEmptyString"]為"true"時會生效.
6022
		#$conf["canNotBeEmpty"]=array();
6023
		#$conf["canBeEmpty"],字串陣列,哪些必填參數的內容可為空字串或空陣列,僅當$conf["canBeEmptyString"]為"false"時會生效.
6024
		#$conf["canBeEmpty"]=array();
6025
		#$conf["skipableVariableCanNotBeEmpty"],字串陣列,哪些可省略參數不可以為空字串或空陣列.
6026
		#$conf["variableCheck::checkArguments"]["skipableVariableCanNotBeEmpty"]=array("ip");
6027
		#$conf["skipableVariableName"],陣列字串,爲可省略參數的變數名稱陣列,形態爲陣列變數,例如: $conf["skipableVariableName"] = array("id","account","password");
6028
		#$conf["variableCheck::checkArguments"]["skipableVariableName"]=array("ip","processFuncs");
6029
		#$conf["skipableVariableType"],陣列字串,爲可省略參數的變數名稱陣列,形態爲陣列變數,例如: $conf["skipableVariableType"] = array("string",integer,"double"); 
6030
		#$conf["variableCheck::checkArguments"]["skipableVariableType"]=array("string","array");
6031
		#$conf["skipableVarDefaultValue"],字串陣列,每個不存在的可省略變數要初始化為什麼,null與代表不指定,若預設值是參數之一,請將$conf["mustBeFilledVar"]改成"\$conf["\mustBeFilledVar\"]".
6032
		#$conf["variableCheck::checkArguments"]["skipableVarDefaultValue"]=array("0.0.0.0",array());
6033
		#$conf["disallowAllSkipableVarIsEmpty"],字串,是否允許每個可省略參數都為空字串,預設為"true"允許,反之為"false".
6034
		#$conf["disallowAllSkipableVarIsEmpty"]="";
6035
		#$conf["disallowAllSkipableVarIsEmptyArray"],字串,是否允許每個可省略參數都為空陣列,預設為"true"允許,反之為"false".
6036
		#$conf["disallowAllSkipableVarIsEmptyArray"]="";
6037
		#$conf["arrayCountEqualCheck"],字串陣列,為檢查哪些陣列參數的元素數量要一樣,$conf["arrayCountEqualCheck"][$i]=array()為第$i組key為哪些的變數其元素數量要相等.
6038
		#$conf["arrayCountEqualCheck"][]=array();
6039
		#參考資料來源:
6040
		#array_keys=>http://php.net/manual/en/function.array-keys.php
6041
		$checkArguments=variableCheck::checkArguments($conf["variableCheck::checkArguments"]);
6042
		unset($conf["variableCheck::checkArguments"]);
6043
 
6044
		#如果檢查參數失敗
6045
		if($checkArguments["status"]==="false"){
6046
 
6047
			#設置執行失敗
6048
			$result["status"]="false";
6049
 
6050
			#設置錯誤訊息
6051
			$result["error"]=$checkArguments;
6052
 
6053
			#回傳結果
6054
			return $result;
6055
 
6056
			}#if end
6057
 
6058
		#如果檢查參數不通過
6059
		if($checkArguments["passed"]==="false"){
6060
 
6061
			#設置執行失敗
6062
			$result["status"]="false";
6063
 
6064
			#設置錯誤訊息
6065
			$result["error"]=$checkArguments;
6066
 
6067
			#回傳結果
6068
			return $result;
6069
 
6070
			}#if end
6071
 
6072
		#針對輸入的內容
6073
		switch($conf["data"]){
6074
 
6075
			#如果是 "quit"
6076
			case "quit":
6077
 
6078
				#關閉與用戶之間的連線
6079
				socket_close($conf["clientSock"]);
6080
 
6081
				break;
6082
 
6083
			#如果是 "shutdown"
6084
			case "shutdown":
6085
 
6086
				#關閉 Server Listen 的 sock
6087
				socket_close($conf["serverSock"]);
6088
 
6089
				break;
6090
 
6091
			default:
6092
 
6093
			}#switch end
6094
 
6095
		}#function endService end
6096
 
6097
	/*
57 liveuser 6098
	#函式說明:
6099
	#針對收到的內容,若是"quit"則斷開用戶的連線,若是"shutdown"則關閉Server Listen的socket,協定為UDP.
6100
	#回傳結果:
6101
	#無.
6102
	#必填參數:
1 liveuser 6103
	#$conf["data"],字串,要處理的內容.
6104
	$conf["data"]="";
6105
	#$conf["clientKey"],resource socket key.
6106
	$conf["clientKey"]=;
6107
	#$conf["serverSock"],resource socket.
6108
	$conf["serverSock"]=;
6109
	#$conf["allSockArray"],resource陣列.
6110
	$conf["allSockArray"]=array();
57 liveuser 6111
	#可省略參數:
6112
	#無.
216 liveuser 6113
	#參考資料:
6114
	#無.
57 liveuser 6115
	#備註:
6116
	#無.
1 liveuser 6117
	*/
6118
	public function endServiceU(&$conf){
6119
 
6120
		#初始化要回傳的結果
6121
		$result=array();
6122
 
6123
		#取得當前執行的函數名稱
6124
		$result["function"]=__FUNCTION__;
6125
 
6126
		#如果沒有參數
6127
		if(func_num_args()==0){
6128
 
6129
			#設置執行失敗
6130
			$result["status"]="false";
6131
 
6132
			#設置執行錯誤訊息
6133
			$result["error"]="函數".$result["function"]."需要參數";
6134
 
6135
			#回傳結果
6136
			return $result;
6137
 
6138
			}#if end
6139
 
6140
		#涵式說明:
6141
		#判斷當前環境為web還是cmd
6142
		#回傳結果:
6143
		#$result,"web"或"cmd"
6144
		if(csInformation::getEnv()==="web"){
6145
 
6146
			#設置執行失敗
6147
			$result["status"]="false";
6148
 
6149
			#設置執行錯誤訊息
6150
			$result["error"][]="函數 ".$result["function"]." 僅能在命令列環境下運行!";
6151
 
6152
			#回傳結果
6153
			return $result;
6154
 
6155
			}#if end
6156
 
6157
		#取得參數
6158
		$result["argu"]=$conf;
6159
 
6160
		#如果 $conf 不為陣列
6161
		if(gettype($conf)!="array"){
6162
 
6163
			#設置執行失敗
6164
			$result["status"]="false";
6165
 
6166
			#設置執行錯誤訊息
6167
			$result["error"][]="\$conf變數須為陣列形態";
6168
 
6169
			#如果傳入的參數為 null
6170
			if($conf==null){
6171
 
6172
				#設置執行錯誤訊息
6173
				$result["error"][]="\$conf變數不得為null,請檢查函數「".$result["function"]."」的參數設置有無正確!";
6174
 
6175
				}#if end
6176
 
6177
			#回傳結果
6178
			return $result;
6179
 
6180
			}#if end
6181
 
6182
		#檢查參數
6183
		#函式說明:
6184
		#檢查必填與可省略的參數,可省略參數可指定預設要給與什麼數值內容。
6185
		#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
6186
		#$reuslt["error"],執行不正常結束的錯訊息陣列.
6187
		#$result["function"],當前執行的函式名稱.
6188
		#$result["argu"],設置給予的參數.
6189
		#$result["passed"],識別要檢查的全體變數是否存在以及型態是否正確的變數,"true"代表檢查全部通過;"false"代表檢查不通過
6190
		#$result[$shouldBeCheckedVarName]["varExist"],所檢查的變數是否存在,"false"代表不存在;"true"代表存在
6191
		#$result[$shouldBeCheckedVarName]["varType"],所檢查的變數型態是否正確,"false"代表錯誤;"true"代表正確
6192
		#$result[$shouldBeCheckedVarName]["error"],每個參數設定的錯誤訊息
6193
		#$result["shouldNotBeEmpty"],不應該為空字串或控陣列的變數.
6194
		#$result["argu"],字串陣列,目前輸入的參數名稱陣列.
6195
		#$result["legalVarName"],字串陣列,合法可用的參數名稱陣列.
6196
		#$result["notNeedVar"],字串陣列,多餘的參數名稱.
6197
		#必填寫的參數:
6198
		#$conf["varInput"],陣列變數,要檢查的陣列變數,請在要檢查的參數前面加上&,這樣變動的結果才能被套用。
6199
		$conf["variableCheck::checkArguments"]["varInput"]=&$conf;	
6200
		#$conf["referenceVarKey"],字串,$conf參數後面的key值,用於移除不要的參考陣列.
6201
		$conf["variableCheck::checkArguments"]["referenceVarKey"]="variableCheck::checkArguments";
6202
		#可以省略的參數:
6203
		#$conf["mustBeFilledVariableName"],爲必填參數的變數名稱陣列,形態爲陣列變數,元素數量需要跟"mustBeFilledVariableType"參數的元素數量一致,例如: $conf["mustBeFilledVariableName"] = array("id","account","password");
6204
		$conf["variableCheck::checkArguments"]["mustBeFilledVariableName"]=array("data","clientKey","serverSock","allSockArray");
6205
		#$conf["mustBeFilledVariableType"],爲必填參數的變數陣列應該爲何種變數形態,形態爲陣列,元素數量需要跟"mustBeFilledVariableName"參數的元素數量一致,例如: $conf["mustBeFilledVariableType"] = array("string",integer,"double","resource","object"); , null代表不指定變數形態.
6206
		$conf["variableCheck::checkArguments"]["mustBeFilledVariableType"]=array("string","string","resource","array");
6207
		#$conf["canBeEmptyString"],字串,必填變數內容如果是空字串就不能算是有設置的話,請設為"false",預設爲"true",可以為空字串.
6208
		#$conf["canBeEmptyString"]="false";
6209
		#$conf["canNotBeEmpty"],字串陣列,哪些必填參數的內容不得為空字串或空陣列,僅當$conf["canBeEmptyString"]為"true"時會生效.
6210
		#$conf["canNotBeEmpty"]=array();
6211
		#$conf["canBeEmpty"],字串陣列,哪些必填參數的內容可為空字串或空陣列,僅當$conf["canBeEmptyString"]為"false"時會生效.
6212
		#$conf["canBeEmpty"]=array();
6213
		#$conf["skipableVariableCanNotBeEmpty"],字串陣列,哪些可省略參數不可以為空字串或空陣列.
6214
		#$conf["variableCheck::checkArguments"]["skipableVariableCanNotBeEmpty"]=array("ip");
6215
		#$conf["skipableVariableName"],陣列字串,爲可省略參數的變數名稱陣列,形態爲陣列變數,例如: $conf["skipableVariableName"] = array("id","account","password");
6216
		#$conf["variableCheck::checkArguments"]["skipableVariableName"]=array("ip","processFuncs");
6217
		#$conf["skipableVariableType"],陣列字串,爲可省略參數的變數名稱陣列,形態爲陣列變數,例如: $conf["skipableVariableType"] = array("string",integer,"double"); 
6218
		#$conf["variableCheck::checkArguments"]["skipableVariableType"]=array("string","array");
6219
		#$conf["skipableVarDefaultValue"],字串陣列,每個不存在的可省略變數要初始化為什麼,null與代表不指定,若預設值是參數之一,請將$conf["mustBeFilledVar"]改成"\$conf["\mustBeFilledVar\"]".
6220
		#$conf["variableCheck::checkArguments"]["skipableVarDefaultValue"]=array("0.0.0.0",array());
6221
		#$conf["disallowAllSkipableVarIsEmpty"],字串,是否允許每個可省略參數都為空字串,預設為"true"允許,反之為"false".
6222
		#$conf["disallowAllSkipableVarIsEmpty"]="";
6223
		#$conf["disallowAllSkipableVarIsEmptyArray"],字串,是否允許每個可省略參數都為空陣列,預設為"true"允許,反之為"false".
6224
		#$conf["disallowAllSkipableVarIsEmptyArray"]="";
6225
		#$conf["arrayCountEqualCheck"],字串陣列,為檢查哪些陣列參數的元素數量要一樣,$conf["arrayCountEqualCheck"][$i]=array()為第$i組key為哪些的變數其元素數量要相等.
6226
		#$conf["arrayCountEqualCheck"][]=array();
6227
		#參考資料來源:
6228
		#array_keys=>http://php.net/manual/en/function.array-keys.php
6229
		$checkArguments=variableCheck::checkArguments($conf["variableCheck::checkArguments"]);
6230
		unset($conf["variableCheck::checkArguments"]);
6231
 
6232
		#如果檢查參數失敗
6233
		if($checkArguments["status"]==="false"){
6234
 
6235
			#設置執行失敗
6236
			$result["status"]="false";
6237
 
6238
			#設置錯誤訊息
6239
			$result["error"]=$checkArguments;
6240
 
6241
			#回傳結果
6242
			return $result;
6243
 
6244
			}#if end
6245
 
6246
		#如果檢查參數不通過
6247
		if($checkArguments["passed"]==="false"){
6248
 
6249
			#設置執行失敗
6250
			$result["status"]="false";
6251
 
6252
			#設置錯誤訊息
6253
			$result["error"]=$checkArguments;
6254
 
6255
			#回傳結果
6256
			return $result;
6257
 
6258
			}#if end
6259
 
6260
		#針對輸入的內容
6261
		switch($conf["data"]){
6262
 
6263
			#如果是 "quit"
6264
			case "quit":
6265
 
6266
				#從 $conf["clientKey"] 取得用戶的IP與port
6267
				$strArray=explode(":",$conf["clientKey"]);
6268
				$remote_ip=$strArray[0];
6269
				$remote_port=$strArray[1];
6270
 
6271
				#卸除儲存與用戶之間連線的socket變數
6272
				unset($conf["allSockArray"][$conf["clientKey"]]);
6273
 
6274
				break;
6275
 
6276
			#如果是 "shutdown"
6277
			case "shutdown":
6278
 
6279
				#關閉 Server Listen 的 sock
6280
				socket_close($conf["serverSock"]);
6281
 
6282
				break;
6283
 
6284
			default:
6285
 
6286
			}#switch end
6287
 
6288
		}#function endServiceU end
624 liveuser 6289
 
6290
	/*
6291
	#函式說明:
668 liveuser 6292
	#給予unixDomainSockServer函式的addOnProcessFunc參數用的函式,在背景執行指令.
624 liveuser 6293
	#回傳結果:
6294
	#$result["status"],執行是否正常,"true"為正常,"false"為不正常.
6295
	#$result["error"],錯誤訊息陣列.
6296
	#$result["function"],當前執行的函數名稱.
6297
	#$result["argu"],使用的參數.
6298
	#$result["continue"],"true"代表執行到此函式為止;"false"代表允許後面的函式繼續執行.
668 liveuser 6299
	#$result["cache"],要暫存在server端的內容.
624 liveuser 6300
	#必填參數:
668 liveuser 6301
	$conf["request"],json字串,key為"cmd2run"者,代表要執行的指令;key為"params"者,為要傳入的參數,一個元素代表一個參數.
624 liveuser 6302
	#$conf["request"]="";
6303
	$conf["sock"],resource,用戶socket.
6304
	#$conf["sock"]=;
6305
	#可省略參數:
705 liveuser 6306
	#$conf["clientCache"],陣列,讓client使用的cache.
6307
	#$conf["clientCache"]=array();
624 liveuser 6308
	#參考資料:
6309
	#無.
6310
	#備註:
6311
	#無.
6312
	*/
6313
	public static function addOnProcessFuncForUnixDomainSockServerInRunWithAutoAddMemoryDaemon(&$conf=array()){
1 liveuser 6314
 
624 liveuser 6315
		#初始化要回傳的結果
6316
		$result=array();
6317
 
6318
		#取得當前執行的函數名稱
6319
		$result["function"]=__FUNCTION__;
6320
 
6321
		#取得參數
6322
		$result["argu"]=$conf;
6323
 
6324
		#允許後面的函式繼續執行
6325
		$result["continue"]="true";
6326
 
6327
		#如果 $conf 不為陣列
6328
		if(gettype($conf)!="array"){
6329
 
6330
			#設置執行失敗
6331
			$result["status"]="false";
6332
 
6333
			#設置執行錯誤訊息
6334
			$result["error"][]="\$conf變數須為陣列形態";
6335
 
6336
			#如果傳入的參數為 null
6337
			if(is_null($conf)){
6338
 
6339
				#設置執行錯誤訊息
6340
				$result["error"][]="\$conf變數不得為null,請檢查函數「".$result["function"]."」的參數設置有無正確!";
6341
 
6342
				}#if end
6343
 
6344
			#回傳結果
6345
			return $result;
6346
 
6347
			}#if end
6348
 
6349
		#函式說明:
6350
		#檢查必填與可省略的參數,可省略參數可指定預設要給與什麼數值內容.
6351
		#回傳結果:
6352
		#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
6353
		#$result["error"],執行不正常結束的錯訊息陣列.
6354
		#$result["simpleError"],簡單表示的錯誤訊息.
6355
		#$result["function"],當前執行的函式名稱.
6356
		#$result["argu"],設置給予的參數.
6357
		#$result["passed"],識別要檢查的全體變數是否存在以及型態是否正確的變數,"true"代表檢查全部通過;"false"代表檢查不通過
6358
		#$result[$shouldBeCheckedVarName]["varExist"],所檢查的變數是否存在,"false"代表不存在;"true"代表存在
6359
		#$result[$shouldBeCheckedVarName]["varType"],所檢查的變數型態是否正確,"false"代表錯誤;"true"代表正確
6360
		#$result[$shouldBeCheckedVarName]["error"],每個參數設定的錯誤訊息
6361
		#$result["shouldNotBeEmpty"],不應該為空字串或控陣列的變數.
6362
		#$result["argu"],字串陣列,目前輸入的參數名稱陣列.
6363
		#$result["legalVarName"],字串陣列,合法可用的參數名稱陣列.
6364
		#$result["notNeedVar"],字串陣列,多餘的參數名稱.
6365
		#必填參數:
6366
		#$conf["varInput"],陣列變數,要檢查的陣列變數,請在要檢查的參數前面加上&,這樣變動的結果才能被套用。
6367
		$conf["variableCheck::checkArguments"]["varInput"]=&$conf;
6368
		#$conf["referenceVarKey"],字串,$conf參數後面的key值,用於移除不要的參考陣列.
6369
		$conf["variableCheck::checkArguments"]["referenceVarKey"]="variableCheck::checkArguments";
6370
		#可省略參數:
6371
		#$conf["mustBeFilledVariableName"],爲必填參數的變數名稱陣列,形態爲陣列變數,元素數量需要跟"mustBeFilledVariableType"參數的元素數量一致,例如: $conf["mustBeFilledVariableName"] = array("id","account","password");
669 liveuser 6372
		$conf["variableCheck::checkArguments"]["mustBeFilledVariableName"]=array("request","socket");
624 liveuser 6373
		#$conf["mustBeFilledVariableType"],爲必填參數的變數陣列應該爲何種變數形態,形態爲陣列,元素數量需要跟"mustBeFilledVariableName"參數的元素數量一致,例如: $conf["mustBeFilledVariableType"] = array("string",integer,"double","resource","object"); , null代表不指定變數形態.
6374
		$conf["variableCheck::checkArguments"]["mustBeFilledVariableType"]=array("string","resource");
6375
		#$conf["canBeEmptyString"],字串,必填變數內容如果是空字串就不能算是有設置的話,請設為"false",預設爲"true",可以為空字串.
6376
		#$conf["canBeEmptyString"]="false";
6377
		#$conf["canNotBeEmpty"],字串陣列,哪些必填參數的內容不得為空字串或空陣列,僅當$conf["canBeEmptyString"]為"true"時會生效.
6378
		#$conf["canNotBeEmpty"]=array();
6379
		#$conf["canBeEmpty"],字串陣列,哪些必填參數的內容可為空字串或空陣列,僅當$conf["canBeEmptyString"]為"false"時會生效.
6380
		#$conf["canBeEmpty"]=array();
6381
		#$conf["skipableVariableCanNotBeEmpty"],字串陣列,哪些可省略參數不可以為空字串或空陣列.
669 liveuser 6382
		#$conf["variableCheck::checkArguments"]["skipableVariableCanNotBeEmpty"]=array("last_req_time","info");
624 liveuser 6383
		#$conf["skipableVariableName"],陣列字串,爲可省略參數的變數名稱陣列,形態爲陣列變數,例如: $conf["skipableVariableName"] = array("id","account","password");
705 liveuser 6384
		$conf["variableCheck::checkArguments"]["skipableVariableName"]=array("last_req_time","info","clientCache");
624 liveuser 6385
		#$conf["skipableVariableType"],陣列字串,爲可省略參數的變數名稱陣列,形態爲陣列變數,例如: $conf["skipableVariableType"] = array("string",integer,"double");
705 liveuser 6386
		$conf["variableCheck::checkArguments"]["skipableVariableType"]=array("string","array","array");
624 liveuser 6387
		#$conf["skipableVarDefaultValue"],字串陣列,每個不存在的可省略變數要初始化為什麼,null與代表不指定,若預設值是參數之一,請將$conf["mustBeFilledVar"]改成"\$conf["\mustBeFilledVar\"]".
6388
		#$conf["variableCheck::checkArguments"]["skipableVarDefaultValue"]=array($phpMaxMemInConfig,"10",null);
6389
		#$conf["disallowAllSkipableVarIsEmpty"],字串,是否允許每個可省略參數都為空字串,預設為"true"允許,反之為"false".
6390
		#$conf["disallowAllSkipableVarIsEmpty"]="";
6391
		#$conf["disallowAllSkipableVarIsEmptyArray"],字串,是否允許每個可省略參數都為空陣列,預設為"true"允許,反之為"false".
6392
		#$conf["disallowAllSkipableVarIsEmptyArray"]="";
6393
		#$conf["arrayCountEqualCheck"],字串陣列,為檢查哪些陣列參數的元素數量要一樣,$conf["arrayCountEqualCheck"][$i]=array()為第$i組key為哪些的變數其元素數量要相等.
6394
		#$conf["arrayCountEqualCheck"][]=array();
6395
		#參考資料:
6396
		#array_keys=>http://php.net/manual/en/function.array-keys.php
6397
		#備註:
6398
		#無.
6399
		$checkArguments=variableCheck::checkArguments($conf["variableCheck::checkArguments"]);
6400
		unset($conf["variableCheck::checkArguments"]);
6401
 
669 liveuser 6402
		#debug
6403
		#var_dump(__LINE__,$checkArguments);
6404
 
624 liveuser 6405
		#如果執行失敗
6406
		if($checkArguments["status"]==="false"){
6407
 
6408
			#設置執行失敗
6409
			$result["status"]="false";
6410
 
6411
			#設置執行錯誤訊息
6412
			$result["error"]=$checkArguments;
6413
 
6414
			#回傳結果
6415
			return $result;
6416
 
6417
			}#if end
6418
 
6419
		#如果檢查不通過
6420
		if($checkArguments["passed"]==="false"){
6421
 
6422
			#設置執行失敗
6423
			$result["status"]="false";
6424
 
6425
			#設置執行錯誤訊息
6426
			$result["error"]=$checkArguments;
6427
 
6428
			#回傳結果
6429
			return $result;
6430
 
6431
			}#if end	
6432
 
6433
		#將需求變成陣列
6434
		$request=(array)json_decode($conf["request"]);
6435
 
6436
		#函式說明:
6437
		#檢查必填與可省略的參數,可省略參數可指定預設要給與什麼數值內容.
6438
		#回傳結果:
6439
		#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
6440
		#$result["error"],執行不正常結束的錯訊息陣列.
6441
		#$result["simpleError"],簡單表示的錯誤訊息.
6442
		#$result["function"],當前執行的函式名稱.
6443
		#$result["argu"],設置給予的參數.
6444
		#$result["passed"],識別要檢查的全體變數是否存在以及型態是否正確的變數,"true"代表檢查全部通過;"false"代表檢查不通過
6445
		#$result[$shouldBeCheckedVarName]["varExist"],所檢查的變數是否存在,"false"代表不存在;"true"代表存在
6446
		#$result[$shouldBeCheckedVarName]["varType"],所檢查的變數型態是否正確,"false"代表錯誤;"true"代表正確
6447
		#$result[$shouldBeCheckedVarName]["error"],每個參數設定的錯誤訊息
6448
		#$result["shouldNotBeEmpty"],不應該為空字串或控陣列的變數.
6449
		#$result["argu"],字串陣列,目前輸入的參數名稱陣列.
6450
		#$result["legalVarName"],字串陣列,合法可用的參數名稱陣列.
6451
		#$result["notNeedVar"],字串陣列,多餘的參數名稱.
6452
		#必填參數:
6453
		#$conf["varInput"],陣列變數,要檢查的陣列變數,請在要檢查的參數前面加上&,這樣變動的結果才能被套用。
6454
		$conf["variableCheck::checkArguments"]["varInput"]=&$request;
6455
		#$conf["referenceVarKey"],字串,$conf參數後面的key值,用於移除不要的參考陣列.
6456
		$conf["variableCheck::checkArguments"]["referenceVarKey"]="variableCheck::checkArguments";
6457
		#可省略參數:
6458
		#$conf["mustBeFilledVariableName"],爲必填參數的變數名稱陣列,形態爲陣列變數,元素數量需要跟"mustBeFilledVariableType"參數的元素數量一致,例如: $conf["mustBeFilledVariableName"] = array("id","account","password");
669 liveuser 6459
		$conf["variableCheck::checkArguments"]["mustBeFilledVariableName"]=array("cmd2run");
624 liveuser 6460
		#$conf["mustBeFilledVariableType"],爲必填參數的變數陣列應該爲何種變數形態,形態爲陣列,元素數量需要跟"mustBeFilledVariableName"參數的元素數量一致,例如: $conf["mustBeFilledVariableType"] = array("string",integer,"double","resource","object"); , null代表不指定變數形態.
668 liveuser 6461
		$conf["variableCheck::checkArguments"]["mustBeFilledVariableType"]=array("string");
624 liveuser 6462
		#$conf["canBeEmptyString"],字串,必填變數內容如果是空字串就不能算是有設置的話,請設為"false",預設爲"true",可以為空字串.
668 liveuser 6463
		#$conf["variableCheck::checkArguments"]["canBeEmptyString"]="true";
624 liveuser 6464
		#$conf["canNotBeEmpty"],字串陣列,哪些必填參數的內容不得為空字串或空陣列,僅當$conf["canBeEmptyString"]為"true"時會生效.
668 liveuser 6465
		#$conf["variableCheck::checkArguments"]["canNotBeEmpty"]=array("cmd");
624 liveuser 6466
		#$conf["canBeEmpty"],字串陣列,哪些必填參數的內容可為空字串或空陣列,僅當$conf["canBeEmptyString"]為"false"時會生效.
6467
		#$conf["canBeEmpty"]=array();
6468
		#$conf["skipableVariableCanNotBeEmpty"],字串陣列,哪些可省略參數不可以為空字串或空陣列.
669 liveuser 6469
		#$conf["variableCheck::checkArguments"]["skipableVariableCanNotBeEmpty"]=array("params");
624 liveuser 6470
		#$conf["skipableVariableName"],陣列字串,爲可省略參數的變數名稱陣列,形態爲陣列變數,例如: $conf["skipableVariableName"] = array("id","account","password");
669 liveuser 6471
		$conf["variableCheck::checkArguments"]["skipableVariableName"]=array("id","params");
624 liveuser 6472
		#$conf["skipableVariableType"],陣列字串,爲可省略參數的變數名稱陣列,形態爲陣列變數,例如: $conf["skipableVariableType"] = array("string",integer,"double");
669 liveuser 6473
		$conf["variableCheck::checkArguments"]["skipableVariableType"]=array("string","array");
624 liveuser 6474
		#$conf["skipableVarDefaultValue"],字串陣列,每個不存在的可省略變數要初始化為什麼,null與代表不指定,若預設值是參數之一,請將$conf["mustBeFilledVar"]改成"\$conf["\mustBeFilledVar\"]".
6475
		#$conf["variableCheck::checkArguments"]["skipableVarDefaultValue"]=array($phpMaxMemInConfig,"10",null);
6476
		#$conf["disallowAllSkipableVarIsEmpty"],字串,是否允許每個可省略參數都為空字串,預設為"true"允許,反之為"false".
6477
		#$conf["disallowAllSkipableVarIsEmpty"]="";
6478
		#$conf["disallowAllSkipableVarIsEmptyArray"],字串,是否允許每個可省略參數都為空陣列,預設為"true"允許,反之為"false".
6479
		#$conf["disallowAllSkipableVarIsEmptyArray"]="";
6480
		#$conf["arrayCountEqualCheck"],字串陣列,為檢查哪些陣列參數的元素數量要一樣,$conf["arrayCountEqualCheck"][$i]=array()為第$i組key為哪些的變數其元素數量要相等.
6481
		#$conf["arrayCountEqualCheck"][]=array();
6482
		#參考資料:
6483
		#array_keys=>http://php.net/manual/en/function.array-keys.php
6484
		#備註:
6485
		#無.
6486
		$checkArguments=variableCheck::checkArguments($conf["variableCheck::checkArguments"]);
6487
		unset($conf["variableCheck::checkArguments"]);
6488
 
669 liveuser 6489
		#debug
6490
		#var_dump(__LINE__,$checkArguments);
6491
 
624 liveuser 6492
		#如果執行失敗
6493
		if($checkArguments["status"]==="false"){
6494
 
6495
			#設置執行失敗
6496
			$result["status"]="false";
6497
 
6498
			#設置執行錯誤訊息
6499
			$result["error"]=$checkArguments;
6500
 
6501
			#回傳結果
6502
			return $result;
6503
 
6504
			}#if end
6505
 
6506
		#如果檢查不通過
6507
		if($checkArguments["passed"]==="false"){
6508
 
6509
			#設置執行失敗
6510
			$result["status"]="false";
6511
 
6512
			#設置執行錯誤訊息
6513
			$result["error"]=$checkArguments;
6514
 
6515
			#回傳結果
6516
			return $result;
6517
 
6518
			}#if end
669 liveuser 6519
 
6520
		#函式說明:
6521
		#呼叫shell執行系統命令,並取得回傳的內容.
6522
		#回傳結果:
6523
		#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
6524
		#$result["error"],錯誤訊息陣列.
6525
		#$result["function"],當前執行的函數名稱.
6526
		#$result["argu"],使用的參數.
6527
		#$result["cmd"],執行的指令內容.
6528
		#$result["fullCmd"],如果參數 $conf["inBackGround"] 為 "true" 則會回傳該值.
6529
		#$result["output"],爲執行完二元碼後的輸出陣列,若 $conf["inBackGround"] 為 "true",則為當下的輸出.
6530
		#$result["tmpFileOutput"],儲存輸出的暫存檔案名稱,若 $conf["inBackGround"] 為 "true" 則會回傳該值.
6531
		#$result["running"],是否還在執行.
6532
		#$result["pid"],pid.
6533
		#$result["statusCode"],執行結束後的代碼.
6534
		#$result["escape"],陣列,儲存重新排序過且已經escape過的指令(key為"cmd")與參數(key為"argu")與兩者組合的一維陣列(key為"array").
6535
		#必填參數:
6536
		#$conf["command"],字串,要執行的指令.
6537
		$conf["external::callShell"]["command"]=$request["cmd2run"];
6538
		#$conf["fileArgu"],字串,變數__FILE__的內容.
6539
		$conf["external::callShell"]["fileArgu"]=__FILE__;
6540
		#可省略參數:
6541
		#$conf["argu"],陣列字串,指令搭配的參數,預設為空陣列.
6542
		$conf["external::callShell"]["argu"]=$request["params"];
6543
		#$conf["arguIsAddr"],陣列字串,指令搭配的哪些參數為路徑,為路徑的參數會進行轉換以便符合呼叫當前函數的位置,預設不指定,若有3個參數,其中第3個參數為路徑,則表示為array("false","false","true").
6544
		#$conf["arguIsAddr"]=array();
6545
		#$conf["pre"],陣列,要在本指令前執行的每個指令與參數.
6546
		#$conf["pre"][$i]["cmd"],字串,要在本指令前執行的第$i+1個指令.
6547
		#$conf["pre"][$i]["param"],陣列字串,要在本指令前執行的第$i+1個指令的參數.
6548
		#$conf["enablePrintDescription"],字串,是否要印出$conf["printDescription"]的內容,"true"代表要,"false"代表不要,預設為"false".
6549
		#$conf["enablePrintDescription"]="true";
6550
		#$conf["printDescription"],字串,執行該外部程式前要印出來的的文字,預設為$conf["command"]的內容加上使用的$conf["argu"]參數.
6551
		#$conf["printDescription"]="";
6552
		#$conf["escapeshellarg"],字串,是否要啟用過濾參數,用了比較安全,但可能會出錯,"true"為啟用,"false"為不啟用,預設為"false".如果參數為"< 、<< 、> 、>> 、| 、2>&1"之一則不會過濾.
6553
		$conf["external::callShell"]["escapeshellarg"]="true";
6554
		#$conf["thereIsShellVar"],陣列字串,指令搭配的參數"argu",若含有「\'」,則取代為「"」.每個argu參數都要有對應的元素."true"代表要置換.
6555
		#$conf["thereIsShellVar"]=array();
6556
		#$conf["username"],字串,要用什麼使用者來執行,預設為執行php的使用者,該參數不適用於apache環境.
6557
		#$conf["username"]="";
6558
		#$conf["password"],字串,root的使用者密碼,預設不使用密碼,該參數不適用於apache環境.
6559
		#$conf["password"]="";
6560
		#$conf["useScript"],字串,是否要啟用Linux的script指令來記錄輸出,"true"代表要,Fedora的selinux會擋住該操作;"false"代表不要,預設為"false".
6561
		#$conf["useScript"]="";
6562
		#$conf["logFilePath"],字串,當 $conf["useScript"] 為 "true" 時,輸出的內容要暫存到哪裡,預設為 "/tmp/.qbpwcf_tmp/external/callShell/".
6563
		#$conf["logFilePath"]=".qbpwcf_tmp/external/callShell/";
6564
		#$conf["inBackGround"],字串,是否要在背景執行,且不會等待程式執行結束再執行下一個指令,"true"代表是,"false"代表不要,預設為"false",如果$conf["command"]有用「;」區隔的多個指令將會出錯.
6565
		#$conf["inBackGround"]="";
6566
		#$conf["getErr"],字串,"true"代表將錯誤輸出變成標準輸出,反之"false"為不變動.
6567
		#$conf["getErr"]="false";
6568
		#$conf["doNotRun"],字串,"true"代表不執行指令,預設為"false"會執行指令.
6569
		$conf["external::callShell"]["doNotRun"]="true";
6570
		#參考資料:
6571
		#exec=>http://php.net/manual/en/function.exec.php
6572
		#escapeshellcmd=>http://php.net/manual/en/function.escapeshellcmd.php
6573
		#escapeshellarg=>http://php.net/manual/en/function.escapeshellarg.php
6574
		#備註:
6575
		#不是所有指令都能用apache的身份執行,目前已知java,javac指令無法執行,使用root身份可能會被selinux阻擋.
6576
		#若使用的 command、argu 參數,含有 ~ 則會被視為字串,若有需要其於 shell 中代表的家目錄位置,可用 fileAccess::tildeToPath 來進行轉換.
6577
		$callShell=external::callShell($conf["external::callShell"]);
6578
		unset($conf["external::callShell"]);
6579
 
6580
		#如果執行失敗
6581
		if($callShell["status"]==="false"){
6582
 
6583
			#設置執行失敗
6584
			$result["status"]="false";
6585
 
6586
			#設置執行錯誤訊息
6587
			$result["error"]=$callShell;
668 liveuser 6588
 
669 liveuser 6589
			#回傳結果
6590
			return $result;
668 liveuser 6591
 
669 liveuser 6592
			}#if end
668 liveuser 6593
 
669 liveuser 6594
		#函式說明:
6595
		#將一維陣列轉換為用特定符號間隔的字串,ex:array("1","2","3") to "a;b;c;".
6596
		#回傳的結果:
6597
		#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
6598
		#$result["function"],當前執行的function名稱
6599
		#$result["error"],錯誤訊息陣列.
6600
		#$result["content"],處理好的字串.
6601
		#$result["argu"],使用的參數.
6602
		#必填參數:
6603
		#$conf["inputArray"],字串陣列,要轉成字串的一維陣列.
6604
		$conf["arrays::arrayToString"]["inputArray"]=$callShell["escape"]["array"];
6605
		#可省略參數:
6606
		#$conf["spiltSymbol"],字串,用來區隔字串的符號,預設為;
6607
		$conf["arrays::arrayToString"]["spiltSymbol"]=" ";
6608
		#$conf["skipEnd"],字串,結尾是否不要加上符號,預設為"false",要加上符號,"true"代表不要加上符號。
6609
		$conf["arrays::arrayToString"]["skipEnd"]="true";
6610
		#參考資料:
6611
		#無.
6612
		#備註:
6613
		#無.
6614
		$arrayToString=arrays::arrayToString($conf["arrays::arrayToString"]);
6615
		unset($conf["arrays::arrayToString"]);
668 liveuser 6616
 
669 liveuser 6617
		#如果執行失敗
6618
		if($arrayToString["status"]==="false"){
668 liveuser 6619
 
669 liveuser 6620
			#設置執行失敗
6621
			$result["status"]="false";
6622
 
6623
			#設置執行錯誤訊息
6624
			$result["error"]=$arrayToString;
6625
 
6626
			#回傳結果
6627
			return $result;
6628
 
6629
			}#if end
6630
 
668 liveuser 6631
		#函式說明:
6632
		#透過proc來多執行序運作.
6633
		#回傳結果:
6634
		#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
6635
		#$reuslt["error"],執行不正常結束的錯訊息陣列.
6636
		#$result["function"],當前執行的函式名稱.
6637
		#$result["argu"],使用的參數.
6638
		#$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"代表程序的資訊.
6639
		#必填參數:
6640
		#$conf["cmds"],字串陣列,每個元素代表要執行的指令與參數.
669 liveuser 6641
		$conf["threads::proc"]["cmds"]=array($arrayToString["content"]);
668 liveuser 6642
		#可省略參數:
6643
		#$conf["wait"],字串,是否需要等待所有程序結束,預設為"true"要等待;反之為"false"不要等待.
669 liveuser 6644
		#$conf["threads::proc"]["wait"]="false";
668 liveuser 6645
		#$conf["workingDir"],字串陣列,個別程式執行時的家目錄,預設不指定.
6646
		#$conf["workingDir"]=array("path");
6647
		#$conf["envs"],2維字串陣列,每個元素代表個別程式執行時的指定環境變數,key變數名稱;value為變數內容.預設為array("QBPWCF" => "Quick Build PHP Website Componment base on Fedora Linux");
6648
		#$conf["envs"]=array(array("key"=>"value"));
6649
		#$conf["executeBy"],字串陣列,每個元素代表個別指令要用什麼程式執行,預設為"bash".
6650
		#$conf["executeBy"]=array("bash");
6651
		#參考資料:
6652
		#https://www.php.net/manual/en/function.proc-open.php
6653
		#https://www.php.net/manual/en/function.proc-get-status.php
6654
		#備註:
6655
		#無.
6656
		$proc=threads::proc($conf["threads::proc"]);
6657
		unset($conf["threads::proc"]);
6658
 
669 liveuser 6659
		/* debug
6660
 
6661
		#函式說明:
6662
		#撰寫log
6663
		#回傳結果:
6664
		#$result["status"],狀態,"true"或"false".
6665
		#$result["error"],錯誤訊息陣列.
6666
		#$result["function"],當前函式的名稱.
6667
		#$result["argu"],使用的參數.
6668
		#$result["content"],要寫入log的內容字串.
6669
		#必填參數:
6670
		#$conf["path"],字串,log檔案的路徑與名稱.
6671
		$conf["logs::record"]["path"]=$conf["socket"]."(sock::addOnProcessFuncForUnixDomainSockServerInRunWithAutoAddMemoryDaemon).log";
6672
		#$conf["content"],any,要寫的內容,若內容不為字串則會用var_dump的格式寫入.
6673
		$conf["logs::record"]["content"]=$proc;
6674
		#$conf["fileArgu"],字串,php變數__FILE__的內容,亦即該檔案在檔案系統的絕對路徑
6675
		$conf["logs::record"]["fileArgu"]=__FILE__;
6676
		#可省略參數:
6677
		#$conf["rewrite"],預設為"false",接續寫入;反之"true"代表重新寫入.
6678
		#$conf["rewrite"]="false";
6679
		#$conf["returnOnly"],預設為"false",會寫入到log檔案.若為"true"則不會寫入log.
6680
		#$conf["returnOnly"]="true";
6681
		#參考資料:
6682
		#無.
6683
		#備註:
6684
		#無.
6685
		$record=logs::record($conf["logs::record"]);
6686
		unset($conf["logs::record"]);
6687
 
624 liveuser 6688
		#如果執行失敗
669 liveuser 6689
		if($record["status"]==="false"){
6690
 
6691
			#設置執行錯誤識別
6692
			$result["status"]="false";
6693
 
6694
			#設置執行錯誤
6695
			$result["error"]=$record;
6696
 
6697
			#回傳結果
6698
			return $result;
6699
 
6700
			}#if end
6701
 
6702
		*/
6703
 
6704
		#設置要暫存在server端的內容
6705
		$result["cache"]=&$proc;
6706
 
6707
		#如果執行失敗
668 liveuser 6708
		if($proc["status"]==="false"){
624 liveuser 6709
 
6710
			#設置執行失敗
6711
			$result["status"]="false";
6712
 
6713
			#設置執行錯誤訊息
668 liveuser 6714
			$result["error"]=$proc;
669 liveuser 6715
 
6716
			#回傳結果
6717
			return $result;
624 liveuser 6718
 
6719
			}#if end
6720
 
6721
		#設置執行正常
6722
		$result["status"]="true";
668 liveuser 6723
 
669 liveuser 6724
		#後面的程式不要執行
6725
		$result["continue"]="false";
668 liveuser 6726
 
624 liveuser 6727
		#回傳結果
6728
		return $result;
6729
 
668 liveuser 6730
		}#function addOnProcessFuncForUnixDomainSockServerInRunWithAutoAddMemoryDaemon end
624 liveuser 6731
 
6732
	/*
6733
	#函式說明:
6734
	#執行程式時,依照需要增加記憶體的上限.
6735
	#回傳結果:
6736
	#$result["status"],執行是否正常,"true"為正常,"false"為不正常.
6737
	#$result["error"],錯誤訊息陣列.
6738
	#$result["function"],當前執行的函數名稱.
668 liveuser 6739
	#$result["argu"],使用的參數.
6740
	#$result["content"],程式執行後的結果(unix domain socket server的輸出).
624 liveuser 6741
	#必填參數:
668 liveuser 6742
	#$conf["cmd"],字串參數,要執行的指令.
6743
	$conf["cmd"]="";
624 liveuser 6744
	#可省略參數:
668 liveuser 6745
	#$conf["params"],陣列字串參數,每個元素代表依序哦昂使用的參數.
6746
	#$conf["params"]=array("");
6747
	#$conf["fileArgu"],字串,__FILE__的內容.
6748
	#$conf["fileArgu"]="";
624 liveuser 6749
	#參考資料:
6750
	#https://www.php.net/manual/en/function.memory-get-usage.php
6751
	#https://www.php.net/manual/en/ini.core.php#ini.memory-limit
669 liveuser 6752
	#https://www.php.net/manual/en/function.stream-get-meta-data.php
624 liveuser 6753
	#備註:
668 liveuser 6754
	#無.
624 liveuser 6755
	*/
6756
	public static function runWithAutoAddMemoryDaemon(&$conf=array()){
6757
 
6758
		#初始化要回傳的結果
6759
		$result=array();
6760
 
6761
		#取得當前執行的函數名稱
6762
		$result["function"]=__FUNCTION__;
6763
 
6764
		#取得參數
6765
		$result["argu"]=$conf;
6766
 
6767
		#如果 $conf 不為陣列
6768
		if(gettype($conf)!="array"){
6769
 
6770
			#設置執行失敗
6771
			$result["status"]="false";
6772
 
6773
			#設置執行錯誤訊息
6774
			$result["error"][]="\$conf變數須為陣列形態";
6775
 
6776
			#如果傳入的參數為 null
6777
			if(is_null($conf)){
6778
 
6779
				#設置執行錯誤訊息
6780
				$result["error"][]="\$conf變數不得為null,請檢查函數「".$result["function"]."」的參數設置有無正確!";
6781
 
6782
				}#if end
6783
 
6784
			#回傳結果
6785
			return $result;
6786
 
6787
			}#if end
6788
 
668 liveuser 6789
		#檢查參數
624 liveuser 6790
		#函式說明:
6791
		#檢查必填與可省略的參數,可省略參數可指定預設要給與什麼數值內容.
6792
		#回傳結果:
6793
		#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
6794
		#$result["error"],執行不正常結束的錯訊息陣列.
6795
		#$result["simpleError"],簡單表示的錯誤訊息.
6796
		#$result["function"],當前執行的函式名稱.
6797
		#$result["argu"],設置給予的參數.
6798
		#$result["passed"],識別要檢查的全體變數是否存在以及型態是否正確的變數,"true"代表檢查全部通過;"false"代表檢查不通過
6799
		#$result[$shouldBeCheckedVarName]["varExist"],所檢查的變數是否存在,"false"代表不存在;"true"代表存在
6800
		#$result[$shouldBeCheckedVarName]["varType"],所檢查的變數型態是否正確,"false"代表錯誤;"true"代表正確
6801
		#$result[$shouldBeCheckedVarName]["error"],每個參數設定的錯誤訊息
6802
		#$result["shouldNotBeEmpty"],不應該為空字串或控陣列的變數.
6803
		#$result["argu"],字串陣列,目前輸入的參數名稱陣列.
6804
		#$result["legalVarName"],字串陣列,合法可用的參數名稱陣列.
6805
		#$result["notNeedVar"],字串陣列,多餘的參數名稱.
6806
		#必填參數:
6807
		#$conf["varInput"],陣列變數,要檢查的陣列變數,請在要檢查的參數前面加上&,這樣變動的結果才能被套用。
6808
		$conf["variableCheck::checkArguments"]["varInput"]=&$conf;
6809
		#$conf["referenceVarKey"],字串,$conf參數後面的key值,用於移除不要的參考陣列.
6810
		$conf["variableCheck::checkArguments"]["referenceVarKey"]="variableCheck::checkArguments";
6811
		#可省略參數:
6812
		#$conf["mustBeFilledVariableName"],爲必填參數的變數名稱陣列,形態爲陣列變數,元素數量需要跟"mustBeFilledVariableType"參數的元素數量一致,例如: $conf["mustBeFilledVariableName"] = array("id","account","password");
668 liveuser 6813
		$conf["variableCheck::checkArguments"]["mustBeFilledVariableName"]=array("cmd");
624 liveuser 6814
		#$conf["mustBeFilledVariableType"],爲必填參數的變數陣列應該爲何種變數形態,形態爲陣列,元素數量需要跟"mustBeFilledVariableName"參數的元素數量一致,例如: $conf["mustBeFilledVariableType"] = array("string",integer,"double","resource","object"); , null代表不指定變數形態.
668 liveuser 6815
		$conf["variableCheck::checkArguments"]["mustBeFilledVariableType"]=array("string");
624 liveuser 6816
		#$conf["canBeEmptyString"],字串,必填變數內容如果是空字串就不能算是有設置的話,請設為"false",預設爲"true",可以為空字串.
668 liveuser 6817
		$conf["variableCheck::checkArguments"]["canBeEmptyString"]="false";
624 liveuser 6818
		#$conf["canNotBeEmpty"],字串陣列,哪些必填參數的內容不得為空字串或空陣列,僅當$conf["canBeEmptyString"]為"true"時會生效.
6819
		#$conf["canNotBeEmpty"]=array();
6820
		#$conf["canBeEmpty"],字串陣列,哪些必填參數的內容可為空字串或空陣列,僅當$conf["canBeEmptyString"]為"false"時會生效.
6821
		#$conf["canBeEmpty"]=array();
6822
		#$conf["skipableVariableCanNotBeEmpty"],字串陣列,哪些可省略參數不可以為空字串或空陣列.
668 liveuser 6823
		$conf["variableCheck::checkArguments"]["skipableVariableCanNotBeEmpty"]=array("params","fileArgu");
624 liveuser 6824
		#$conf["skipableVariableName"],陣列字串,爲可省略參數的變數名稱陣列,形態爲陣列變數,例如: $conf["skipableVariableName"] = array("id","account","password");
668 liveuser 6825
		$conf["variableCheck::checkArguments"]["skipableVariableName"]=array("params","fileArgu");
624 liveuser 6826
		#$conf["skipableVariableType"],陣列字串,爲可省略參數的變數名稱陣列,形態爲陣列變數,例如: $conf["skipableVariableType"] = array("string",integer,"double");
668 liveuser 6827
		$conf["variableCheck::checkArguments"]["skipableVariableType"]=array("array","string");
624 liveuser 6828
		#$conf["skipableVarDefaultValue"],字串陣列,每個不存在的可省略變數要初始化為什麼,null與代表不指定,若預設值是參數之一,請將$conf["mustBeFilledVar"]改成"\$conf["\mustBeFilledVar\"]".
668 liveuser 6829
		$conf["variableCheck::checkArguments"]["skipableVarDefaultValue"]=array(null,__FILE__);
624 liveuser 6830
		#$conf["disallowAllSkipableVarIsEmpty"],字串,是否允許每個可省略參數都為空字串,預設為"true"允許,反之為"false".
6831
		#$conf["disallowAllSkipableVarIsEmpty"]="";
6832
		#$conf["disallowAllSkipableVarIsEmptyArray"],字串,是否允許每個可省略參數都為空陣列,預設為"true"允許,反之為"false".
6833
		#$conf["disallowAllSkipableVarIsEmptyArray"]="";
668 liveuser 6834
		#$conf["disallowAllSkipableVarNotExist"],字串,是否不允許每個可省略參數都不存在,預設為"false"代表允許,反之為"true".
6835
		#$conf["disallowAllSkipableVarNotExist"]="";
624 liveuser 6836
		#$conf["arrayCountEqualCheck"],字串陣列,為檢查哪些陣列參數的元素數量要一樣,$conf["arrayCountEqualCheck"][$i]=array()為第$i組key為哪些的變數其元素數量要相等.
6837
		#$conf["arrayCountEqualCheck"][]=array();
6838
		#參考資料:
6839
		#array_keys=>http://php.net/manual/en/function.array-keys.php
6840
		#備註:
6841
		#無.
6842
		$checkArguments=variableCheck::checkArguments($conf["variableCheck::checkArguments"]);
6843
		unset($conf["variableCheck::checkArguments"]);
6844
 
6845
		#如果執行失敗
6846
		if($checkArguments["status"]==="false"){
6847
 
6848
			#設置執行失敗
6849
			$result["status"]="false";
668 liveuser 6850
 
6851
			#設置錯誤資訊
624 liveuser 6852
			$result["error"]=$checkArguments;
668 liveuser 6853
 
624 liveuser 6854
			#回傳結果
6855
			return $result;
6856
 
6857
			}#if end
6858
 
6859
		#如果檢查不通過
6860
		if($checkArguments["passed"]==="false"){
6861
 
6862
			#設置執行失敗
6863
			$result["status"]="false";
668 liveuser 6864
 
6865
			#設置錯誤資訊
624 liveuser 6866
			$result["error"]=$checkArguments;
668 liveuser 6867
 
624 liveuser 6868
			#回傳結果
6869
			return $result;
6870
 
6871
			}#if end
6872
 
6873
		/*
6874
		#函式說明:
6875
		#於 ./tmp 底下建立暫存目錄與回傳暫存檔案名稱路徑 
6876
		#回傳結果:
6877
		#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
6878
		#$result["error"],錯誤訊息.
6879
		#$result["function"],當前執行的函數名稱.
6880
		#$result["content"],暫存檔案的路徑與名稱.
6881
		#必填參數:
6882
		#無.
6883
		#可省略參數:
6884
		#無.
6885
		#參考資料:
6886
		#無.
6887
		#備註:
6888
		#無.
6889
		*/
6890
		$createTempFile=fileAccess::createTempFile();
6891
 
6892
		#如果執行失敗
6893
		if($createTempFile["status"]==="false"){
6894
 
6895
			#設置執行失敗
6896
			$result["status"]="false";
6897
 
6898
			#設置執行錯誤訊息
6899
			$result["error"]=$createTempFile;
6900
 
6901
			#回傳結果
6902
			return $result;
6903
 
6904
			}#if end
6905
 
6906
		#取得暫存的 unix domain socket 檔案
6907
		$tmpUnixDomainSock=$createTempFile["content"];
6908
 
668 liveuser 6909
		#初始化用來運行  unixDomainSockServer.php 的參數
6910
		$argu=array();
6911
 
6912
		#設置參數
6913
		$argu[]="--sock";
6914
 
6915
		#設置參數
6916
		$argu[]=$tmpUnixDomainSock;
6917
 
6918
		#設置參數
6919
		$argu[]="--addOnProcessFunc";
6920
 
6921
		#設置參數
6922
		$argu[]="\qbpwcf\sock::addOnProcessFuncForUnixDomainSockServerInRunWithAutoAddMemoryDaemon";
6923
 
6924
		#設置參數
6925
		$argu[]="--funcToRunWhenIdle";
6926
 
6927
		#設置參數
6928
		$argu[]="\qbpwcf\config::autoAddMemory";
669 liveuser 6929
 
6930
		#設置參數
6931
		$argu[]="--onlyOutputCache";
6932
 
6933
		#設置參數
6934
		$argu[]="true";
6935
 
6936
		#設置參數
6937
		$argu[]="--cacheLayer";
6938
 
6939
		#設置參數
6940
		$argu[]="serverCache";
6941
 
6942
		#設置參數
6943
		$argu[]="--cacheLayer";
6944
 
6945
		#設置參數
6946
		$argu[]="serverSide";
6947
 
6948
		#設置參數
6949
		$argu[]="--cacheLayer";
6950
 
6951
		#設置參數
6952
		$argu[]="funcToRunWhenIdle";
6953
 
6954
		#設置參數
6955
		$argu[]="--cacheLayer";
6956
 
6957
		#設置參數
6958
		$argu[]="\qbpwcf\config::autoAddMemory";
6959
 
6960
		#設置參數
6961
		$argu[]="--cacheLayer";
6962
 
6963
		#設置參數
6964
		$argu[]="cache";
6965
 
6966
		#設置參數
6967
		$argu[]="--cacheLayer";
6968
 
6969
		#設置參數
6970
		$argu[]="stdout";
6971
 
624 liveuser 6972
		#函式說明:
668 liveuser 6973
		#呼叫shell執行系統命令,並取得回傳的內容.
624 liveuser 6974
		#回傳結果:
668 liveuser 6975
		#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
624 liveuser 6976
		#$result["error"],錯誤訊息陣列.
668 liveuser 6977
		#$result["function"],當前執行的函數名稱.
6978
		#$result["argu"],使用的參數.
6979
		#$result["cmd"],執行的指令內容.
6980
		#$result["fullCmd"],如果參數 $conf["inBackGround"] 為 "true" 則會回傳該值.
6981
		#$result["output"],爲執行完二元碼後的輸出陣列,若 $conf["inBackGround"] 為 "true",則為當下的輸出.
6982
		#$result["tmpFileOutput"],儲存輸出的暫存檔案名稱,若 $conf["inBackGround"] 為 "true" 則會回傳該值.
6983
		#$result["running"],是否還在執行.
6984
		#$result["pid"],pid.
6985
		#$result["statusCode"],執行結束後的代碼.
6986
		#$result["escape"],陣列,儲存重新排序過且已經escape過的指令(key為"cmd")與參數(key為"argu")與兩者組合的一維陣列(key為"array").
624 liveuser 6987
		#必填參數:
668 liveuser 6988
		#$conf["command"],字串,要執行的指令.
6989
		$conf["external::callShell"]["command"]="unixDomainSockServer.php";
624 liveuser 6990
		#$conf["fileArgu"],字串,變數__FILE__的內容.
668 liveuser 6991
		$conf["external::callShell"]["fileArgu"]=$conf["fileArgu"];
624 liveuser 6992
		#可省略參數:
668 liveuser 6993
		#$conf["argu"],陣列字串,指令搭配的參數,預設為空陣列.
6994
		$conf["external::callShell"]["argu"]=$argu;
6995
		#$conf["arguIsAddr"],陣列字串,指令搭配的哪些參數為路徑,為路徑的參數會進行轉換以便符合呼叫當前函數的位置,預設不指定,若有3個參數,其中第3個參數為路徑,則表示為array("false","false","true").
6996
		#$conf["arguIsAddr"]=array();
6997
		#$conf["pre"],陣列,要在本指令前執行的每個指令與參數.
6998
		#$conf["pre"][$i]["cmd"],字串,要在本指令前執行的第$i+1個指令.
6999
		#$conf["pre"][$i]["param"],陣列字串,要在本指令前執行的第$i+1個指令的參數.
7000
		#$conf["enablePrintDescription"],字串,是否要印出$conf["printDescription"]的內容,"true"代表要,"false"代表不要,預設為"false".
7001
		#$conf["enablePrintDescription"]="true";
7002
		#$conf["printDescription"],字串,執行該外部程式前要印出來的的文字,預設為$conf["command"]的內容加上使用的$conf["argu"]參數.
7003
		#$conf["printDescription"]="";
7004
		#$conf["escapeshellarg"],字串,是否要啟用過濾參數,用了比較安全,但可能會出錯,"true"為啟用,"false"為不啟用,預設為"false".如果參數為"< 、<< 、> 、>> 、| 、2>&1"之一則不會過濾.
7005
		$conf["external::callShell"]["escapeshellarg"]="true";
7006
		#$conf["thereIsShellVar"],陣列字串,指令搭配的參數"argu",若含有「\'」,則取代為「"」.每個argu參數都要有對應的元素."true"代表要置換.
7007
		#$conf["thereIsShellVar"]=array();
7008
		#$conf["username"],字串,要用什麼使用者來執行,預設為執行php的使用者,該參數不適用於apache環境.
7009
		#$conf["username"]="";
7010
		#$conf["password"],字串,root的使用者密碼,預設不使用密碼,該參數不適用於apache環境.
7011
		#$conf["password"]="";
7012
		#$conf["useScript"],字串,是否要啟用Linux的script指令來記錄輸出,"true"代表要,Fedora的selinux會擋住該操作;"false"代表不要,預設為"false".
7013
		#$conf["useScript"]="";
7014
		#$conf["logFilePath"],字串,當 $conf["useScript"] 為 "true" 時,輸出的內容要暫存到哪裡,預設為 "/tmp/.qbpwcf_tmp/external/callShell/".
7015
		#$conf["logFilePath"]=".qbpwcf_tmp/external/callShell/";
7016
		#$conf["inBackGround"],字串,是否要在背景執行,且不會等待程式執行結束再執行下一個指令,"true"代表是,"false"代表不要,預設為"false",如果$conf["command"]有用「;」區隔的多個指令將會出錯.
7017
		#$conf["inBackGround"]="";
7018
		#$conf["getErr"],字串,"true"代表將錯誤輸出變成標準輸出,反之"false"為不變動.
7019
		#$conf["getErr"]="false";
7020
		#$conf["doNotRun"],字串,"true"代表不執行指令,預設為"false"會執行指令.
7021
		$conf["external::callShell"]["doNotRun"]="true";
7022
		#參考資料:
7023
		#exec=>http://php.net/manual/en/function.exec.php
7024
		#escapeshellcmd=>http://php.net/manual/en/function.escapeshellcmd.php
7025
		#escapeshellarg=>http://php.net/manual/en/function.escapeshellarg.php
7026
		#備註:
7027
		#不是所有指令都能用apache的身份執行,目前已知java,javac指令無法執行,使用root身份可能會被selinux阻擋.
7028
		#若使用的 command、argu 參數,含有 ~ 則會被視為字串,若有需要其於 shell 中代表的家目錄位置,可用 fileAccess::tildeToPath 來進行轉換.
7029
		$callShell=external::callShell($conf["external::callShell"]);
7030
		unset($conf["external::callShell"]);
7031
 
669 liveuser 7032
		#debug
7033
		#var_dump(__LINE__,$callShell);exit;
7034
 
668 liveuser 7035
		#如果執行失敗
7036
		if($callShell["status"]==="false"){
7037
 
7038
			#如果socket存在
7039
			if(file_exists($tmpUnixDomainSock)){
7040
 
7041
				#移除之
7042
				unlink($tmpUnixDomainSock);
7043
 
7044
				}#if end
7045
 
7046
			#設置執行失敗
7047
			$result["status"]="false";
7048
 
7049
			#設置執行錯誤訊息
7050
			$result["error"]=$callShell;
7051
 
7052
			#回傳結果
7053
			return $result;
7054
 
7055
			}#if end
7056
 
7057
		#函式說明:
7058
		#將一維陣列轉換為用特定符號間隔的字串,ex:array("1","2","3") to "a;b;c;".
7059
		#回傳的結果:
7060
		#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
7061
		#$result["function"],當前執行的function名稱
7062
		#$result["error"],錯誤訊息陣列.
7063
		#$result["content"],處理好的字串.
7064
		#$result["argu"],使用的參數.
7065
		#必填參數:
7066
		#$conf["inputArray"],字串陣列,要轉成字串的一維陣列.
7067
		$conf["arrays::arrayToString"]["inputArray"]=$callShell["escape"]["array"];
7068
		#可省略參數:
7069
		#$conf["spiltSymbol"],字串,用來區隔字串的符號,預設為;
7070
		$conf["arrays::arrayToString"]["spiltSymbol"]=" ";
7071
		#$conf["skipEnd"],字串,結尾是否不要加上符號,預設為"false",要加上符號,"true"代表不要加上符號。
7072
		$conf["arrays::arrayToString"]["skipEnd"]="true";
624 liveuser 7073
		#參考資料:
668 liveuser 7074
		#無.
624 liveuser 7075
		#備註:
7076
		#無.
668 liveuser 7077
		$arrayToString=arrays::arrayToString($conf["arrays::arrayToString"]);
7078
		unset($conf["arrays::arrayToString"]);
624 liveuser 7079
 
7080
		#如果執行失敗
668 liveuser 7081
		if($arrayToString["status"]==="false"){
624 liveuser 7082
 
668 liveuser 7083
			#如果socket存在
7084
			if(file_exists($tmpUnixDomainSock)){
7085
 
7086
				#移除之
7087
				unlink($tmpUnixDomainSock);
7088
 
7089
				}#if end
7090
 
624 liveuser 7091
			#設置執行失敗
7092
			$result["status"]="false";
7093
 
7094
			#設置執行錯誤訊息
668 liveuser 7095
			$result["error"]=$arrayToString;
624 liveuser 7096
 
7097
			#回傳結果
7098
			return $result;
7099
 
7100
			}#if end
7101
 
668 liveuser 7102
		#函式說明:
7103
		#透過proc來多執行序運作.
7104
		#回傳結果:
7105
		#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
7106
		#$reuslt["error"],執行不正常結束的錯訊息陣列.
7107
		#$result["function"],當前執行的函式名稱.
7108
		#$result["argu"],使用的參數.
7109
		#$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"代表程序的資訊.
7110
		#必填參數:
7111
		#$conf["cmds"],字串陣列,每個元素代表要執行的指令與參數.
7112
		$conf["threads::proc"]["cmds"]=array($arrayToString["content"]);
7113
		#可省略參數:
7114
		#$conf["wait"],字串,是否需要等待所有程序結束,預設為"true"要等待;反之為"false"不要等待.
7115
		$conf["threads::proc"]["wait"]="false";
7116
		#$conf["workingDir"],字串陣列,個別程式執行時的家目錄,預設不指定.
7117
		#$conf["workingDir"]=array("path");
7118
		#$conf["envs"],2維字串陣列,每個元素代表個別程式執行時的指定環境變數,key變數名稱;value為變數內容.預設為array("QBPWCF" => "Quick Build PHP Website Componment base on Fedora Linux");
7119
		#$conf["envs"]=array(array("key"=>"value"));
7120
		#$conf["executeBy"],字串陣列,每個元素代表個別指令要用什麼程式執行,預設為"bash".
7121
		#$conf["executeBy"]=array("bash");
7122
		#參考資料:
7123
		#https://www.php.net/manual/en/function.proc-open.php
7124
		#https://www.php.net/manual/en/function.proc-get-status.php
7125
		#備註:
7126
		#無.
7127
		$procForUnixDoaminSocket=threads::proc($conf["threads::proc"]);	
7128
		unset($conf["threads::proc"]);	
7129
 
7130
		#如果執行失敗
7131
		if($procForUnixDoaminSocket["status"]==="false"){
7132
 
7133
			#如果socket存在
7134
			if(file_exists($tmpUnixDomainSock)){
7135
 
7136
				#移除之
7137
				unlink($tmpUnixDomainSock);
7138
 
7139
				}#if end
7140
 
7141
			#設置執行失敗
7142
			$result["status"]="false";
7143
 
7144
			#設置執行錯誤訊息
7145
			$result["error"]=$procForUnixDoaminSocket;
7146
 
7147
			#回傳結果
7148
			return $result;
7149
 
7150
			}#if end
7151
 
7152
		#var_dump($procForUnixDoaminSocket);exit;
7153
 
7154
		#如果 unix doamin socket server 沒有在運行
7155
		if($procForUnixDoaminSocket["content"][0]["proc_get_status"]["running"]===false){
7156
 
7157
			#如果socket存在
7158
			if(file_exists($tmpUnixDomainSock)){
7159
 
7160
				#移除之
7161
				unlink($tmpUnixDomainSock);
7162
 
7163
				}#if end
7164
 
7165
			#設置執行失敗
7166
			$result["status"]="false";
7167
 
7168
			#設置執行錯誤訊息
7169
			$result["error"]=$procForUnixDoaminSocket;
7170
 
7171
			#回傳結果
7172
			return $result;
7173
 
7174
			}#if end
7175
 
7176
		#如果當下 unix doamin socket server 沒有在運行
669 liveuser 7177
		if(proc_get_status($procForUnixDoaminSocket["content"][0]["process"])["running"]===false){
668 liveuser 7178
 
7179
			#如果socket存在
7180
			if(file_exists($tmpUnixDomainSock)){
7181
 
7182
				#移除之
7183
				unlink($tmpUnixDomainSock);
7184
 
7185
				}#if end
7186
 
7187
			#設置執行失敗
7188
			$result["status"]="false";
7189
 
7190
			#設置執行錯誤訊息
7191
			$result["error"]=$procForUnixDoaminSocket;
7192
 
7193
			#回傳結果
7194
			return $result;
7195
 
7196
			}#if end
7197
 
7198
		#debug
7199
		#var_dump(__LINE__,"before send msg");
7200
 
7201
		#初始化要求執行程式的訊息
7202
		$msg=array();
7203
 
7204
		#設置執行的指令
7205
		$msg["cmd2run"]=$conf["cmd"];
7206
 
7207
		#如果有參數
7208
		if(isset($conf["params"])){
7209
 
7210
			#設置參數
7211
			$msg["params"]=$conf["params"];
7212
 
7213
			}#if end
7214
 
669 liveuser 7215
		#初始化儲存等待了幾秒
7216
		$waitSec=0;
668 liveuser 7217
 
669 liveuser 7218
		#無窮迴圈
7219
		while(true){
668 liveuser 7220
 
669 liveuser 7221
			#函式說明:
7222
			#連線到 unixDomainSockServer 提供的 unix domain socket.
7223
			#回傳結果:
7224
			#$result["status"],"true"代表執行正常;"false"代表執行不正常.
7225
			#$result["error"],錯誤訊息陣列.
7226
			#$result["function"],當前執行的函式名稱.
7227
			#$result["content"],取得的回應.
7228
			#必填參數:
7229
			#$conf["sock"],字串,要連線的unix domain socket.
7230
			$conf["sock::unixDomainSockClient"]["sock"]=$tmpUnixDomainSock;
7231
			#可省略參數:
7232
			#$conf["id"],字串,取得的id,若無此值,則會得到新的數值.
7233
			#$conf["id"]="";
7234
			#$conf["cmd"],字串,要執行的指令,當$conf["id"]參數合法時,才會執行.
7235
			#$conf["sock::unixDomainSockClient"]["cmd"]=$callShell["escape"]["cmd"];
7236
			#$conf["param"],參數陣列.
7237
			#$conf["sock::unixDomainSockClient"]["param"]=$callShell["escape"]["argu"];
7238
			#$conf["escaped"],字串,param參數是否已經escaped了,預設為"false",反之為"true".
7239
			#$conf["sock::unixDomainSockClient"]["escaped"]="true";
7240
			#$conf["custom"],陣列,要客制化傳輸的內容,會覆蓋以上除了$conf["id"]以外的可省略參數.
7241
			#$conf["custom"]=array();
7242
			#參考資料:
7243
			#http://php.net/manual/en/function.stream-socket-client.php
7244
			#http://php.net/manual/en/function.stream-get-contents.php
7245
			#備註:
7246
			#無.
7247
			$paramsOfUnixDomainSockClient=$conf["sock::unixDomainSockClient"];
7248
			$unixDomainSockClient=sock::unixDomainSockClient($paramsOfUnixDomainSockClient);
7249
			unset($paramsOfUnixDomainSockClient);
668 liveuser 7250
 
669 liveuser 7251
			#如果執行成功
7252
			if($unixDomainSockClient["status"]==="true"){
7253
 
7254
				#debug
7255
				#var_dump(__LINE__,"before parse id");
7256
 
7257
				#跳出while
7258
				break;
7259
 
668 liveuser 7260
				}#if end
7261
 
669 liveuser 7262
			#提示錯誤
7263
			else{
668 liveuser 7264
 
669 liveuser 7265
				#debug
7266
				#var_dump(__LINE__,$unixDomainSockClient);
7267
 
7268
				}#else end
7269
 
7270
			#如果當下 unix doamin socket server 沒有在運行
7271
			if(proc_get_status($procForUnixDoaminSocket["content"][0]["process"])["running"]===false){
7272
 
7273
				#如果socket存在
7274
				if(file_exists($tmpUnixDomainSock)){
7275
 
7276
					#移除之
7277
					unlink($tmpUnixDomainSock);
7278
 
7279
					}#if end
7280
 
7281
				#設置執行失敗
7282
				$result["status"]="false";
7283
 
7284
				#設置執行錯誤訊息
7285
				$result["error"][]="client取得回應前server就意外結束了";
7286
 
7287
				#設置執行錯誤訊息
7288
				$result["error"][]=$procForUnixDoaminSocket;
7289
 
7290
				#回傳結果
7291
				return $result;
7292
 
7293
				}#if end
7294
 
7295
			#等後1秒,擔心unix domain socket server 尚未跑起來.
7296
			sleep(1);
7297
 
7298
			#已等待時間加1秒
7299
			$waitSec=$waitSec+1;
7300
 
7301
			}#while end
668 liveuser 7302
 
7303
		#debug
7304
		#var_dump(__LINE__,"json string got:".$unixDomainSockClient["content"]);
7305
 
7306
		#取得json回應
7307
		$jsonRes=json_decode($unixDomainSockClient["content"]);
7308
 
7309
		#如果執行失敗
7310
		if($jsonRes===null){
7311
 
7312
			#如果socket存在
7313
			if(file_exists($tmpUnixDomainSock)){
7314
 
7315
				#移除之
7316
				unlink($tmpUnixDomainSock);
7317
 
7318
				}#if end
7319
 
7320
			#設置執行錯誤識別
7321
			$result["status"]="false";
7322
 
7323
			#設置錯誤訊息
7324
			$result["error"]=$unixDomainSockClient;
7325
 
7326
			#回傳結果
7327
			return $result;
7328
 
7329
			}#if end
7330
 
7331
		#如果沒有產生新id
7332
		if(!isset($jsonRes->id)){
7333
 
7334
			#如果socket存在
7335
			if(file_exists($tmpUnixDomainSock)){
7336
 
7337
				#移除之
7338
				unlink($tmpUnixDomainSock);
7339
 
7340
				}#if end
7341
 
7342
			#設置執行錯誤識別
7343
			$result["status"]="false";
7344
 
7345
			#設置錯誤訊息
7346
			$result["error"]=$unixDomainSockClient;
7347
 
7348
			#回傳結果
7349
			return $result;
7350
 
7351
			}#if end
7352
 
7353
		#debug
7354
		#var_dump(__LINE__,"got id:".$jsonRes->id);
7355
 
669 liveuser 7356
		#debug
7357
		#while(true){};
7358
 
668 liveuser 7359
		#用新的id再傳送一次要求給 qbpwcf_usock_path
669 liveuser 7360
		$paramsOfUnixDomainSockClient=array();
7361
		$paramsOfUnixDomainSockClient["sock"]=$tmpUnixDomainSock;
668 liveuser 7362
		$paramsOfUnixDomainSockClient["id"]=$jsonRes->id;
7363
		$paramsOfUnixDomainSockClient["custom"]=$msg;
7364
		$unixDomainSockClient=sock::unixDomainSockClient($paramsOfUnixDomainSockClient);
7365
		unset($paramsOfUnixDomainSockClient);
7366
 
7367
		#debug
7368
		#var_dump(__LINE__,$unixDomainSockClient);
7369
 
7370
		#如果執行失敗
7371
		if($unixDomainSockClient["status"]==="false"){
7372
 
7373
			#如果socket存在
7374
			if(file_exists($tmpUnixDomainSock)){
7375
 
7376
				#移除之
7377
				unlink($tmpUnixDomainSock);
7378
 
7379
				}#if end
7380
 
7381
			#設置執行錯誤識別
7382
			$result["status"]="false";
7383
 
7384
			#設置錯誤訊息
7385
			$result["error"]=$unixDomainSockClient;
7386
 
7387
			#回傳結果
7388
			return $result;
7389
 
7390
			}#if end
7391
 
7392
		#debug
7393
		#var_dump(__LINE__,$unixDomainSockClient);
7394
 
7395
		#如果有回應的內容
7396
		if(!empty($unixDomainSockClient["content"])){
7397
 
7398
			#取得json回應
7399
			$jsonRes=(array)json_decode($unixDomainSockClient["content"]);
7400
 
7401
			#如果執行失敗
7402
			if($jsonRes===null){
7403
 
7404
				#如果socket存在
7405
				if(file_exists($tmpUnixDomainSock)){
7406
 
7407
					#移除之
7408
					unlink($tmpUnixDomainSock);
7409
 
7410
					}#if end
7411
 
7412
				#設置執行錯誤識別
7413
				$result["status"]="false";
7414
 
7415
				#設置錯誤訊息
7416
				$result["error"]=$unixDomainSockClient;
7417
 
7418
				#回傳結果
7419
				return $result;
7420
 
7421
				}#if end
7422
 
7423
			#如果執行指令失敗
7424
			if($jsonRes["status"]==="false"){
7425
 
7426
				#如果socket存在
7427
				if(file_exists($tmpUnixDomainSock)){
7428
 
7429
					#移除之
7430
					unlink($tmpUnixDomainSock);
7431
 
7432
					}#if end
7433
 
7434
				#設置執行錯誤識別
7435
				$result["status"]="false";
7436
 
7437
				#設置錯誤訊息
7438
				$result["error"]=$jsonRes["error"];
7439
 
7440
				#回傳結果
7441
				return $result;
7442
 
7443
				}#if end
7444
 
7445
			#印出client收到的結果
669 liveuser 7446
			#var_dump($jsonRes);
668 liveuser 7447
 
7448
			}#if end
7449
 
669 liveuser 7450
		#debug
7451
		#var_dump(__LINE__,$procForUnixDoaminSocket);
7452
 
7453
		#初始化儲存標準輸出
7454
		$result["content"]["stdout"]="";
7455
 
7456
		#初始化儲存非標準輸出
7457
		$result["content"]["stderr"]="";
7458
 
668 liveuser 7459
		#等待 unixDomainSockServer 結束執行
7460
		while(true){
7461
 
7462
			#取得程序狀態
7463
			$proc_get_status=proc_get_status($procForUnixDoaminSocket["content"][0]["process"]);
7464
 
669 liveuser 7465
			/* debug
668 liveuser 7466
 
669 liveuser 7467
			#函式說明:
7468
			#撰寫log
7469
			#回傳結果:
7470
			#$result["status"],狀態,"true"或"false".
7471
			#$result["error"],錯誤訊息陣列.
7472
			#$result["function"],當前函式的名稱.
7473
			#$result["argu"],使用的參數.
7474
			#$result["content"],要寫入log的內容字串.
7475
			#必填參數:
7476
			#$conf["path"],字串,log檔案的路徑與名稱.
7477
			$conf["logs::record"]["path"]="/tmp/sock::runWithAutoAddMemoryDaemon.log";
7478
			#$conf["content"],any,要寫的內容,若內容不為字串則會用var_dump的格式寫入.
7479
			$conf["logs::record"]["content"]=$proc_get_status;
7480
			#$conf["fileArgu"],字串,php變數__FILE__的內容,亦即該檔案在檔案系統的絕對路徑
7481
			$conf["logs::record"]["fileArgu"]=__FILE__;
7482
			#可省略參數:
7483
			#$conf["rewrite"],預設為"false",接續寫入;反之"true"代表重新寫入.
7484
			#$conf["rewrite"]="false";
7485
			#$conf["returnOnly"],預設為"false",會寫入到log檔案.若為"true"則不會寫入log.
7486
			#$conf["returnOnly"]="true";
7487
			#參考資料:
7488
			#無.
7489
			#備註:
7490
			#無.
7491
			$record=logs::record($conf["logs::record"]);
7492
			unset($conf["logs::record"]);
7493
 
7494
			#如果執行失敗
7495
			if($record["status"]==="false"){
668 liveuser 7496
 
669 liveuser 7497
				#設置執行錯誤識別
7498
				$result["status"]="false";
7499
 
7500
				#設置執行錯誤
7501
				$result["error"]=$record;
7502
 
7503
				#回傳結果
7504
				return $result;
7505
 
7506
				}#if end
7507
 
7508
			*/
7509
 
7510
			#確認process是否存在
7511
			#ps auxwf | grep sshd | grep -v 'grep' | wc -l
7512
			#函式說明:
7513
			#呼叫shell執行系統命令,並取得回傳的內容.
7514
			#回傳結果:
7515
			#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
7516
			#$result["error"],錯誤訊息陣列.
7517
			#$result["function"],當前執行的函數名稱.
7518
			#$result["argu"],使用的參數.
7519
			#$result["cmd"],執行的指令內容.
7520
			#$result["fullCmd"],如果參數 $conf["inBackGround"] 為 "true" 則會回傳該值.
7521
			#$result["output"],爲執行完二元碼後的輸出陣列,若 $conf["inBackGround"] 為 "true",則為當下的輸出.
7522
			#$result["tmpFileOutput"],儲存輸出的暫存檔案名稱,若 $conf["inBackGround"] 為 "true" 則會回傳該值.
7523
			#$result["running"],是否還在執行.
7524
			#$result["pid"],pid.
7525
			#$result["statusCode"],執行結束後的代碼.
7526
			#$result["escape"],陣列,儲存重新排序過且已經escape過的指令(key為"cmd")與參數(key為"argu")與兩者組合的一維陣列(key為"array").
7527
			#必填參數:
7528
			#$conf["command"],字串,要執行的指令.
7529
			$conf["external::callShell"]["command"]="ps";
7530
			#$conf["fileArgu"],字串,變數__FILE__的內容.
7531
			$conf["external::callShell"]["fileArgu"]=$conf["fileArgu"];
7532
			#可省略參數:
7533
			#$conf["argu"],陣列字串,指令搭配的參數,預設為空陣列.
7534
			$conf["external::callShell"]["argu"]=array("auxwf","|","grep",$proc_get_status["pid"],"|","grep","-v","'grep'","|","wc","-l");
7535
			#$conf["arguIsAddr"],陣列字串,指令搭配的哪些參數為路徑,為路徑的參數會進行轉換以便符合呼叫當前函數的位置,預設不指定,若有3個參數,其中第3個參數為路徑,則表示為array("false","false","true").
7536
			#$conf["arguIsAddr"]=array();
7537
			#$conf["pre"],陣列,要在本指令前執行的每個指令與參數.
7538
			#$conf["pre"][$i]["cmd"],字串,要在本指令前執行的第$i+1個指令.
7539
			#$conf["pre"][$i]["param"],陣列字串,要在本指令前執行的第$i+1個指令的參數.
7540
			#$conf["enablePrintDescription"],字串,是否要印出$conf["printDescription"]的內容,"true"代表要,"false"代表不要,預設為"false".
7541
			#$conf["enablePrintDescription"]="true";
7542
			#$conf["printDescription"],字串,執行該外部程式前要印出來的的文字,預設為$conf["command"]的內容加上使用的$conf["argu"]參數.
7543
			#$conf["printDescription"]="";
7544
			#$conf["escapeshellarg"],字串,是否要啟用過濾參數,用了比較安全,但可能會出錯,"true"為啟用,"false"為不啟用,預設為"false".如果參數為"< 、<< 、> 、>> 、| 、2>&1"之一則不會過濾.
7545
			#$conf["escapeshellarg"]="false";
7546
			#$conf["thereIsShellVar"],陣列字串,指令搭配的參數"argu",若含有「\'」,則取代為「"」.每個argu參數都要有對應的元素."true"代表要置換.
7547
			#$conf["thereIsShellVar"]=array();
7548
			#$conf["username"],字串,要用什麼使用者來執行,預設為執行php的使用者,該參數不適用於apache環境.
7549
			#$conf["username"]="";
7550
			#$conf["password"],字串,root的使用者密碼,預設不使用密碼,該參數不適用於apache環境.
7551
			#$conf["password"]="";
7552
			#$conf["useScript"],字串,是否要啟用Linux的script指令來記錄輸出,"true"代表要,Fedora的selinux會擋住該操作;"false"代表不要,預設為"false".
7553
			#$conf["useScript"]="";
7554
			#$conf["logFilePath"],字串,當 $conf["useScript"] 為 "true" 時,輸出的內容要暫存到哪裡,預設為 "/tmp/.qbpwcf_tmp/external/callShell/".
7555
			#$conf["logFilePath"]=".qbpwcf_tmp/external/callShell/";
7556
			#$conf["inBackGround"],字串,是否要在背景執行,且不會等待程式執行結束再執行下一個指令,"true"代表是,"false"代表不要,預設為"false",如果$conf["command"]有用「;」區隔的多個指令將會出錯.
7557
			#$conf["inBackGround"]="";
7558
			#$conf["getErr"],字串,"true"代表將錯誤輸出變成標準輸出,反之"false"為不變動.
7559
			#$conf["getErr"]="false";
7560
			#$conf["doNotRun"],字串,"true"代表不執行指令,預設為"false"會執行指令.
7561
			#$conf["doNotRun"]="false";
7562
			#參考資料:
7563
			#exec=>http://php.net/manual/en/function.exec.php
7564
			#escapeshellcmd=>http://php.net/manual/en/function.escapeshellcmd.php
7565
			#escapeshellarg=>http://php.net/manual/en/function.escapeshellarg.php
7566
			#備註:
7567
			#不是所有指令都能用apache的身份執行,目前已知java,javac指令無法執行,使用root身份可能會被selinux阻擋.
7568
			#若使用的 command、argu 參數,含有 ~ 則會被視為字串,若有需要其於 shell 中代表的家目錄位置,可用 fileAccess::tildeToPath 來進行轉換.
7569
			$callShell=external::callShell($conf["external::callShell"]);
7570
			unset($conf["external::callShell"]);
7571
 
7572
			#如果執行失敗
7573
			if($callShell["status"]==="false"){
7574
 
7575
				#設置執行失敗
7576
				$result["status"]="false";
7577
 
7578
				#設置執行錯誤訊息
7579
				$result["error"]=$callShell;
7580
 
7581
				#回傳結果
7582
				return $result;
7583
 
7584
				}#if end
7585
 
7586
			#如果沒有輸出結果
7587
			if(!isset($callShell["output"][0])){
7588
 
7589
				#設置執行失敗
7590
				$result["status"]="false";
7591
 
7592
				#設置執行錯誤訊息
7593
				$result["error"]=$callShell;
7594
 
7595
				#回傳結果
7596
				return $result;
7597
 
7598
				}#if end
7599
 
7600
			#如果執行結束了
7601
			if( $proc_get_status["running"]===false || $callShell["output"][0]==="0" ){
7602
 
668 liveuser 7603
				#取得程式執行過程產生的標準輸出
669 liveuser 7604
				$result["content"]["stdout"]=$procForUnixDoaminSocket["content"][0]["content"];
7605
 
7606
				#如果是resource
7607
				if(gettype($result["content"]["stdout"])==="resource"){
7608
 
7609
					#讀取內容
7610
					$result["content"]["stdout"]=stream_get_contents($result["content"]["stdout"]);
7611
 
7612
					}#if end
7613
 
668 liveuser 7614
				#取得程式執行過程產生的非標準輸出
669 liveuser 7615
				$result["content"]["stderr"]=$procForUnixDoaminSocket["content"][0]["error"];
7616
 
7617
				#如果是resource
7618
				if(gettype($result["content"]["stderr"])==="resource"){
7619
 
7620
					#讀取內容
7621
					$result["content"]["stderr"]=stream_get_contents($result["content"]["stderr"]);
7622
 
7623
					}#if end
668 liveuser 7624
 
7625
				#跳出 while
7626
				break;
7627
 
7628
				}#if end
7629
 
669 liveuser 7630
			#休息1秒
7631
			sleep(1);
7632
 
668 liveuser 7633
			}#while end
7634
 
7635
		#如果socket存在
7636
		if(file_exists($tmpUnixDomainSock)){
7637
 
7638
			#移除之
7639
			unlink($tmpUnixDomainSock);
7640
 
7641
			}#if end
7642
 
624 liveuser 7643
		#設置執行正常
7644
		$result["status"]="true";
7645
 
7646
		#回傳結果
7647
		return $result;
7648
 
7649
		}#function runWithAutoAddMemoryDaemon end
7650
 
717 liveuser 7651
	/*
7652
	#函式說明:
7653
	#用fwrite寫入到resource,可以指定每個寫入字串的結尾方式.
7654
	#回傳結果:
7655
	#$result["status"],執行是否正常,"true"為正常,"false"為不正常.
7656
	#$result["error"],錯誤訊息陣列.
7657
	#$result["function"],當前執行的函數名稱.
7658
	#$result["argu"],使用的參數.
7659
	#$result["is_writable"],參數stream是否為可寫入的resource,"true"代表可寫入;"false"代表不可寫入.
7660
	#必填參數:
7661
	#$conf["stream"],resource,寫入的目標.
7662
	$conf["stream"]="";
7663
	#$conf["data"],字串陣列,要寫入的內容,每個元素代表每段要寫入的內容.
7664
	$conf["data"]=array();
7665
	#可省略參數:
7666
	#$conf["msgEndType"],字串,訊息結尾要怎麼寫,預設為"none",代表不做處理;"EOL"代表結尾要用PHP_EOL;"HTTP/1.1"代表"data"參數最多為2個,分別為header跟body,結尾方式為兩個PHP_EOL.
7667
	#$conf["msgEndType"]="";
7668
	#$conf["autoClose"],字串,寫入結束後是否要關閉resource,預設為"false"代表保持開着;反之為"true".
7669
	#$conf["autoClose"]="false";
7670
	#參考資料:
7671
	#https://stackoverflow.com/questions/5294305/how-to-check-if-a-php-stream-resource-is-readable-or-writable#5294425
7672
	#https://www.php.net/manual/en/function.stream-get-meta-data.php
7673
	#https://www.php.net/manual/en/function.is-writable.php
7674
	#https://www.php.net/manual/en/function.socket-get-status.php
720 liveuser 7675
	#https://www.php.net/manual/en/function.fopen.php
717 liveuser 7676
	#備註:
7677
	#無.
7678
	*/
7679
	public static function fwrite(&$conf=array()){
7680
 
7681
		#初始化要回傳的結果
7682
		$result=array();
7683
 
7684
		#取得當前執行的函數名稱
7685
		$result["function"]=__FUNCTION__;
7686
 
7687
		#取得參數
7688
		$result["argu"]=$conf;
7689
 
7690
		#如果 $conf 不為陣列
7691
		if(gettype($conf)!="array"){
7692
 
7693
			#設置執行失敗
7694
			$result["status"]="false";
7695
 
7696
			#設置執行錯誤訊息
7697
			$result["error"][]="\$conf變數須為陣列形態";
7698
 
7699
			#如果傳入的參數為 null
7700
			if(is_null($conf)){
7701
 
7702
				#設置執行錯誤訊息
7703
				$result["error"][]="\$conf變數不得為null,請檢查函數「".$result["function"]."」的參數設置有無正確!";
7704
 
7705
				}#if end
7706
 
7707
			#回傳結果
7708
			return $result;
7709
 
7710
			}#if end
7711
 
7712
		#檢查參數
7713
		#函式說明:
7714
		#檢查必填與可省略的參數,可省略參數可指定預設要給與什麼數值內容.
7715
		#回傳結果:
7716
		#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
7717
		#$result["error"],執行不正常結束的錯訊息陣列.
7718
		#$result["simpleError"],簡單表示的錯誤訊息.
7719
		#$result["function"],當前執行的函式名稱.
7720
		#$result["argu"],設置給予的參數.
7721
		#$result["passed"],識別要檢查的全體變數是否存在以及型態是否正確的變數,"true"代表檢查全部通過;"false"代表檢查不通過
7722
		#$result[$shouldBeCheckedVarName]["varExist"],所檢查的變數是否存在,"false"代表不存在;"true"代表存在
7723
		#$result[$shouldBeCheckedVarName]["varType"],所檢查的變數型態是否正確,"false"代表錯誤;"true"代表正確
7724
		#$result[$shouldBeCheckedVarName]["error"],每個參數設定的錯誤訊息
7725
		#$result["shouldNotBeEmpty"],不應該為空字串或控陣列的變數.
7726
		#$result["argu"],字串陣列,目前輸入的參數名稱陣列.
7727
		#$result["legalVarName"],字串陣列,合法可用的參數名稱陣列.
7728
		#$result["notNeedVar"],字串陣列,多餘的參數名稱.
7729
		#必填參數:
7730
		#$conf["varInput"],陣列變數,要檢查的陣列變數,請在要檢查的參數前面加上&,這樣變動的結果才能被套用。
7731
		$conf["variableCheck::checkArguments"]["varInput"]=&$conf;
7732
		#$conf["referenceVarKey"],字串,$conf參數後面的key值,用於移除不要的參考陣列.
7733
		$conf["variableCheck::checkArguments"]["referenceVarKey"]="variableCheck::checkArguments";
7734
		#可省略參數:
7735
		#$conf["mustBeFilledVariableName"],爲必填參數的變數名稱陣列,形態爲陣列變數,元素數量需要跟"mustBeFilledVariableType"參數的元素數量一致,例如: $conf["mustBeFilledVariableName"] = array("id","account","password");
7736
		$conf["variableCheck::checkArguments"]["mustBeFilledVariableName"]=array("stream","data");
7737
		#$conf["mustBeFilledVariableType"],爲必填參數的變數陣列應該爲何種變數形態,形態爲陣列,元素數量需要跟"mustBeFilledVariableName"參數的元素數量一致,例如: $conf["mustBeFilledVariableType"] = array("string",integer,"double","resource","object"); , null代表不指定變數形態.
7738
		$conf["variableCheck::checkArguments"]["mustBeFilledVariableType"]=array("resource","array");
7739
		#$conf["canBeEmptyString"],字串,必填變數內容如果是空字串就不能算是有設置的話,請設為"false",預設爲"true",可以為空字串.
7740
		#$conf["variableCheck::checkArguments"]["canBeEmptyString"]="false";
7741
		#$conf["canNotBeEmpty"],字串陣列,哪些必填參數的內容不得為空字串或空陣列,僅當$conf["canBeEmptyString"]為"true"時會生效.
7742
		$conf["variableCheck::checkArguments"]["canNotBeEmpty"]=array("stream");
7743
		#$conf["canBeEmpty"],字串陣列,哪些必填參數的內容可為空字串或空陣列,僅當$conf["canBeEmptyString"]為"false"時會生效.
7744
		#$conf["canBeEmpty"]=array();
7745
		#$conf["skipableVariableCanNotBeEmpty"],字串陣列,哪些可省略參數不可以為空字串或空陣列.
7746
		$conf["variableCheck::checkArguments"]["skipableVariableCanNotBeEmpty"]=array("msgEndType","autoClose");
7747
		#$conf["skipableVariableName"],陣列字串,爲可省略參數的變數名稱陣列,形態爲陣列變數,例如: $conf["skipableVariableName"] = array("id","account","password");
7748
		$conf["variableCheck::checkArguments"]["skipableVariableName"]=array("msgEndType","autoClose");
7749
		#$conf["skipableVariableType"],陣列字串,爲可省略參數的變數名稱陣列,形態爲陣列變數,例如: $conf["skipableVariableType"] = array("string",integer,"double");
7750
		$conf["variableCheck::checkArguments"]["skipableVariableType"]=array("string","string");
7751
		#$conf["skipableVarDefaultValue"],字串陣列,每個不存在的可省略變數要初始化為什麼,null與代表不指定,若預設值是參數之一,請將$conf["mustBeFilledVar"]改成"\$conf["\mustBeFilledVar\"]".
7752
		$conf["variableCheck::checkArguments"]["skipableVarDefaultValue"]=array("none","false");
7753
		#$conf["disallowAllSkipableVarIsEmpty"],字串,是否允許每個可省略參數都為空字串,預設為"true"允許,反之為"false".
7754
		#$conf["disallowAllSkipableVarIsEmpty"]="";
7755
		#$conf["disallowAllSkipableVarIsEmptyArray"],字串,是否允許每個可省略參數都為空陣列,預設為"true"允許,反之為"false".
7756
		#$conf["disallowAllSkipableVarIsEmptyArray"]="";
7757
		#$conf["disallowAllSkipableVarNotExist"],字串,是否不允許每個可省略參數都不存在,預設為"false"代表允許,反之為"true".
7758
		#$conf["disallowAllSkipableVarNotExist"]="";
7759
		#$conf["arrayCountEqualCheck"],字串陣列,為檢查哪些陣列參數的元素數量要一樣,$conf["arrayCountEqualCheck"][$i]=array()為第$i組key為哪些的變數其元素數量要相等.
7760
		#$conf["arrayCountEqualCheck"][]=array();
7761
		#參考資料:
7762
		#array_keys=>http://php.net/manual/en/function.array-keys.php
7763
		#備註:
7764
		#無.
7765
		$checkArguments=variableCheck::checkArguments($conf["variableCheck::checkArguments"]);
7766
		unset($conf["variableCheck::checkArguments"]);
7767
 
7768
		#如果執行失敗
7769
		if($checkArguments["status"]==="false"){
7770
 
7771
			#設置執行失敗
7772
			$result["status"]="false";
7773
 
7774
			#設置錯誤資訊
7775
			$result["error"]=$checkArguments;
7776
 
7777
			#回傳結果
7778
			return $result;
7779
 
7780
			}#if end
7781
 
7782
		#如果檢查不通過
7783
		if($checkArguments["passed"]==="false"){
7784
 
7785
			#設置執行失敗
7786
			$result["status"]="false";
7787
 
7788
			#設置錯誤資訊
7789
			$result["error"]=$checkArguments;
7790
 
7791
			#回傳結果
7792
			return $result;
7793
 
7794
			}#if end
7795
 
7796
		#debug
720 liveuser 7797
		#var_dump(__LINE__,$conf["stream"]);
717 liveuser 7798
 
7799
		/*
7800
 
7801
		#函式說明:
7802
		#處理各種錯誤與例外.
7803
		#回傳結果:
7804
		#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
7805
		#$result["passed"],檢查是否通過,"true"代表通過,"false"代表不通過.
7806
		#$result["argu"],使用的參數.
7807
		#$result["function"],當前執行的函數.
7808
		#$result["error"],涵式錯誤訊息陣列.
7809
		#必填參數:
7810
		#無.
7811
		#可省略參數:
7812
		#$conf["allowCodition"],陣列,滿足什麼條件的錯誤跟例外要繼續執行而不中斷.
7813
		$conf["variableCheck::setErrorHandler"]["allowCodition"]=array("stream_get_meta_data(): supplied resource is not a valid stream resource","[function] => stream_get_meta_data");
7814
		#$conf["debug"],字串,"true"代表遇到不允許繼續執行的例外時要輸出debug資訊;預設為"false";
7815
		$conf["variableCheck::setErrorHandler"]["debug"]="true";
7816
		#$conf["format"],字串,遇到不允許的錯誤時,要用什麼格式呈現,預設為"html",其他選擇有"cmd".
7817
		#$conf["format"]="html";
7818
		#參考資料:
7819
		#無.
7820
		#備註:
7821
		#無.
7822
		$setErrorHandler=variableCheck::setErrorHandler($conf["variableCheck::setErrorHandler"]);
7823
		unset($conf["variableCheck::setErrorHandler"]);
7824
 
7825
		#如果有回傳內容
7826
		if($setErrorHandler!==null){
7827
 
7828
			#設置執行失敗
7829
			$result["status"]="false";
7830
 
7831
			#設置錯誤資訊
7832
			$result["error"]=$setErrorHandler;
7833
 
7834
			#回傳結果
7835
			return $result;
7836
 
7837
			}#if end
7838
 
7839
		*/
7840
 
7841
		#取得 stream 狀態
7842
		$stream_get_meta_data=stream_get_meta_data($conf["stream"]);
7843
 
720 liveuser 7844
		#debug
7845
		#var_dump(__LINE__,$stream_get_meta_data);
7846
 
7847
		#如果存在 uri
7848
		if(isset($stream_get_meta_data["uri"])){
7849
 
7850
			#取得能否寫入
7851
			$is_writable=is_writable($stream_get_meta_data["uri"]);
7852
 
7853
			}#if end
7854
 
7855
		#反之用 mode 來判斷
7856
		else if(isset($stream_get_meta_data["mode"])){
7857
 
7858
			#函式說明:
7859
			#檢查一個字串裡面是否有多個關鍵字
7860
			#回傳結果:
7861
			#$result["status"],"true"代表執行成功,"false"代表執行失敗.
7862
			#$result["error"],錯誤訊息.
7863
			#$result["function"],當前執行的函數名稱.
7864
			#$result["founded"],是否有找到的關鍵字,"true"代表有找到關鍵字;"false"代表沒有找到關鍵字.
7865
			#$result["foundedKeyWords"],找到的關鍵字.
7866
			#$result["foundedAll"],是否有找到全部的關鍵字,"true"代表有;"false"代表沒有.
7867
			#$result["argu"],使用的參數.
7868
			#必填參數:
7869
			#$conf["keyWords"],字串陣列,想要搜尋的關鍵字.
7870
			$conf["search::findManyKeyWords"]["keyWords"]=array("r+","w","a","x","c");
7871
			#$conf["string"],字串,要被搜尋的字串內容.
7872
			$conf["search::findManyKeyWords"]["string"]=$stream_get_meta_data["mode"];
7873
			#可省略參數:
7874
			#$conf["completeEqual"],字串,是否內容要完全符合,不能多出任何不符合的內容,預設為不需要完全符合.
7875
			#$conf["completeEqual"]="true";
7876
			#參考資料:
7877
			#無.
7878
			#備註:
7879
			#無.
7880
			$findManyKeyWords=search::findManyKeyWords($conf["search::findManyKeyWords"]);
7881
			unset($conf["search::findManyKeyWords"]);
7882
 
7883
			#如果執行失敗
7884
			if($findManyKeyWords["status"]==="false"){
7885
 
7886
				#設置執行失敗
7887
				$result["status"]="false";
7888
 
7889
				#設置錯誤資訊
7890
				$result["error"]=$findManyKeyWords;
7891
 
7892
				#回傳結果
7893
				return $result;
7894
 
7895
				}#if end
7896
 
7897
			#如果模式含有寫入的屬性
7898
			if($findManyKeyWords["founded"]==="true"){
7899
 
7900
				#設置可以寫入
7901
				$is_writable=true;
7902
 
7903
				}#if end
7904
 
7905
			}#else 
7906
 
7907
		#反之需要其他判斷方式
7908
		else{
7909
 
7910
			#設置警示訊息
7911
			$result["warning"][]="無法判別 resource 能否寫入";
7912
 
7913
			#設置警示訊息
7914
			$result["warning"][]=$stream_get_meta_data;
7915
 
7916
			#直接放行
7917
			$is_writable=true;
7918
 
7919
			}#else end
7920
 
717 liveuser 7921
		#如果不可寫入
7922
		if($is_writable!==true){
7923
 
7924
			#設置執行失敗
7925
			$result["status"]="false";
7926
 
7927
			#設置錯誤資訊
7928
			$result["error"][]="resource 無法寫入";
7929
 
7930
			#設置錯誤資訊
7931
			$result["error"][]=$stream_get_meta_data;
7932
 
7933
			#設置resource不可寫入
7934
			$result["is_writable"]="false";
7935
 
7936
			#回傳結果
7937
			return $result;
7938
 
7939
			}#if end
7940
 
7941
		#設置resource可寫入
7942
		$result["is_writable"]="true";
7943
 
7944
		#判斷訊息結尾的格式
7945
		switch($conf["msgEndType"]){
7946
 
7947
			#如果是 "none"
7948
			case "none":
7949
 
7950
				#要寫入的每個字串
7951
				foreach($conf["data"] as $msg){
7952
 
7953
					#寫入內容
7954
					fwrite($conf["stream"],$msg);
7955
 
7956
					}#foreach end
7957
 
7958
				break;
7959
 
7960
			#如果是 "EOL"
7961
			case "EOL":
7962
 
7963
				#要寫入的每個字串
7964
				foreach($conf["data"] as $msg){
7965
 
7966
					#寫入內容,用PHP_EOL結尾.
7967
					fwrite($conf["stream"],$msg.PHP_EOL);
7968
 
7969
					}#foreach end
7970
 
7971
				break;
7972
 
7973
			#如果是 "HTTP/1.1"
7974
			case "HTTP/1.1":
7975
 
7976
				#如果要寫入的字串大於2段
7977
				if(count($conf["data"])>2){
7978
 
7979
					#設置執行失敗
7980
					$result["status"]="false";
7981
 
7982
					#設置錯誤資訊
7983
					$result["error"][]="當參數 msgEndType 為 ".$conf["msgEndType"]." 時,參數 data 的數量不得超過2個.";
7984
 
7985
					#設置resource不可寫入
7986
					$result["is_writable"]="false";
7987
 
7988
					#回傳結果
7989
					return $result;
7990
 
7991
					}#if end
7992
 
7993
				#要寫入的每個字串
7994
				foreach($conf["data"] as $msg){
7995
 
7996
					#寫入 header/body
7997
					fwrite($conf["stream"],$msg.PHP_EOL.PHP_EOL);
7998
 
7999
					}#foreach end
8000
 
8001
				#跳出switch
8002
				break;
8003
 
8004
			#非預期的類型
8005
			default:
8006
 
8007
				#設置執行失敗
8008
				$result["status"]="false";
8009
 
8010
				#設置錯誤資訊
8011
				$result["error"][]="unsupported msgEndType ".$conf["msgEndType"];
8012
 
8013
				#回傳結果
8014
				return $result;
8015
 
8016
			}#switch end
8017
 
8018
		#若要關閉resource
8019
		if($conf["autoClose"]==="true"){
8020
 
8021
			#關閉resouce.
8022
			fclose($conf["stream"]);
8023
 
8024
			}#if end
8025
 
8026
		#設置執行正常
8027
		$result["status"]="true";
8028
 
8029
		#回傳結果
8030
		return $result;
8031
 
8032
		}#function fwrite end
8033
 
1 liveuser 8034
	}#class sock end
8035
 
8036
?>