Rev 911 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | RSS feed
<?php/*QBPWCF, Quick Build PHP website Component base on Fedora Linux.Copyright (C) 2015~2024 Min-Jhin,ChenThis file is part of QBPWCF.QBPWCF is free software: you can redistribute it and/or modifyit under the terms of the GNU General Public License as published bythe Free Software Foundation, either version 3 of the License, or(at your option) any later version.QBPWCF is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; without even the implied warranty ofMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See theGNU General Public License for more details.You should have received a copy of the GNU General Public Licensealong with QBPWCF. If not, see <http://www.gnu.org/licenses/>.*/namespace qbpwcf;/*類別說明:應用qemu的類別.備註:無.*/class qemu{/*#函式說明:#當前類別被呼叫的靜態方法不存在時,將會執行該函數,回報該方法不存在.#回傳結果:#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.#$reuslt["error"],執行不正常結束的錯訊息陣列.#$result["function"],當前執行的函式名稱.#必填參數:#$method,物件,為物件實體或類別名稱,會自動置入該參數.#$arguments,陣列,為呼叫方法時所用的參數.#參考資料:#__call=>http://php.net/manual/en/language.oop5.overloading.php#object.callstatic*/public function call($method,$arguments){#取得當前執行的函式$result["function"]=__FUNCTION__;#設置執行不正常$result["status"]="false";#設置執行錯誤$result["error"][]=__NAMESPACE__ ."/".$method."() 不存在!";#設置所丟入的參數$result["error"][]=$arguments;#回傳結果return $result;}#function __call end/*#函式說明:#當前類別被呼叫的靜態方法不存在時,將會執行該函數,回報該方法不存在.#回傳結果:#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.#$reuslt["error"],執行不正常結束的錯訊息陣列.#$result["function"],當前執行的函式名稱.#必填參數:#$method,物件,為物件實體或類別名稱,會自動置入該參數.#$arguments,陣列,為呼叫方法時所用的參數.#參考資料:#__call=>http://php.net/manual/en/language.oop5.overloading.php#object.callstatic*/public static function callStatic($method,$arguments){#取得當前執行的函式$result["function"]=__FUNCTION__;#設置執行不正常$result["status"]="false";#設置執行錯誤$result["error"][]="欲呼叫的". __NAMESPACE__ ."/".$method."() 不存在!";#設置所丟入的參數$result["error"][]=$arguments;#回傳結果return $result;}#function callStatic end/*#函數說明:#建立供qemu使用的socket檔案.#回傳結果:#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.#$result["error"],錯誤訊息.#$result["function"],當前執行的函數名稱.#$result["argu"],所使用的參數.#$result["content"],socket檔案的位置與名稱.#$result["createdFilePath"],socket檔案的路徑.#$result["createdFileName"],socket檔案名稱.#必填參數:#無#可省略參數:#$conf["sockFolder"],字串,socket檔案要儲存在哪邊,預設為"/tmp/qbpwcf/qemu".#$conf["sockFolder"]="/tmp/qbpwcf/qemu";#$conf["sockFile"],字串,socket檔案的名稱,預設為"亂數產生的5位英數字.sock",副檔名".sock"會自動補上.#$conf["sockFile"]="";#$conf["plusSockFileName"],字串,針對亂數產生的socket檔案名稱,是否要增加一些內容,譬如:"[__name]-spice-sock",就代表要在自動產生的[__name]名稱後面加上"-spice-sock"字串.#$conf["plusSockFileName"]="[__name]";#$conf["fileArgu"],字串,php變數__FILE__的內容,亦即該檔案在檔案系統的絕對路徑#$conf["fileArgu"]=__FILE__;#備註:#如果要在/tmp與/var/tmp底下建立socket檔案,若在apache環境下則會被作業系統特殊處理,即不等於實際上的路徑.*/function createSockFile(&$conf=array()){#初始化要回傳的結果$result=array();#取得當前執行的函數名稱$result["function"]=__FUNCTION__;#涵式說明:#判斷當前環境為web還是cmd#回傳結果:#$result,"web"或"cmd"if(csInformation::getEnv()==="web"){#設置執行失敗$result["status"]="false";#設置執行錯誤訊息$result["error"][]="函數 ".$result["function"]." 僅能在命令列環境下運行!";#回傳結果return $result;}#if end#取得參數$result["argu"]=$conf;#如果 $conf 不為陣列if(gettype($conf)!="array"){#設置執行失敗$result["status"]="false";#設置執行錯誤訊息$result["error"][]="\$conf變數須為陣列形態";#如果傳入的參數為 nullif($conf==null){#設置執行錯誤訊息$result["error"][]="\$conf變數不得為null,請檢查函數「".$result["function"]."」的參數設置有無正確!";}#if end#回傳結果return $result;}#if end#檢查參數#函式說明:#檢查一包含數個可省略變數的陣列變數,其型態是否正確,省略掉的陣列變數可以直接給定預設值。#回傳結果:#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.#$result["error"],錯誤訊息陣列.#$result["function"],當前執行的函式名稱.#$result["passed"],參數是否都通過檢查,"true",代表有通過檢查,"false"代表沒有通過檢查。#必填參數:#$conf["checkedVar"],陣列,要檢查的變數陣列名稱為?$conf["variableCheck::checkSkipableVarType"]["checkedVar"]=$conf;#$conf["sikpableVarNameArray"],字串陣列,要檢查型態是否設定正確的變數名稱陣列.$conf["variableCheck::checkSkipableVarType"]["sikpableVarNameArray"]=array("sockFolder","sockFile","plusSockFileName","fileArgu");#$argu,要直接存取的陣列變數名稱,變數前面加上「&」,如果要在別的函式裡面使用本函式,請記得將變動過結果($argu)給使用該函式的設定變數(通常是$conf=$argu).$argu=&$conf;#可省略參數:#$conf["skipableVarTypeArray"],字串陣列,要檢查的每個變數,其型態應該要為何,null代表不指定變數形態.$conf["variableCheck::checkSkipableVarType"]["skipableVarTypeArray"]=array("string","string","string","string");#$conf["skipableVarDefaultValue"],字串陣列,每個不存在的變數要初始化為什麼,null代表不指定.$conf["variableCheck::checkSkipableVarType"]["skipableVarDefaultValue"]=array("/tmp/qbpwcf/qemu",null,null,__FILE__);$checkSkipableVarType=variableCheck::checkSkipableVarType($conf["variableCheck::checkSkipableVarType"],$argu);unset($conf);#如果檢查參數失敗if($checkSkipableVarType["status"]==="false"){#設置執行失敗$result["status"]="false";#設置執行錯誤訊息$result["error"]=$checkSkipableVarType;#回傳結果return $result;}#if end#如果檢查參數不通過if($checkSkipableVarType["passed"]==="false"){#設置執行失敗$result["status"]="false";#設置執行錯誤訊息$result["error"]=$checkSkipableVarType;#回傳結果return $result;}#if end#取得更新後的參數$conf=$argu;#如果 socket 檔案不存在if(!isset($conf["sockFile"])){#產生亂數#涵式說明:#建立以圖片(PNG格式)呈現的驗證碼.#回傳的解果:#$result["status"],執行是否正常,"true"代表執行成功,"false"代表執行失敗.#$result["error"],錯誤訊息.#$result["function"],檔前執行的函數名稱.#$result["randNumberWord"],傳驗證碼的內容.#$result["imgAddress"],圖片的位置與名稱.#必填的參數:#$conf["imgAddressAndName"],字串,爲驗證碼圖片儲存的位置與名稱,副檔名程式會自動產生$conf["authenticate::validationCode"]["imgAddressAndName"]="no used";#$conf["fileArgu"],字串,php變數__FILE__的內容,亦即該檔案在檔案系統的絕對路徑$conf["authenticate::validationCode"]["fileArgu"]="no used";#可省略的參數:#$conf["num"],字串,爲驗證碼的位數,請輸入阿拉伯數字,預設為"8"位數.#$conf["num"]="8";#$conf["disableImg"],字串,是否要取消驗證碼圖片的輸出,"true"為要取消,預設為"false"為不取消$conf["authenticate::validationCode"]["disableImg"]="true";#$conf["imgToData"],字串,預設為"true"代表將圖片轉存成base64圖片,並將原始圖片移除;反之為"false"#$conf["imgToData"]="true";$validationCode=authenticate::validationCode($conf["authenticate::validationCode"]);unset($conf["authenticate::validationCode"]);#產生亂數驗證碼失敗if($validationCode["status"]==="false"){#設置執行失敗$result["status"]="false";#設置執行錯誤訊息$result["error"]=$validationCode;#回傳結果return $result;}#if end#取得 socket 檔案名稱$conf["sockFile"]=$validationCode["randNumberWord"];}#if end#如果有設置 $conf["plusSockFileName"]if(isset($conf["plusSockFileName"])){#如果含有 $conf["plusSockFileName"]#函式說明:#檢查字串裡面有無指定的關鍵字#回傳的結果:#$result["status"],"true"代表執行成功,"false"代表執行失敗。#$result["error"],錯誤訊息#$result["function"],當前執行的函數名稱.#$result["founded"],是否找到關鍵字,"true"代表有找到關鍵字;"false"代表沒有找到關鍵字。#$result["keyWordCount"],找到的關鍵字數量.#必填的參數:$conf["search::findKeyWord"]["keyWord"]="[__name]";#想要搜尋的關鍵字$conf["search::findKeyWord"]["string"]=$conf["plusSockFileName"];#要被搜尋的字串內容#可省略的參數:#$conf["completeEqual"]="true";#是否內容要完全符合,不能多出任何不符合的內容,預設為不需要完全符合。$findKeyWord=search::findKeyWord($conf["search::findKeyWord"]);unset($conf["search::findKeyWord"]);#如果分割字串失敗if($findKeyWord["status"]==="false"){#設置執行失敗$result["status"]="false";#設置執行錯誤訊息$result["error"]=$findKeyWord;#回傳結果return $result;}#if end#如果沒有關鍵字 [__name]if($findKeyWord["founded"]==="false"){#設置執行失敗$result["status"]="false";#設置執行錯誤訊息$result["error"]=$findKeyWord;#回傳結果return $result;}#if end#產生新的socket檔案名稱#涵式說明:#處理多個字串避免網頁出錯#回傳的結果:#$result["status"],"true"代表執行成功,"false"代表執行失敗。#$result["function"],當前執行的函數.#$result["error"],錯誤訊息#$result["processedStrArray"],處理好的字串陣列#必填的參數:$conf["stringProcess::correctMutiStrCharacter"]["stringIn"]=array($conf["plusSockFileName"]);#爲要處理的字串陣列#可省略的參數:$conf["stringProcess::correctMutiStrCharacter"]["selectedCharacter"]=array("[__name]");#爲被選擇要處理的字串/字元,須爲陣列值。#若不設定則預設爲要將這些字串作替換 ("<",">","=","//","'","$","%","&","|","/*","*","#","\"").#特殊字元,「\n」代表換行,「\t」代表tab鍵的間隔$conf["stringProcess::correctMutiStrCharacter"]["changeTo"]=array($conf["sockFile"]);#爲被選擇的字元要換成什麼字串/字元,須爲陣列值。若不設定,則預設爲更換成""(空字串).$correctMutiStrCharacter=stringProcess::correctMutiStrCharacter($conf["stringProcess::correctMutiStrCharacter"]);unset($conf["stringProcess::correctMutiStrCharacter"]);#如果分割字串失敗if($correctMutiStrCharacter["status"]==="false"){#設置執行失敗$result["status"]="false";#設置執行錯誤訊息$result["error"]=$correctMutiStrCharacter;#回傳結果return $result;}#if end#取得產生好的新socket檔案名稱$conf["sockFile"]=$correctMutiStrCharacter["processedStrArray"][0];}#if end#建立socket檔案#函式說明:#檢查要建立的檔案路徑是否存在,若不存在則建立新檔案,若檔案已存在則會在原檔名後面加上從(1)開始的編號,再度嘗試建立檔案,以避免資料異常.#回傳的結果:#$result["status"],執行狀態,"true"代表執行正常,"false"代表執行失敗.#$result["error"],錯誤訊息陣列.#$result["function"],當前執行的函數名稱.#$result["argu"],使用的參數.#$result["createdFileName"],建立好的檔案名稱.#$result["createdFilePath"],檔案建立的路徑.#$result["createdFilePathAndName"].建立好的檔案名稱與路徑.#必填的參數:#$conf["checkedFileAndPath"],字串陣列,要建立的檔案路徑$conf["fileAccess::createFileAfterCheck"]["checkedFileAndPath"]=$conf["sockFolder"]."/".$conf["sockFile"].".sock";#$conf["fileArgu"],字串,php變數__FILE__的內容,亦即該檔案在檔案系統的絕對路徑$conf["fileAccess::createFileAfterCheck"]["fileArgu"]=$conf["fileArgu"];#可省略參數:#$conf["filenameExtensionStartPoint"],字串,檔案的副檔名是從倒數第幾個小數點(dot)開始,預設為"1",最後一個小數點.#$conf["filenameExtensionStartPoint"]="";#$conf["repeatNameRule"],字串,遇到相同名稱的檔案要如何加上識別的編號,編號用「\$i」表示,預設為"(\$i)".#$conf["repeatNameRule"]="";$createFileAfterCheck=fileAccess::createFileAfterCheck($conf["fileAccess::createFileAfterCheck"]);unset($conf["fileAccess::createFileAfterCheck"]);#建立socket檔案失敗if($createFileAfterCheck["status"]==="false"){#設置執行失敗$result["status"]="false";#設置執行錯誤訊息$result["error"]=$createFileAfterCheck;#回傳結果return $result;}#if end#實際建立的檔案名稱$result["createdFileName"]=$createFileAfterCheck["createdFileName"];#取得建立好的socket路徑所在$result["createdFilePath"]=$createFileAfterCheck["createdFilePath"];#取得易讀的路徑#函式說明:#將檔案目錄的絕對位置中的 "../" 剔除變成直觀的路徑.#回傳的結果:#$result["status"],執行是否成功,"true"代表執行成功,"false"代表執行失敗.#$result["function"],當前執行的函數.#$result["error"],錯誤訊息陣列.#$result["changedPath"],處理完後回傳的目錄字串.#$result["oriPath"],原始的路徑字串#必填的參數:#$conf["dirStr"],字串,要處理的檔案目錄字串.$conf["stringProcess::changeDirByDotDotSolidus"]["dirStr"]=$result["createdFilePath"];$changeDirByDotDotSolidus=stringProcess::changeDirByDotDotSolidus($conf["stringProcess::changeDirByDotDotSolidus"]);unset($conf["stringProcess::changeDirByDotDotSolidus"]);#如果處理路徑失敗if($changeDirByDotDotSolidus["status"]==="false"){#設置執行失敗$result["status"]="false";#設置執行錯誤訊息$result["error"]=$changeDirByDotDotSolidus;#回傳結果return $result;}#if end#取得建立好的socket路徑$result["createdFilePath"]=$createFileAfterCheck["createdFileName"];#取得建立好的socket路徑與檔案名稱$result["content"]=$createFileAfterCheck["createdFilePathAndName"];#取得易讀的路徑#函式說明:#將檔案目錄的絕對位置中的 "../" 剔除變成直觀的路徑.#回傳的結果:#$result["status"],執行是否成功,"true"代表執行成功,"false"代表執行失敗.#$result["function"],當前執行的函數.#$result["error"],錯誤訊息陣列.#$result["changedPath"],處理完後回傳的目錄字串.#$result["oriPath"],原始的路徑字串#必填的參數:#$conf["dirStr"],字串,要處理的檔案目錄字串.$conf["stringProcess::changeDirByDotDotSolidus"]["dirStr"]=$result["content"];$changeDirByDotDotSolidus=stringProcess::changeDirByDotDotSolidus($conf["stringProcess::changeDirByDotDotSolidus"]);unset($conf["stringProcess::changeDirByDotDotSolidus"]);#如果處理路徑失敗if($changeDirByDotDotSolidus["status"]==="false"){#設置執行失敗$result["status"]="false";#設置執行錯誤訊息$result["error"]=$changeDirByDotDotSolidus;#回傳結果return $result;}#if end#處理好的路徑檔案字串$result["content"]=$changeDirByDotDotSolidus["changedPath"];#設置執行正常$result["status"]="true";#回傳結果return $result;}#function createSockFile end/*#函式說明:#在背景建立qemu虛擬機器#回傳結果:#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.#$result["error"],錯誤訊息.#$result["function"],當前執行的函數名稱.#$result["argu"],所使用的參數.#$result["cmd"],執行的command#必填的參數:#$conf["fileArgu"],字串,php變數__FILE__的內容,亦即該檔案在檔案系統的絕對路徑$conf["fileArgu"]=__FILE__;#可省的參數:#$conf["architecture"],字串,所使用的處理器架構,可用的有"i386","x86_64"預設為"x86_64".#$conf["architecture"]="x86_64";#$conf["configFile"],字串,使用讀設定檔的方式來執行qemu,此為設定檔的路徑.#$conf["configFile"]="";#$conf["storage"],字串陣列,$conf["storage"][$i]代表第$i+1個虛擬硬碟位置與名稱.#$conf["storage"]=array();#$conf["storageType"],字串陣列,$conf["storageType"][$i]代表第$i+1個虛擬硬碟的類型,可以為ide,sata,scsi,virtio,sd或/dev/開頭的裝置.#$conf["storageType"]=array();#$conf["memory"],字串,可以使用的記憶體大小,以G為單位,預設為"2",亦即2GB的記憶體.#$conf["memory"]="2";#$conf["vga"],字串,顯示卡類型,可用的有"cirrus","std","vmware","qxl","virtio"預設為"qxl".#$conf["vga"]="qxl";#$conf["soundhw"],字串,音效卡類型,可用的有"ac97","hda","all"預設為"all".#$conf["soundhw"]="";#$conf["kvm"],字串,是否使用kvm來加速虛擬機速度,"true"為啟用,"false"為不用kvm加速,預設為"true".#$conf["kvm"]="true";#$conf["machine"],字串,要用什麼樣的主機板,預設為"q35"(Q35 + ICH9, 2009),可用的還有傳統的"pc"(i440FX+PIIX,1996),知名的xen全虛擬化"xenfv",或半虛擬化"xenpv".#$conf["machine"]="";#$conf["spiceSock"],字串,是否要透過sock檔案的提供spice服務,此方法必須client端與server端都在同一台機器上,才能透spice協定進行連線,留空代表不使用,副檔名".sock"會自動補上.#$conf["spiceSock"]="";#$conf["spicePort"],字串,要使用spice服務來遠端遙控的port,例如"5901",請與參數$conf["spiceSock"]擇一使用.#$conf["spicePort"]="5901";#$conf["spicePassword"],字串,要使用spice服務來遠端遙控時所需的密碼,預設為不設定.#$conf["spicePassword"]="";#$conf["gl"],字串,是否要啟用opengl支援,可以讓spice可以擁有3D加速的功能,"true"為要使用,預設為"false"不啟用.#$conf["gl"]="";#$conf["userNet"][$i]["cardType"],字串,使用的網卡是什麼型號,預設為"virtio-net",可選的有e1000,e1000-82545em,ne2k_pci,rtl8139等...#$conf["userNet"][$i]["cardType"]="";#$conf["userNet"][$i]["mac"],字串,第$i+1個user網路類型的網卡mac.#$conf["userNet"][$i]["mac"]="";#$conf["userNet"][$i]["hostfwd"],二維字串陣列,第$i+1個user網路類型,指定到host::port的封包要轉到guest::port,例如array(array("8080","80"),array("8088","443")),就代表從8080port要進入host的封包會轉送到gust的80port,從8088port要進入host的封包會轉送到gust的443port.#$conf["userNet"][$i]["hostfwd"]=array()#$conf["bridgeNet"][$i]["cardType"],字串,使用的網卡是什麼型號,預設為"virtio",可選的有e1000,e1000-82545em,ne2k_pci,rtl8139等...#$conf["bridgeNet"][$i]["mac"],字串,第$i+1個bridge網路類型的網卡mac.#$conf["bridgeNet"][$i]["mac"]="";#$conf["bridgeNet"][$i]["brName"],字串,第$i+1個bridge網路類型要接到哪個bridge.#$conf["bridgeNet"][$i]["brName"]="";#$conf["socketNet"][$i]["cardType"],字串,使用的網卡是什麼型號,預設為"virtio",可選的有e1000,e1000-82545em,ne2k_pci,rtl8139等...#$conf["socketNet"][$i]["mac"],字串,第$i+1個socket網路類型的網卡mac.#$conf["socketNet"][$i]["mac"]="";#$conf["socketNet"][$i]["addr"],字串,第$i+1個socket網路類型的ip與port,預設為"230.0.0.1:1234".#$conf["socketNet"][$i]["addr"]="";#$conf["monitorLP"],字串,monitor要listen哪個port,預設為10000開始的port.#$conf["monitorLP"]="";#備註:#伺服器須有安裝qemu套件.#建議:#新增nec-usb-xhci的支援.*/function run(&$conf){#初始化要回傳的結果$result=array();#取得當前執行的函數名稱$result["function"]=__FUNCTION__;#如果沒有參數if(func_num_args()==0){#設置執行失敗$result["status"]="false";#設置執行錯誤訊息$result["error"]="函數".$result["function"]."需要參數";#回傳結果return $result;}#if end#涵式說明:#判斷當前環境為web還是cmd#回傳結果:#$result,"web"或"cmd"if(csInformation::getEnv()==="web"){#設置執行失敗$result["status"]="false";#設置執行錯誤訊息$result["error"][]="函數 ".$result["function"]." 僅能在命令列環境下運行!";#回傳結果return $result;}#if end#取得參數$result["argu"]=$conf;#如果 $conf 不為陣列if(gettype($conf)!=="array"){#設置執行失敗$result["status"]="false";#設置執行錯誤訊息$result["error"][]="\$conf變數須為陣列形態";#如果傳入的參數為 nullif($conf===null){#設置執行錯誤訊息$result["error"][]="\$conf變數不得為null,請檢查函數「".$result["function"]."」的參數設置有無正確!";}#if end#回傳結果return $result;}#if end#檢查參數#函式說明:#檢查必填與可省略的參數,可省略參數可指定預設要給與什麼數值內容。#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.#$reuslt["error"],執行不正常結束的錯訊息陣列.#$result["function"],當前執行的函式名稱.#$result["passed"],識別要檢查的全體變數是否存在以及型態是否正確的變數,"true"代表檢查全部通過;"false"代表檢查不通過#$result[$shouldBeCheckedVarName]["varExist"],所檢查的變數是否存在,"false"代表不存在;"true"代表存在#$result[$shouldBeCheckedVarName]["varType"],所檢查的變數型態是否正確,"false"代表錯誤;"true"代表正確#$result[$shouldBeCheckedVarName]["error"],每個參數設定的錯誤訊息#$result["shouldNotBeEmpty"],不應該為空字串或控陣列的變數.#$result["argu"],字串陣列,目前輸入的參數名稱陣列.#$result["legalVarName"],字串陣列,合法可用的參數名稱陣列.#$result["notNeedVar"],字串陣列,多餘的參數名稱.#必填寫的參數:#$conf["varInput"],陣列變數,要檢查的陣列變數,請在要檢查的參數前面加上&,這樣變動的結果才能被套用。$conf["variableCheck::checkArguments"]["varInput"]=&$conf;#$conf["mustBeFilledVariableName"],爲必填參數的變數名稱陣列,形態爲陣列變數,元素數量需要跟"mustBeFilledVariableType"參數的元素數量一致,例如: $conf["mustBeFilledVariableName"] = array("id","account","password");$conf["variableCheck::checkArguments"]["mustBeFilledVariableName"]=array("fileArgu");#$conf["mustBeFilledVariableType"],爲必填參數的變數陣列應該爲何種變數形態,形態爲陣列,元素數量需要跟"mustBeFilledVariableName"參數的元素數量一致,例如: $conf["mustBeFilledVariableType"] = array("string",integer,"double","resource","object"); , null代表不指定變數形態.$conf["variableCheck::checkArguments"]["mustBeFilledVariableType"]=array("string");#$conf["referenceVarKey"],字串,$conf參數後面的key值,用於移除不要的參考陣列.$conf["variableCheck::checkArguments"]["referenceVarKey"]="variableCheck::checkArguments";#可以省略的參數:#$conf["canBeEmptyString"],字串,必填變數內容如果是空字串就不能算是有設置的話,請設為"false",預設爲"true",可以為空字串.$conf["variableCheck::checkArguments"]["canBeEmptyString"]="false";#$conf["canNotBeEmpty"],字串陣列,哪些必填參數的內容不得為空字串或空陣列,僅當$conf["canBeEmptyString"]為"true"時會生效.#$conf["canNotBeEmpty"]=array();#$conf["canBeEmpty"],字串陣列,哪些必填參數的內容可為空字串或空陣列,僅當$conf["canBeEmptyString"]為"false"時會生效.#$conf["canBeEmpty"]=array();#$conf["skipableVariableCanNotBeEmpty"],字串陣列,哪些可省略參數不可以為空字串或空陣列.#$conf["skipableVariableCanNotBeEmpty"]=array();#$conf["skipableVariableName"],陣列字串,爲可省略參數的變數名稱陣列,形態爲陣列變數,例如: $conf["skipableVariableName"] = array("id","account","password");$conf["variableCheck::checkArguments"]["skipableVariableName"]=array("architecture","configFile","storage","storageType","memory","vga","soundhw","kvm","machine","spiceSock","spicePort","spicePassword","userNet","bridgeNet","socketNet","monitorLP","monitorSock","gl");#$conf["skipableVariableType"],陣列字串,爲可省略參數的變數名稱陣列,形態爲陣列變數,例如: $conf["skipableVariableType"] = array("string",integer,"double");$conf["variableCheck::checkArguments"]["skipableVariableType"]=array("string","string","string","string","string","string","string","string","string","string","string","string","array","array","array","string","string","string");#$conf["skipableVarDefaultValue"],字串陣列,每個不存在的可省略變數要初始化為什麼,null與代表不指定,若預設值是參數之一,請將$conf["mustBeFilledVar"]改成"\$conf["\mustBeFilledVar\"]".$conf["variableCheck::checkArguments"]["skipableVarDefaultValue"]=array("x86_64",null,null,null,"2","qxl","all","true","q35",null,null,null,null,null,null,null,null,"false");#$conf["arrayCountEqualCheck"],字串陣列,為檢查哪些陣列參數的元素數量要一樣,$conf["arrayCountEqualCheck"][$i]=array()為第$i組key為哪些的變數其元素數量要相等.$conf["variableCheck::checkArguments"]["arrayCountEqualCheck"][]=array("storage","storageType");#參考資料來源:#array_keys=>http://php.net/manual/en/function.array-keys.php$checkArguments=variableCheck::checkArguments($conf["variableCheck::checkArguments"]);unset($conf["variableCheck::checkArguments"]);#如果參數檢查失敗if($checkArguments["status"]==="false"){#設置執行不正常$result["status"]="false";#設置執行錯誤$result["error"]=$checkArguments;#回傳結果return $result;}#if end#如果參數檢查不通過if($checkArguments["passed"]==="false"){#設置執行不正常$result["status"]="false";#設置執行錯誤$result["error"]=$checkArguments;#回傳結果return $result;}#if end#檢查qemu的指令是否存在#函式說明:#檢查指令是否存在#回傳結果:#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.#$result["error"],錯誤訊息.#$result["function"],當前執行的函數名稱.#$result["argu"],使用的參數.#$result["content"],新增好後的檔案內容.#必填參數:#$conf["cmd"],"字串",要查詢的指令.$conf["cmd::checkCmdExist"]["cmd"]="qemu-system-".$conf["architecture"];#$conf["fileArgu"],字串,變數__FILE__的內容.$conf["cmd::checkCmdExist"]["fileArgu"]=$conf["fileArgu"];#可省略參數:#$conf["binPath"],字串,要搜尋的路徑,預設為"/usr/bin".#$conf["binPath"]="";$checkCmdExist=cmd::checkCmdExist($conf["cmd::checkCmdExist"]);unset($conf["cmd::checkCmdExist"]);#如果檢查指令失敗if($checkCmdExist["status"]==="false"){#設置執行不正常$result["status"]="false";#設置執行錯誤$result["error"]=$checkCmdExist;#回傳結果return $result;}#if end#如果指令不存在if($checkCmdExist["founded"]==="false"){#設置執行不正常$result["status"]="false";#設置執行錯誤$result["error"]=$checkCmdExist;#回傳結果return $result;}#if end#初始化要執行的command$qemuBin="qemu-system-".$conf["architecture"];#設定 $conf["memory"] 參數$conf["memory"]=$conf["memory"]."G";#串接memory設定$paramsArray[]="-m";$paramsArray[]=$conf["memory"];#設定 $conf["vga"] 參數$conf["vga"]=" -vga ".$conf["vga"];#串接 vag 設定$paramsArray[]=$conf["vga"];#設定 $conf["soundhw"] 參數$conf["soundhw"]=" -soundhw ".$conf["soundhw"];#串接 soundhw 設定$paramsArray[]=$conf["soundhw"];#設定 usb 支援$paramsArray[]="-usb";#檢查主機有無支援 vmx 或 svm#初始化判別是否支援kvm的識別$kvmSupported="false";#設置支援的關鍵字串$kvmSuppurtKeyWord=array("vmx","svm");#有幾個支援的關鍵字串就執行幾次foreach($kvmSuppurtKeyWord as $kvmWord){#函數說明:#檢查指令的輸出是否含有關鍵字#回傳結果:#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.#$result["error"],錯誤訊息.#$result["function"],當前執行的函數名稱.#$result["argu"],使用的參數.#$result["founded"],是否找到關鍵字,"true"代表有,"false"代表沒有.#$result["content"],關鍵字所在列的輸出.#必填參數:#$conf["cmd"],字串,要執行的指令.$conf["cmd::searchOutPut"]["cmd"]="lscpu";#$conf["keyWord"],字串,要檢查是否有關鍵字.$conf["cmd::searchOutPut"]["keyWord"]=$kvmWord;#$conf["fileArgu"],字串,php變數__FILE__的內容,亦即該檔案在檔案系統的絕對路徑$conf["cmd::searchOutPut"]["fileArgu"]=$conf["fileArgu"];#可省略參數:#$conf["binPath"],字串,要搜尋的路徑,預設為"/usr/bin".#$conf["binPath"]="";$searchOutPut=cmd::searchOutPut($conf["cmd::searchOutPut"]);unset($conf["cmd::searchOutPut"]);#如果搜尋指令輸出是否有關鍵字失敗if($searchOutPut["status"]==="false"){#設置執行不正常$result["status"]="false";#設置執行錯誤$result["error"]=$searchOutPut;#回傳結果return $result;}#if end#如果有找到關鍵字if($searchOutPut["founded"]==="true"){#設置支援 kvm$kvmSupported="true";#跳出 foreachbreak;}#if end}#foreach end#如果不支援kvm又指定要用kvmif($kvmSupported==="false" && $conf["kvm"]==="true"){#設置不使用 kvm$conf["kvm"]="false";#設置警告訊息$conf["warning"][]="因為主機不支援kvm,因此取消 -enable-kvm 參數";}#if#如果指定要用kvmif($conf["kvm"]==="true"){#設置 kvm 參數$conf["kvm"]=" -enable-kvm";}#if end#反之else{#不啟用enable-kvm$conf["kvm"]="";}#else end#串接 kvm 設定$paramsArray[]=$conf["kvm"];#設置 machine 類型$conf["machine"]=" -machine ".$conf["machine"];#串接 machine 設定$paramsArray[]=$conf["machine"];#初始化 spice 設定字串,與壓縮的選項$spice=" -spice image-compression=auto_glz";#如果有設置 $conf["spiceSock"] 或 $conf["spicePort"]if(isset($conf["spiceSock"]) || isset($conf["spicePort"])){#如果有設置 $conf["spiceSock"]if(isset($conf["spiceSock"])){#確保socket檔案可以存在#涵式說明:#確保路徑存在.#回傳的結果:#$result["status"],執行正常與否,"true"代表正常,"false"代表不正常.#$result["error"],錯誤訊息陣列.#$resutl["function"],當前執行的涵式名稱.#$result["path"],建立好的路徑字串.#$result["fileName"],檔案名稱,若 $conf["haveFileName"] 為 "true" 則會回傳.#必填的參數:#$conf["path"],要檢查的路徑$conf["fileAccess::validatePath"]["path"]=$conf["spiceSock"];#$conf["fileArgu"],字串,php變數__FILE__的內容,亦即該檔案在檔案系統的絕對路徑$conf["fileAccess::validatePath"]["fileArgu"]=$conf["fileArgu"];#可省略參數:#$conf["haveFileName"],字串,"true"代表有$conf["path"]檔案名稱,"false"代表$conf["path"]為純路徑,預設為"false".$conf["fileAccess::validatePath"]["haveFileName"]="true";#$conf["dirPermission"],字串,新建資料夾的權限設定,預設爲0770,亦即擁有者,同群組者可以讀,寫,存取,其他人僅能存取.#$conf["dirPermission"]="";$validatePath=fileAccess::validatePath($conf["fileAccess::validatePath"]);unset($conf["fileAccess::validatePath"]);#如果確保路徑失敗if($validatePath["status"]==="false"){#設置執行不正常$result["status"]="false";#設置執行錯誤$result["error"]=$validatePath;#回傳結果return $result;}#if end#取得socket檔案的路徑$conf["spiceSock"]=",unix,addr=".$conf["spiceSock"];#設置 socket 類型的 spice$spice=$spice.$conf["spiceSock"];}#if end#反之有設置 $conf["spicePort"]else if(isset($conf["spicePort"])){#設置spice的port$conf["spicePort"]=",port=".$conf["spicePort"];#設置 tcp/ip 類型的 spice$spice=$spice.$conf["spicePort"];}#if end#如果有設置 $conf["spicePassword"]if(isset($conf["spicePassword"])){#設置spice連線的密碼$conf["spicePassword"]=",password=".$conf["spicePassword"];#串接使用的密碼$spice=$spice.$conf["spicePassword"];}#if ned#反之不用密碼else{#設置spice連線不需要密碼$conf["spicePassword"]=",disable-ticketing";#串接不要使用密碼$spice=$spice.$conf["spicePassword"];}#else end#如果 $conf["gl"] 等於 "true"if($conf["gl"]==="true"){#設置gl$spice=$spice.",gl=on";}#if end#串接spice設置$paramsArray[]=$spice;}#if end#如果有設置硬碟if(isset($conf["storage"])){#依據每個硬碟foreach($conf["storage"] as $index=>$storage){#檢查檔案是否存在#涵式說明:檢查多個檔案與資料夾是否存在.#回傳的結果:#$result["status"],執行正常與否,"true"代表正常,"false"代表不正常.#$result["error"],錯誤訊息陣列.#$resutl["function"],當前執行的涵式名稱.#$result["allExist"],所有檔案皆存在的識別,"true"代表皆存在,"false"代表沒有全部都存在.#$result["varName"][$i],爲第$i個資料夾或檔案的路徑與名稱。#$result["varNameFullPath"][$i],爲第$i個資料夾或檔案的完整檔案系統路徑與名稱。#$result["varNameWebPath"][$i],為第$i個資料夾或檔案的網址#$result["varExist"][$i],爲第$i個資料夾或檔案是否存在,"true"代表存在,"false"代表不存在。#必填參數:#$conf["fileArray"],陣列字串,要檢查是否存在的檔案有哪些,須爲一維陣列數值。$conf["fileAccess::checkMultiFileExist"]["fileArray"]=array($storage);#$conf["fileArgu"],字串,php變數__FILE__的內容,亦即該檔案在檔案系統的絕對路徑$conf["fileAccess::checkMultiFileExist"]["fileArgu"]=$conf["fileArgu"];#可省略參數#$conf["disableWebSearch"],"字串",是否取消「當檔案找不到時,改用catchWebContent類別的wget函數來檢查檔案是否存在於網路上」的功能,"false"不取消,若要取消該功能請設為"true",若抓到的內容為空字串則會視為檔案不存在,預設為"true".#$conf["disableWebSearch"]="false";#$conf["userDir"],字串,網頁是否置放於家目錄底下,"true"為是,"false"為不是,預設為"true".#$conf["userDir"]="true";#參考資料來源:#http://php.net/manual/en/function.file-exists.php#http://php.net/manual/en/control-structures.foreach.php#備註:#函數file_exists檢查的路徑為檔案系統的路徑$checkMultiFileExist=fileAccess::checkMultiFileExist($conf["fileAccess::checkMultiFileExist"]);unset($conf["fileAccess::checkMultiFileExist"]);#如果檢查硬碟檔案是否存在失敗if($checkMultiFileExist["status"]==="false"){#設置執行不正常$result["status"]="false";#設置執行錯誤$result["error"]=$checkMultiFileExist;#回傳結果return $result;}#if end#如果硬碟檔案不存在if($checkMultiFileExist["allExist"]==="false"){#設置執行不正常$result["status"]="false";#設置執行錯誤$result["error"]=$checkMultiFileExist;#回傳結果return $result;}#if end#解析硬碟檔案資訊#涵是說明:#取得檔案路徑字串的路徑與檔案的名稱與檔案副檔名#回傳的結果:#$result["status"],執行是否正常,"true"正常,"false"代表不正常.#$result["error"],錯誤訊息.#$result["function"],當前執行的函式名稱.#$result["filePath"],路徑字串.#$result["fileName"],檔案名稱字串.#$result["fileExtention"],檔案的副檔名.#$result["fullFileName"],含副檔名的檔案名稱.#$result["fullFilePathAndName"],完整的檔案路徑(含副檔名).#必填的參數:#$conf["fileAddressAndName"],字串,檔案名稱與其路徑.$conf["fileAccess::getFileAddressAndNameAndFileExtention"]["fileAddressAndName"]=$checkMultiFileExist["varNameFullPath"][0];#可省略的參數:#無.#備註:#php內建的fileinfo方法無法正確解析中文路徑檔案名稱.$getFileAddressAndNameAndFileExtention=fileAccess::getFileAddressAndNameAndFileExtention($conf["fileAccess::getFileAddressAndNameAndFileExtention"]);unset($conf["fileAccess::getFileAddressAndNameAndFileExtention"]);#如果取得檔案資訊失敗if($getFileAddressAndNameAndFileExtention["status"]==="false"){#設置執行不正常$result["status"]="false";#設置執行錯誤$result["error"]=$checkMultiFileExist;#回傳結果return $result;}#if end#取得副檔名$diskExtention=&$getFileAddressAndNameAndFileExtention["fileExtention"];#依據副檔名switch($diskExtention){#如果是 "qcow2,raw,img,vdi,vmdk之一"case "qcow2":case "raw":case "img":case "vdi":case "vmdk":#跳出switchbreak;#其他副檔名default:#檢查是否有關鍵字 "/dev/"#函式說明:#檢查字串裡面有無指定的關鍵字#回傳的結果:#$result["status"],"true"代表執行成功,"false"代表執行失敗。#$result["error"],錯誤訊息#$result["function"],當前執行的函數名稱.#$result["founded"],是否找到關鍵字,"true"代表有找到關鍵字;"false"代表沒有找到關鍵字。#$result["keyWordCount"],找到的關鍵字數量.#必填的參數:$conf["search::findKeyWord"]["keyWord"]="/dev/";#想要搜尋的關鍵字$conf["search::findKeyWord"]["string"]=$diskExtention;#要被搜尋的字串內容#可省略的參數:#$conf["completeEqual"]="true";#是否內容要完全符合,不能多出任何不符合的內容,預設為不需要完全符合。$findKeyWord=search::findKeyWord($conf["search::findKeyWord"]);unset($conf["search::findKeyWord"]);#如果尋找關鍵字失敗if($findKeyWord["status"]==="false"){#設置執行不正常$result["status"]="false";#設置執行錯誤$result["error"]=$findKeyWord;#回傳結果return $result;}#if end#如果沒有關鍵字if($findKeyWord["founded"]==="false"){#設置執行不正常$result["status"]="false";#設置執行錯誤的訊息$result["error"][]="虛擬硬碟的副檔名必須是qcow2,raw,img,vdi,vmdk或\"/dev/\"開頭的裝置之一";#回傳結果return $result;}#if end#跳出 switchbreak;}#switch end#另存儲存裝置的接口類型$storageType=&$conf["storageType"][$index];#依據儲存裝置的接口類型switch($storageType){#如果是 virtiocase "virtio":#建立virtio接口的儲存裝置片段$paramsArray[]="-drive";$paramsArray[]="file=".$storage.",if=".$storageType.",l2-cache-size=13M,cache-clean-interval=900,cache=directsync,aio=native";#如果是 satacase "sata":#建立sata接口的儲存裝置片段$paramsArray[]="-device";$paramsArray[]="ahci,id=ahci".$index;$paramsArray[]="-drive";$paramsArray[]="if=none,file=".$storage.",format=".$storageType.",id=drive-ide-".$index." -device ide-drive,bus=ahci".$index.".0,drive=drive-ide-".$index;#如果是 idecase "ide":#建立ide接口的儲存裝置片段$paramsArray[]="-drive";$paramsArray[]="file=".$storage.",if=".$storageType;#如果是 scsicase "scsi":#建立scsi接口的儲存裝置片段$paramsArray[]="-drive";$paramsArray[]="file=".$storage.",if=".$storageType;#如果是 sdcase "sd":#建立 sd 卡裝置的語法$paramsArray[]="-device";$paramsArray[]="usb-ehci,id=ehci".$index;$paramsArray[]="-drive";$paramsArray[]="if=sd,file=".$storage.",format=".$storageType.",id=sd".$index;$paramsArray[]="-device";$paramsArray[]="usb-storage,bus=ehci0.".$index.",drive=sd".$index;#如果是 usbcase "usb":#初始化虛擬儲存裝置的檔案類型參數$storageTypeParam="";#如果是qcow2格式if($storageType==="qcow2"){#設置對應的優化參數$storageTypeParam=",l2-cache-size=13M,cache-clean-interval=900,cache=directsync,aio=native";}#建立 usb-storage 裝置的語法$paramsArray[]="-drive";$paramsArray[]="=file='".$storage."',format=".$storageType.$storageTypeParam.",if=none,id=usbStorage-".$index;$paramsArray[]="-device usb-storage,drive=usbStorage-".$index;#其他類型default:#設置執行不正常$result["status"]="false";#設置執行錯誤的訊息$result["error"][]="虛擬硬碟的接口必須是virtio,sata,ide,scsi,sd之一";#回傳結果return $result;}#switch end}#foreach end}#if end#如果有設定$conf["userNet"]if(isset($conf["userNet"])){#有幾個 $conf["userNet"] 就執行幾次foreach($conf["userNet"] as $userNet){#初始化暫存設定網路的參數$settingStr="";#如果未設定 $conf["userNet"][$i]["cardType"]if(!isset($conf["userNet"][$i]["cardType"])){#預設為 "virtio-net"$conf["userNet"][$i]["cardType"]="virtio-net";}#if end#如果沒有指定macif(!isset($conf["userNet"][$i]["mac"])){#設置執行不正常$result["status"]="false";#設置執行錯誤的訊息$result["error"][]="網卡的mac需要指定";#回傳結果return $result;}#if end#設置網路類型$paramsArray[]="-netdev";$paramsArray[]="user,id=userNet".$i;#如果有設定 $conf["userNet"][$i]["hostfwd"]if(isset($conf["userNet"][$i]["hostfwd"])){#初始化 hostfwd 的設定$hostfwdStr="";#有幾個 $conf["userNet"][$i]["hostfwd"] 就執行幾次foreach($conf["userNet"][$i]["hostfwd"] as $hostfwd){#如果 $hostfwd 不為兩個元素if(count($hostfwd)!==2){#設置執行不正常$result["status"]="false";#設置執行錯誤的訊息$result["error"][]="參數hostfwd須為二維陣列";#回傳結果return $result;}#if end#設定轉port$hostfwdStr=$hostfwdStr.",hostfwd=tcp::".$hostfwd[0]."-:".$hostfwd[1];}#foreach end}#if end#設置網卡類型與mac$paramsArray[]="device";$paramsArray[]=$conf["userNet"][$i]["cardType"].",mac=".$conf["userNet"][$i]["mac"].",netdev=userNet".$i.$hostfwdStr;}#foreache end}#if end#如果有設置 $conf["bridgeNet"]if(isset($conf["bridgeNet"])){#有幾個 $conf["bridgeNet"] 就執行幾次foreach($conf["bridgeNet"] as $bridgeNet){#如果未設定 $conf["bridgeNet"][$i]["cardType"]if(!isset($conf["bridgeNet"][$i]["cardType"])){#預設為 "virtio-net"$conf["bridgeNet"][$i]["cardType"]="virtio-net";}#if end#如果沒有指定macif(!isset($conf["bridgeNet"][$i]["mac"])){#設置執行不正常$result["status"]="false";#設置執行錯誤的訊息$result["error"][]="網卡的mac需要指定";#回傳結果return $result;}#if end#如果沒有設定要橋接到哪個bridgeif(!isset($conf["bridgeNet"][$i]["brName"])){#增加socket預設的addr參數$conf["bridgeNet"][$i]["addr"]="230.0.0.1:1234";#將之轉換成socketNet$conf["socketNet"][]=$conf["bridgeNet"][$i];#跳到下一個 bridge netcontinue;}#if end#檢查 $conf["bridgeNet"][$i]["brName"] 是否在 /etc/qemu/bridge.conf 裡面#檢查有無 "allow ".$conf["bridgeNet"][$i]["brName"] 在裡面#函式說明:#尋找檔案裡面有無關鍵字存在,取得其所在列數與內容.#回傳結果:#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.#$reuslt["error"],執行不正常結束的錯訊息陣列.#$result["function"],當前執行的函式名稱.#$result["argu"],所使用的參數.#$result["founded"],是否有找到關鍵字,"true"代表有找到,"false"代表沒有找到.#$result["content"],符合的列數與內容.#$result["content"][$i]["LN"],第$i+1個符合條件的列數.#$result["content"][$i]["LC"],第$i+1個符合條件的列內容.#必填參數:#$conf["fileAddr"],字串,檔案的路徑與名稱.$conf["search::findKeyWordInFile"]["fileAddr"]="/etc/qemu/bridge.conf";#$conf["keyWord"],字串,要搜尋的關鍵字.$conf["search::findKeyWordInFile"]["keyWord"]="allow ".$conf["bridgeNet"][$i]["brName"];#$conf["fileArgu"],字串,__FILE__的內容$conf["search::findKeyWordInFile"]["fileArgu"]=$conf["fileArgu"];$findKeyWordInFile=search::findKeyWordInFile($conf["search::findKeyWordInFile"]);unset($conf["search::findKeyWordInFile"]);#如果尋找關鍵字失敗if($findKeyWordInFile["status"]==="false"){#設置執行不正常$result["status"]="false";#設置執行錯誤的訊息$result["error"]=$findKeyWordInFile;#回傳結果return $result;}#if end#如果有找到關鍵字if($findKeyWordInFile["founded"]==="false"){#設置執行不正常$result["status"]="false";#設置執行錯誤的訊息$result["error"]=$findKeyWordInFile;#回傳結果return $result;}#if end#檢查有無該bridge存在#函式說明:#檢查與取得net interface的資訊#回傳結果#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.#$result["error"],錯誤訊息陣列.#$result["function"],當前執行的函數名稱.#$result["cmd"],使用的command.#$result["argu"],使用的參數.#$result["founded"],是否有找到目標網路界面,"true"代表有,"false"代表沒有.#$result["content"],原始輸出的逐行內容.#必填參數:#$conf["netInterface"],字串,網路界面的名稱.$conf["cmd::getNetDevInfo"]["netInterface"]=$conf["bridgeNet"][$i]["brName"];#$conf["fileArgu"],字串,__FILE__的內容.$conf["cmd::getNetDevInfo"]["fileArgu"]=$conf["fileArgu"];$getNetDevInfo=cmd::getNetDevInfo($conf["cmd::getNetDevInfo"]);unset($conf["cmd::getNetDevInfo"]);#如果執行失敗if($getNetDevInfo["status"]==="false"){#設置執行不正常$result["status"]="false";#設置執行錯誤的訊息$result["error"]=$getNetDevInfo;#回傳結果return $result;}#if end#如果尋找不到bridge的名稱if($getNetDevInfo["founded"]==="false"){#設置執行不正常$result["status"]="false";#設置執行錯誤的訊息$result["error"]=$getNetDevInfo;#回傳結果return $result;}#if end#設置 netdev$paramsArray[]="-netdev";$paramsArray[]="=bridge,name=".$conf["bridgeNet"][$i]["brName"].",id=bridgeNet".$i;#設置網路卡$paramsArray[]="-device";$paramsArray[]=$conf["bridgeNet"][$i]["cardType"].",mac=".$conf["bridgeNet"][$i]["mac"].",netdev=bridgeNet".$i;}#foreache end}#if end#如果有設置 $conf["socketNet"]if(isset($conf["socketNet"])){#有幾個 $conf["socketNet"] 就執行幾次foreach($conf["socketNet"] as $socketNet){#如果未設定 $conf["socketNet"][$i]["cardType"]if(!isset($conf["socketNet"][$i]["cardType"])){#預設為 "virtio-net"$conf["socketNet"][$i]["cardType"]="virtio-net";}#if end#如果沒有指定macif(!isset($conf["socketNet"][$i]["mac"])){#設置執行不正常$result["status"]="false";#設置執行錯誤的訊息$result["error"][]="網卡的mac需要指定";#回傳結果return $result;}#if end#檢查 $conf["socketNet"][$i]["addr"] 是否有設置if(!(isset($conf["socketNet"][$i]["addr"]))){#預設為 "230.0.0.1:1234"$conf["socketNet"][$i]["addr"]="230.0.0.1:1234";}#if end#設置 netdev$paramsArray[]="-netdev";$paramsArray[]="socket,mcast=".$conf["socketNet"][$i]["addr"].",id=socketNet".$i;#設置網卡設備$paramsArray[]="-device";$paramsArray[]=$conf["socketNet"][$i]["cardType"].",mac=".$conf["socketNet"][$i]["mac"].",netdev=socketNet".$i;}#foreache end}#if end#virtio serial$paramsArray[]="-device";$paramsArray[]="-virtio-serial-pci";#qemu agest agent#確保socket檔案可以存在#涵式說明:#確保路徑存在.#回傳的結果:#$result["status"],執行正常與否,"true"代表正常,"false"代表不正常.#$result["error"],錯誤訊息陣列.#$resutl["function"],當前執行的涵式名稱.#$result["path"],建立好的路徑字串.#$result["fileName"],檔案名稱,若 $conf["haveFileName"] 為 "true" 則會回傳.#必填的參數:#$conf["path"],要檢查的路徑$conf["fileAccess::validatePath"]["path"]="/tmp/qbpwcf/qemu/".$_SERVER["LOGNAME"]."-".time()."-org.qemu.guest_agent.0";#$conf["fileArgu"],字串,php變數__FILE__的內容,亦即該檔案在檔案系統的絕對路徑$conf["fileAccess::validatePath"]["fileArgu"]=$conf["fileArgu"];#可省略參數:#$conf["haveFileName"],字串,"true"代表有$conf["path"]檔案名稱,"false"代表$conf["path"]為純路徑,預設為"false".$conf["fileAccess::validatePath"]["haveFileName"]="true";#$conf["dirPermission"],字串,新建資料夾的權限設定,預設爲0770,亦即擁有者,同群組者可以讀,寫,存取,其他人僅能存取.#$conf["dirPermission"]="";$validatePath=fileAccess::validatePath($conf["fileAccess::validatePath"]);unset($conf["fileAccess::validatePath"]);#如果確保路徑失敗if($validatePath["status"]==="false"){#設置執行不正常$result["status"]="false";#設置執行錯誤$result["error"]=$validatePath;#回傳結果return $result;}#if end#設置 qemu agest agent$paramsArray[]="-chardev";$paramsArray[]="socket,id=charchannel0,path=".$validatePath["path"].".".$validatePath["fileName"].",server,nowait";$paramsArray[]="-device";$paramsArray[]="virtserialport,chardev=charchannel0,name=org.qemu.guest_agent.0";#剪貼簿共享$paramsArray[]="-chardev";$paramsArray[]="spicevmc,id=charchannel1,name=vdagent";$paramsArray[]="-device";$paramsArray[]="virtserialport,chardev=charchannel1,name=com.redhat.spice.0";#共享資料夾$paramsArray[]="-chardev";$paramsArray[]="spiceport,id=charchannel2,name=vdagent";$paramsArray[]="-device";$paramsArray[]="virtserialport,chardev=charchannel2,name=org.spice-space.webdav.0";#spice usb redir$paramsArray[]="-chardev";$paramsArray[]="spicevmc,name=usbredir,id=usbredirchardev1";$paramsArray[]="-device";$paramsArray[]="usb-redir,chardev=usbredirchardev1,id=usbredirdev1,debug=3";$paramsArray[]="-chardev";$paramsArray[]="spicevmc,name=usbredir,id=usbredirchardev2";$paramsArray[]="-device";$paramsArray[]="usb-redir,chardev=usbredirchardev2,id=usbredirdev2,debug=3";$paramsArray[]="-chardev";$paramsArray[]="spicevmc,name=usbredir,id=usbredirchardev3";$paramsArray[]="-device";$paramsArray[]="usb-redir,chardev=usbredirchardev3,id=usbredirdev3,debug=3";$paramsArray[]="-chardev";$paramsArray[]="spicevmc,name=usbredir,id=usbredirchardev4";$paramsArray[]="-device";$paramsArray[]="usb-redir,chardev=usbredirchardev4,id=usbredirdev4,debug=3";$paramsArray[]="-chardev";$paramsArray[]="spicevmc,name=usbredir,id=usbredirchardev5";$paramsArray[]="-device";$paramsArray[]="usb-redir,chardev=usbredirchardev5,id=usbredirdev5,debug=3";#uefi bios#-pflash /usr/share/edk2/ovmf/OVMF_CODE.fd \#boot menu$paramsArray[]="-boot";$paramsArray[]="menu=on";#virtio input$paramsArray[]="-device";$paramsArray[]="virtio-keyboard-pci";$paramsArray[]="-device";$paramsArray[]="virtio-mouse-pci";$paramsArray[]="-device";$paramsArray[]="virtio-tablet-pci";#virtio balloon$paramsArray[]="-balloon";$paramsArray[]="virtio,deflate-on-oom=true";#virtio rng$paramsArray[]="-device";$paramsArray[]="virtio-rng-pci";#irq-chip, 需要 iommu 支援#-localtime$paramsArray[]="-localtime";#-daemonize$paramsArray[]="-daemonize";#檢查10000以上的port哪個沒有被使用.#函式說明:#掃port的程式#回傳結果:#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.#$result["error"],錯誤訊息.#$result["function"],當前執行的函數名稱.#$result["argu"],使用的參數.#$result["content"],掃好可能可以使用的port資訊.#必填參數#$conf["fileArgu"],字串,變數__FILE__的內容.$conf["cmd::nmap"]["fileArgu"]=$conf["fileArgu"];#可省略參數:#$conf["target"],字串,要掃描的主機,預設為"127.0.0.1",#$conf["target"]="127.0.0.1";#$conf["-Pn"],字串,是否要啟用避免ping不到就會掃port失敗的功能,預設為"false".#$conf["-Pn"]="false";$nmap=cmd::nmap($conf["cmd::nmap"]);unset($conf["cmd::nmap"]);#如果掃port失敗if($nmap["status"]==="false"){#設置執行不正常$result["status"]="false";#設置執行錯誤的訊息$result["error"]=$nmap;#回傳結果return $result;}#if end#如果沒有使用 $conf["monitorLP"]if(!isset($conf["monitorLP"])){#從port10000開始找是否可用for($i=10000;$i<65536;$i++){#如果port沒有被使用if(!in_array($i,$nmap["content"])){#設定monitor的port$conf["monitorLP"]=$i;#跳出迴圈break;}#if end}#for end}#if end#反之有設定 $conf["monitorLP"]else if(isset($conf["monitorLP"])){#如果port被使用了if(in_array($conf["monitorLP"],$nmap["content"])){#設置執行不正常$result["status"]="false";#設置執行錯誤的訊息$result["error"][]="port ".$conf["monitorLP"]." 已經被使用了";#回傳結果return $result;}#if end}#if end#設置監控的port$paramsArray[]="-serial";$paramsArray[]="mon:telnet::".$conf["monitorLP"].",server,nowait";#執行qemu指令#涵式說明:#呼叫shell執行系統命令,並取得回傳的內容.#回傳的結果:#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.#$result["error"],錯誤訊息陣列.#$result["function"],當前執行的函數名稱.#$result["cmd"],執行的指令內容.#$result["fullCmd"],如果參數 $conf["inBackGround"] 為 "true" 則會回傳該值.#$result["output"],爲執行完二元碼後的輸出陣列,若 $conf["inBackGround"] 為 "true",則為當下的輸出.#$result["tmpFileOutput"],儲存輸出的暫村檔案名稱,若 $conf["inBackGround"] 為 "true" 則會回傳該值.#$result["running"],是否還在執行.#$result["pid"],pid#必填的參數#$conf["command"],字串,要執行的指令與.$conf["external::callShell"]["command"]=$qemuBin;#$conf["fileArgu"],字串,變數__FILE__的內容.$conf["external::callShell"]["fileArgu"]=$conf["fileArgu"];#可省略參數:#$conf["argu"],陣列字串,指令搭配的參數,預設為空陣列.$conf["external::callShell"]["argu"]=$paramsArray;#$conf["arguIsAddr"],陣列字串,指令搭配的哪些參數為路徑,為路徑的參數會進行轉換以便符合呼叫當前函數的位置,預設不指定,若有3個參數,其中第3個參數為路徑,則表示為array("false","false","true").#$conf["arguIsAddr"]=array();#$conf["enablePrintDescription"],字串,是否要印出$conf["printDescription"]的內容,"true"代表要,"false"代表不要,預設為"false".#$conf["enablePrintDescription"]="true";#$conf["printDescription"],字串,執行該外部程式前要印出來的的文字,預設為$conf["command"]的內容.#$conf["printDescription"]="";#$conf["escapeshellarg"],字串,是否要啟用過濾參數,用了比較安全,但可能會出錯,"true"為啟用,"false"為不啟用,預設為"false".$conf["external::callShell"]["escapeshellarg"]="true";#$conf["username"],字串,要用什麼使用者來執行,預設為執行php的使用者,該參數不適用於apache環境.#$conf["username"]="";#$conf["password"],字串,與$conf["username"]搭配的使用者密碼,預設不使用密碼,該參數不適用於apache環境.#$conf["password"]="";#$conf["useScript"],字串,是否要啟用Linux的script指令來記錄輸出,"true"代表要,Fedora的selinux會擋住該操作;"false"代表不要,預設為"false".#$conf["useScript"]="";#$conf["logFilePath"],字串,當 $conf["useScript"] 為 "true" 時,輸出的內容要暫存到哪裡,預設為 "/tmp/.qbpwcf_tmp/external/callShell/".#$conf["logFilePath"]=".qbpwcf_tmp/external/callShell/";#$conf["inBackGround"],字串,是否要在背景執行,且不會等待程式執行結束再執行下一個指令,"true"代表是,"false"代表不要,預設為"false",如果$conf["command"]有用「;」區隔的多個指令將會出錯.$conf["external::callShell"]["inBackGround"]="true";#備註:#不是所有指令都能用apache的身份執行,目前已知java,javac指令無法執行,使用root身份可能會被selinux阻擋.#參考資料:#exec=>http://php.net/manual/en/function.exec.php#escapeshellcmd=>http://php.net/manual/en/function.escapeshellcmd.php#escapeshellarg=>http://php.net/manual/en/function.escapeshellarg.php$callShell=external::callShell($conf["external::callShell"]);unset($conf["external::callShell"]);#如果執行指令失敗if($callShell["status"]==="false"){#設置執行不正常$result["status"]="false";#設置執行錯誤的訊息$result["error"]=$callShell;#回傳結果return $result;}#if end#取得執行的指令$result["cmd"]=$callShell["cmd"];#初始化找到的可能qemu pid 陣列$possiableQemuPidsArray=array();#無窮迴圈while(true){#避免抓到暫時的qemu pidsleep(1);#由於 qemu 的 -daemonize 參數,會將qemu初始化變成常駐程式,因此需要重新尋找正確的pid#函數說明:#檢查指令的輸出是否含有關鍵字#回傳結果:#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.#$result["error"],錯誤訊息.#$result["function"],當前執行的函數名稱.#$result["argu"],使用的參數.#$result["founded"],是否找到關鍵字,"true"代表有,"false"代表沒有.#$result["content"],關鍵字所在列的輸出.#必填參數:#$conf["cmd"],字串,要執行的指令.$conf["cmd::searchOutPut"]["cmd"]="ps aux";#$conf["keyWord"],字串,要檢查是否有關鍵字.$conf["cmd::searchOutPut"]["keyWord"]=$result["cmd"];#$conf["fileArgu"],字串,變數__FILE__的內容.$conf["cmd::searchOutPut"]["fileArgu"]=$conf["fileArgu"];#可省略參數:#$conf["binPath"],字串,要搜尋的路徑,預設為"/usr/bin".#$conf["binPath"]="";$searchOutPut=cmd::searchOutPut($conf["cmd::searchOutPut"]);unset($conf["cmd::searchOutPut"]);#如果搜尋失敗if($searchOutPut["status"]==="false"){#設置執行不正常$result["status"]="false";#設置執行錯誤的訊息$result["error"]=$searchOutPut;#回傳結果return $result;}#if end#如果有找到pid資訊if($searchOutPut["founded"]==="true"){#如果有3個以上的結果if(count($searchOutPut["content"])>3){#休息一秒sleep(1);#在檢查一次continue;}#if end#針對每個輸出foreach($searchOutPut["content"] as $maybeTrueQemuPidStr){#函式說明:#檢查一個字串裡面是否沒有多個任何篩選字存在#回傳的結果:#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.#$result["function"],當前執行的函數#$result["error"],涵式錯誤訊息,若爲""則表示沒有錯誤#$result["filtered"],該字串是否為要過濾掉的,"true"為要過濾掉的;"false"為不用過濾掉的#必填的參數:$conf["search::filterString"]["inputStr"]=$maybeTrueQemuPidStr;#要過濾的字串$conf["search::filterString"]["filterWord"]=array("ps aux"," grep ");#要過濾的字串不能含有該陣列元素之一$filterString=search::filterString($conf["search::filterString"]);unset($conf["search::filterString"]);#如果搜尋失敗if($filterString["status"]==="false"){#設置執行不正常$result["status"]="false";#設置執行錯誤的訊息$result["error"]=$filterString;#回傳結果return $result;}#if end#如果可能是正確的pid資訊列if($filterString["filtered"]==="false"){#解析pid關鍵字#涵式說明:#將固定格式的字串分開,並回傳分開的結果。#回傳結果:#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.#$result["error"],錯誤訊息陣列#$result["function"],當前執行的函數名稱.#$result["oriStr"],要分割的原始字串內容#$result["dataArray"],爲分割好字串的陣列內容,$result["dataArray"][$i]爲第($i+1)段的內容。#$result["dataCounts"],爲總共分成幾段#$result["found"],是否有在$conf["stringIn"]找到$conf["spiltSymbol"],"true"代表有找到,"false"代表沒有找到.#必填的參數:$conf["stringProcess::spiltString"]["stringIn"]=$maybeTrueQemuPidStr;#要處理的字串。$conf["stringProcess::spiltString"]["spiltSymbol"]=" ";#爲以哪個符號作爲分割#可省略參數:#$conf["allowEmptyStr"],是否允許分割出來空字串,預設為"false"不允許;"true"代表允許.$conf["stringProcess::spiltString"]["allowEmptyStr"]="false";$spiltString=stringProcess::spiltString($conf["stringProcess::spiltString"]);unset($conf["stringProcess::spiltString"]);#如果分割字串失敗if($spiltString["status"]==="false"){#設置執行不正常$result["status"]="false";#設置執行錯誤的訊息$result["error"]=$spiltString;#回傳結果return $result;}#if end#如果分割出來的段數小於2if($spiltString["dataCounts"]<2){#設置執行不正常$result["status"]="false";#設置執行錯誤的訊息$result["error"]=$spiltString;#回傳結果return $result;}#if end#如果分割出來的pid段不存在if(!isset($spiltString["dataArray"][1])){#設置執行不正常$result["status"]="false";#設置執行錯誤的訊息$result["error"]=$spiltString;#回傳結果return $result;}#if end#取得正確的pid$callShell["pid"]=$spiltString["dataArray"][1];#如果抓到的pid數量小於1if(count($possiableQemuPidsArray)<1){#取得pid$possiableQemuPidsArray[]=$callShell["pid"];#繼續找可能的pidcontinue 2;}#if end#納後來發現的qemu pid 跳出 whilebreak 2;}#if ned}#foreach end#設置警告的訊息$result["warning"][]=$callShell["pid"]."不為正確的pid";#結束無窮迴圈break;}#if end#反之else{#設置警告的訊息$result["warning"][]=$callShell["pid"]."不為正確的pid";}#else end}#while end#如果存在記錄暫存輸出的檔案if(file_exists($callShell["tmpFileOutput"])){#取得檔案內容$output=file($callShell["tmpFileOutput"]);#如果有內容if(count($output)>0){#設置執行失敗$result["status"]="false";#設置錯誤訊息$result["error"]=$output;#回傳結果return $result;}#if end}#if end#取得程式的pid$result["content"]=$callShell["pid"];#設置執行正常$result["status"]="true";#回傳結果return $result;}#function run end/*#涵式說明:#使用remote-viewer指令進行遠端#回傳結果:#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.#$reuslt["error"],執行不正常結束的錯訊息陣列.#$result["function"],當前執行的函式名稱.#$result["argu"],所使用的參數.#$result["cmd"],執行的指令.#$result["config"],連線所用的config檔案內容.#必填參數:#$conf["type"],字串,"tcp"代表是用網路連線;"sock"代表是用unix socket進行連線,僅限於本機.$conf["type"]="";#$conf["addr"],字串,要連線到的位置,若$conf["type"]是tcp,則可以為IP位置或dns;若$conf["type"]是sock,則可以為socket檔案在本機上的位置.$conf["addr"]="";#$conf["fileArgu"],字串,__FILE__的內容.$conf["fileArgu"]=__FILE__;#可省略參數:#$conf["username"],字串,要用什麼使用者來執行,預設為執行php的使用者,該參數不適用於apache環境.#$conf["username"]="";#$conf["password"],字串,與$conf["username"]搭配的使用者密碼,預設不使用密碼,該參數不適用於apache環境.#$conf["password"]="";#$conf["spicePassword"],字串,連線用的密碼,$conf["type"]為"sock"時不適用.#$conf["spicePassword"]="";#$conf["port"],字串,$conf["addr"]為tcp時,連線用的port.#$conf["port"]="";#$conf["title"],字串,遠端視窗的標題要為什麼?預設為連線的位置.#$conf["title"]="";#$conf["fullScreen"],字串,是否一連線就要全螢幕,"true"代表要,"false"代表不要,預設為"false".#$conf["fullScreen"]="";#備註:#僅能在命列執行.#sock檔案的路徑有錯誤*/function spice(&$conf){#初始化要回傳的結果$result=array();#取得當前執行的函數名稱$result["function"]=__FUNCTION__;#如果沒有參數if(func_num_args()==0){#設置執行失敗$result["status"]="false";#設置執行錯誤訊息$result["error"]="函數".$result["function"]."需要參數";#回傳結果return $result;}#if end#涵式說明:#判斷當前環境為web還是cmd#回傳結果:#$result,"web"或"cmd"if(csInformation::getEnv()=="web"){#設置執行失敗$result["status"]="false";#設置執行錯誤訊息$result["error"][]="函數 ".$result["function"]." 僅能在命令列環境下運行!";#回傳結果return $result;}#if end#取得參數$result["argu"]=$conf;#如果 $conf 不為陣列if(gettype($conf)!="array"){#設置執行失敗$result["status"]="false";#設置執行錯誤訊息$result["error"][]="\$conf變數須為陣列形態";#如果傳入的參數為 nullif($conf==null){#設置執行錯誤訊息$result["error"][]="\$conf變數不得為null,請檢查函數「".$result["function"]."」的參數設置有無正確!";}#if end#回傳結果return $result;}#if end#檢查參數#函式說明:#檢查必填與可省略的參數,可省略參數可指定預設要給與什麼數值內容。#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.#$reuslt["error"],執行不正常結束的錯訊息陣列.#$result["function"],當前執行的函式名稱.#$result["passed"],識別要檢查的全體變數是否存在以及型態是否正確的變數,"true"代表檢查全部通過;"false"代表檢查不通過#$result[$shouldBtCheckedVarName]["varExist"],所檢查的變數是否存在,"false"代表不存在;"true"代表存在#$result[$shouldBtCheckedVarName]["varType"],所檢查的變數型態是否正確,"false"代表錯誤;"true"代表正確#$result[$shouldBtCheckedVarName]["error"],每個參數設定的錯誤訊息#必填寫的參數:#$conf["variableCheck::checkArguments"]["varInput"],陣列變數,要檢查的陣列變數,請在要檢查的參數前面加上&,這樣變動的結果才能被套用。$conf["variableCheck::checkArguments"]["varInput"]=&$conf;#$conf["variableCheck::checkArguments"]["mustBeFilledVariableName"],爲必填參數的變數名稱陣列,形態爲陣列變數,例如: $conf["mustBeFilledVariableName"] = array("id","account","password");$conf["variableCheck::checkArguments"]["mustBeFilledVariableName"]=array("type","addr","fileArgu");#$conf["variableCheck::checkArguments"]["mustBeFilledVariableType"],爲必填參數的變數陣列應該爲何種變數形態,形態爲陣列 例如: $conf["mustBeFilledVariableType"] = array("string",integer,"double");$conf["variableCheck::checkArguments"]["mustBeFilledVariableType"]=array("string","string","string");#$conf["referenceVarKey"],字串,$conf參數後面的key值,用於移除不要的參考陣列.$conf["variableCheck::checkArguments"]["referenceVarKey"]="variableCheck::checkArguments";#可以省略的參數:#$conf["variableCheck::checkArguments"]["canBeEmptyString"],必填變數內容如果是空字串就不能算是有設置的話,請設為"false",預設爲"true"。#$conf["variableCheck::checkArguments"]["canBeEmptyString"]="false";#$conf["variableCheck::checkArguments"]["skipableVariableName"],爲可省略參數的變數名稱陣列,形態爲陣列變數,例如: $conf["skipableVariableName"] = array("id","account","password");$conf["variableCheck::checkArguments"]["skipableVariableName"]=array("username","password","port","title","fullScreen","spicePassword");#$conf["variableCheck::checkArguments"]["skipableVariableType"],爲可省略參數的變數名稱陣列,形態爲陣列變數,例如: $conf["skipableVariableType"] = array("string",integer,"double");$conf["variableCheck::checkArguments"]["skipableVariableType"]=array("string","string","string","string","string","string");#$conf["variableCheck::checkArguments"]["skipableVarDefaultValue"],字串陣列,每個不存在的可省略變數要初始化為什麼,"null"代表不指定,若預設值是必填參數之一,請將$conf["mustBeFilledVar"]改成"\$conf["\mustBeFilledVar\"]".$conf["variableCheck::checkArguments"]["skipableVarDefaultValue"]=array(null,null,null,null,"false",null);#$conf["variableCheck::checkArguments"]["arrayCountEqualCheck"],字串陣列,為檢查哪些陣列參數的元素數量要一樣,$conf["arrayCountEqualCheck"][$i]=array()為第$i組key為哪些的變數其元素數量要相等.#$conf["variableCheck::checkArguments"]["arrayCountEqualCheck"][]=array();$checkResult=variableCheck::checkArguments($conf["variableCheck::checkArguments"]);unset($conf["variableCheck::checkArguments"]);#如果檢查參數失敗if($checkResult["status"]=="false"){#設置執行失敗$result["status"]="false";#設置執行錯誤$result["error"]=$checkResult;#回傳結果return $result;}#if end#如果檢查參數不通過if($checkResult["passed"]=="false"){#設置執行失敗$result["status"]="false";#設置執行錯誤$result["error"]=$checkResult;#回傳結果return $result;}#if end#建立暫存的 remote-viewer 設定檔#函數說明:#建立暫存目錄與回傳暫存檔案名稱路徑#回傳結果:#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.#$result["error"],錯誤訊息.#$result["function"],當前執行的函數名稱.#$result["content"],暫存檔案的路徑與名稱.#必填參數:#無#可省略參數:#$conf["tempDir"],字串,暫存目錄的名稱,預設為.fileAccess/createTempFile$conf["fileAccess::createTempFile"]["tempDir"]="/tmp/qbpwcf/remote-viewer";#$conf["fileArgu"],字串,__FILE__的內容,預設為當前檔案的位置.$conf["fileAccess::createTempFile"]["fileArgu"]=$conf["fileArgu"];#$conf["createPath"],字串,是否僅要建立目錄,"true"代表要,"false"代表不要,預設為"true".#$conf["fileAccess::createTempFile"]["createPath"]="true";#$conf["createFile"],字串,是否要在暫存路徑建立好後建立暫存檔案,"true"代表要,"false"代表不用,預設為"true".#$conf["fileAccess::createTempFile"]["createFile"]="true";$createTempFile=fileAccess::createTempFile($conf["fileAccess::createTempFile"]);unset($conf["fileAccess::createTempFile"]);#如果建立暫存檔案失敗if($createTempFile["status"]==="false"){#設置執行失敗$result["status"]="false";#設置執行錯誤$result["error"]=$createTempFile;#回傳結果return $result;}#if end#初始化要寫入到設定檔裡面的內容$dataToWrite=array("[virt-viewer]","type=spice");#如果有設置標題if(isset($conf["title"])){#設置標題$dataToWrite[]="title=某人的虛擬機器";}#if end#初始化 spice 的目標$spiceAddr="";#判斷 $conf["type"]switch($conf["type"]){#如果是 "tcp"case "tcp":#設置連線的位置$dataToWrite[]="host=".$conf["addr"];#設置連線的 port$dataToWrite[]="port=".$conf["port"];#跳出 switchbreak;#如果是 "sock"case "sock":#初始化執行的參數$argu=array();#如果有設置標題if(isset($conf["title"])){#設置標題$argu[]="-t";$argu[]=$conf["title"];}#if end#如果要全螢幕if($conf["fullScreen"]==="true"){#設置要全螢幕$argu[]="-f";}#if end#將 $conf["addr"] 轉換成絕對位址#函數說明:#將檔案的位置名稱變成網址,也可以取得檔案位於伺服器上檔案系統的絕對位置.#回傳結果:#$result["status"],"true"爲建立成功,"false"爲建立失敗.#$result["error"],錯誤訊息陣列.#$result["function"],函數名稱.#$result["content"],網址,若是在命令列執行,則為"null".#$result["webPathFromRoot"],相對於網頁根目錄的路徑.#$result["fileSystemAbsoulutePosition"],針對伺服器端的絕對位置,亦即從網頁「/」目錄開始的路徑.#$result["fileSystemRelativePosition"],針對伺服器檔案系統的相對位置.#必填參數:#$conf["address"],字串,檔案的相對位置,若為絕對位置則會自動轉換成相對位置.$conf["fileAccess::getInternetAddress"]["address"]=$conf["addr"];#$conf["fileArgu"],字串,php變數__FILE__的內容,亦即該檔案在檔案系統的絕對路徑.$conf["fileAccess::getInternetAddress"]["fileArgu"]=$conf["fileArgu"];#可省略參數:#$conf["userDir"],字串,網頁是否置放於家目錄底下,"true"為是,"false"為不是,預設為"true".#$conf["userDir"]="true";#備註:#在命令列執行,所得的路徑是錯誤的。$getInternetAddress=fileAccess::getInternetAddress($conf["fileAccess::getInternetAddress"]);unset($conf["fileAccess::getInternetAddress"]);#如果取得位址失敗if($getInternetAddress["status"]==="false"){#設置執行失敗$result["status"]="false";#設置執行錯誤$result["error"]=$getInternetAddress;#回傳結果return $result;}#if end#debug#var_dump($getInternetAddress);#檢查socket檔案是否存在#函式說明:#用shell檢查檔案是否存在,可以指定查詢時用的身份.#回傳的結果:#$result["status"],執行是否成功,"true"代表成功,"false"代表失敗.#$result["function"],當前執行的函數名稱.#$result["error"],錯誤訊息陣列.#$result["founded"],"true"代表有找到檔案,"false"代表沒有找到檔案.#必填的參數:#$conf["fileName"],字串,要檢查的檔案名稱.$conf["cmd::checkFileExist"]["fileName"]=$getInternetAddress["fileSystemAbsoulutePosition"];#$conf["fileArgu"],字串,__FILE__的內容,預設為當前檔案的位置.$conf["cmd::checkFileExist"]["fileArgu"]=$conf["fileArgu"];#可省略參數:#$conf["username"],字串,要用哪個身份來檢查檔案是否存在,預設不使用.#$conf["username"]="";#$conf["password"],字串,要用哪個身份來檢查檔案是否存在,預設不使用,若沒有設定好不用密碼即可登入,則在web端會直接出錯,在命令列則會提示輸入密碼.#$conf["password"]="";#備註:#僅能在命令列環境下執行.$checkFileExist=cmd::checkFileExist($conf["cmd::checkFileExist"]);unset($conf["cmd::checkFileExist"]);#如果檔案檢查失敗if($checkFileExist["status"]==="false"){#設置執行失敗$result["status"]="false";#設置執行錯誤$result["error"]=$checkFileExist;#回傳結果return $result;}#if end#如果檔案不存在if($checkFileExist["founded"]==="false"){#設置執行失敗$result["status"]="false";#設置執行錯誤$result["error"]=$checkFileExist;#回傳結果return $result;}#if end#將路徑變成直觀的路徑#函式說明:#將檔案目錄的絕對位置中的 "../" 剔除變成直觀的路徑.#回傳的結果:#$result["status"],執行是否成功,"true"代表執行成功,"false"代表執行失敗.#$result["function"],當前執行的函數.#$result["error"],錯誤訊息陣列.#$result["changedPath"],處理完後回傳的目錄字串.#$result["oriPath"],原始的路徑字串#必填的參數:#$conf["dirStr"],字串,要處理的檔案目錄字串.$conf["stringProcess::changeDirByDotDotSolidus"]["dirStr"]=$getInternetAddress["fileSystemAbsoulutePosition"];$changeDirByDotDotSolidus=stringProcess::changeDirByDotDotSolidus($conf["stringProcess::changeDirByDotDotSolidus"]);unset($conf["stringProcess::changeDirByDotDotSolidus"]);#如果轉換路徑失敗if($changeDirByDotDotSolidus["status"]==="false"){#設置執行失敗$result["status"]="false";#設置執行錯誤$result["error"]=$changeDirByDotDotSolidus;#回傳結果return $result;}#if end#設置位置參數$argu[]=$spiceAddr."spice+unix://".$changeDirByDotDotSolidus["changedPath"];#執行 remote-viewer 指令#涵式說明:#呼叫shell執行系統命令,並取得回傳的內容.#回傳的結果:#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.#$result["error"],錯誤訊息陣列.#$result["function"],當前執行的函數名稱.#$result["cmd"],執行的指令內容.#$result["output"],爲執行完二元碼後的輸出陣列.#必填的參數#$conf["command"],字串,要執行的指令與.$conf["external::callShell"]["command"]="remote-viewer";#$conf["fileArgu"],字串,變數__FILE__的內容.$conf["external::callShell"]["fileArgu"]=$conf["fileArgu"];#可省略參數:#$conf["argu"],陣列字串,指令搭配的參數,預設為空陣列.$conf["external::callShell"]["argu"]=$argu;#$conf["enablePrintDescription"],字串,是否要印出$conf["printDescription"]的內容,"true"代表要,"false"代表不要,預設為"false".$conf["external::callShell"]["enablePrintDescription"]="true";#$conf["printDescription"],字串,執行該外部程式前要印出來的的文字,預設為$conf["command"]的內容.#$conf["external::callShell"]["printDescription"]="";#$conf["escapeshellarg"],字串,是否要啟用過濾參數,用了比較安全,但可能會出錯,"true"為啟用,"false"為不啟用,預設為"false".$conf["external::callShell"]["escapeshellarg"]="true";#如果有設定 $conf["username"]if(isset($conf["username"])){#$conf["username"],字串,要用什麼使用者來執行,預設為執行apache的使用者,該參數不適用於apache環境.$conf["external::callShell"]["username"]=$conf["username"];}#if end#如果有設定 $conf["password"]if(isset($conf["password"])){#$conf["password"],字串,與$conf["username"]搭配的使用者密碼,預設不使用密碼,該參數不適用於apache環境.$conf["external::callShell"]["password"]=$conf["password"];}#if end#$conf["useScript"],字串,是否要啟用Linux的script指令來記錄輸出,"true"代表要;"false"代表不要,預設為"false".#$conf["external::callShell"]["useScript"]="true";#$conf["logFilePath"],字串,當 $conf["useScript"] 為 "true" 時,輸出的內容要暫存到哪裡,預設為 ".qbpwcf_tmp/external/callShell/".#$conf["logFilePath"]=".qbpwcf_tmp/external/callShell/";#$conf["inBackGround"],字串,是否要在背景執行,且不會等待程式執行結束再執行下一個指令,"true"代表是,"false"代表不要,預設為"false",如果$conf["command"]有用「;」區隔的多個指令將會出錯.$conf["external::callShell"]["inBackGround"]="true";#備註:#不是所有指令都能用apache的身份執行,目前已知java,javac指令無法執行,使用root身份可能會被selinux阻擋.#參考資料:#exec=>http://php.net/manual/en/function.exec.php#escapeshellcmd=>http://php.net/manual/en/function.escapeshellcmd.php#escapeshellarg=>http://php.net/manual/en/function.escapeshellarg.php$callShell=external::callShell($conf["external::callShell"]);unset($conf["external::callShell"]);#如果執行 remote-viewer 指令失敗if($callShell["status"]=="false"){#設置執行失敗$result["status"]="false";#設置執行錯誤$result["error"]=$callShell;#回傳結果return $result;}#if end#執行的指令$result["cmd"]=$callShell["cmd"];#執行的pid$result["pid"]=$callShell["pid"];#設置執行正常$result["status"]="true";#回傳結果return $result;#跳出 switchbreak;#如果是其他形態default:#設置執行失敗$result["status"]="false";#設置執行錯誤$result["error"][]="\$conf[\"type\"] 僅能為 tcp 或 sock";#回傳結果return $result;}#switc end#如果要全螢幕if($conf["fullScreen"]==="true"){#設置要全螢幕$dataToWrite[]="fullscreen=1";}#if end#如果有設置連線用的密碼if(isset($conf["spicePassword"])){#設置連線用的密碼$dataToWrite[]="password=".$conf["spicePassword"];}#if end#啟用轉usb$dataToWrite[]="enable-usbredir=1";#不限制usb$dataToWrite[]="usb-filter=-1";#全螢幕快捷按鍵為f11$dataToWrite[]="toggle-fullscreen=f11";#螢幕被抓取時按下 ctrl+alt 即可離開$dataToWrite[]="release-cursor=ctrl+alt";#將參數寫到暫存檔案裡面#涵式說明:#將多行字串寫入到檔案#回傳的結果:#$result["status"],"true"表示檔案寫入成功,"false"表示檔案寫入失敗.#$result["error"],錯誤訊息陣列.#$result["function"],當前執行函數的名稱.#必填的參數:#$conf["fileName"],字串,爲要編輯的檔案名稱$conf["fileAccess::writeMultiLine"]["fileName"]=$createTempFile["content"];#$conf["inputString"],字串陣列,爲要寫入到 $conf["fileName"] 裏面的內容#$conf["inputString"][$i] 代表第 $i+1 行。$conf["fileAccess::writeMultiLine"]["inputString"]=$dataToWrite;#$conf["fileArgu"],字串,php變數__FILE__的內容,亦即該檔案在檔案系統的絕對路徑$conf["fileAccess::writeMultiLine"]["fileArgu"]=$conf["fileArgu"];#可省略的參數:#$conf["writeMethod"]="a";#爲檔案撰寫的方式,可省略,是複寫'a'還是,重新寫入'w',預設爲'w',重新寫入。$writeMultiLine=fileAccess::writeMultiLine($conf["fileAccess::writeMultiLine"]);unset($conf["fileAccess::writeMultiLine"]);#如果撰寫多行文字失敗if($writeMultiLine["status"]==="false"){#設置執行失敗$result["status"]="false";#設置執行錯誤$result["error"]=$writeMultiLine;#回傳結果return $result;}#if end#執行 remote-viewer 指令#涵式說明:#呼叫shell執行系統命令,並取得回傳的內容.#回傳的結果:#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.#$result["error"],錯誤訊息陣列.#$result["function"],當前執行的函數名稱.#$result["cmd"],執行的指令內容.#$result["output"],爲執行完二元碼後的輸出陣列.#必填的參數#$conf["command"],字串,要執行的指令與.$conf["external::callShell"]["command"]="remote-viewer";#$conf["fileArgu"],字串,變數__FILE__的內容.$conf["external::callShell"]["fileArgu"]=$conf["fileArgu"];#可省略參數:#$conf["argu"],陣列字串,指令搭配的參數,預設為空陣列.$conf["external::callShell"]["argu"]=array($createTempFile["content"]);#$conf["enablePrintDescription"],字串,是否要印出$conf["printDescription"]的內容,"true"代表要,"false"代表不要,預設為"false".$conf["external::callShell"]["enablePrintDescription"]="true";#$conf["printDescription"],字串,執行該外部程式前要印出來的的文字,預設為$conf["command"]的內容.#$conf["external::callShell"]["printDescription"]="";#$conf["escapeshellarg"],字串,是否要啟用過濾參數,用了比較安全,但可能會出錯,"true"為啟用,"false"為不啟用,預設為"false".$conf["external::callShell"]["escapeshellarg"]="true";#如果有設定 $conf["username"]if(isset($conf["username"])){#$conf["username"],字串,要用什麼使用者來執行,預設為執行apache的使用者,該參數不適用於apache環境.$conf["external::callShell"]["username"]=$conf["username"];}#if end#如果有設定 $conf["password"]if(isset($conf["password"])){#$conf["password"],字串,與$conf["username"]搭配的使用者密碼,預設不使用密碼,該參數不適用於apache環境.$conf["external::callShell"]["password"]=$conf["password"];}#if end#$conf["useScript"],字串,是否要啟用Linux的script指令來記錄輸出,"true"代表要;"false"代表不要,預設為"false".#$conf["external::callShell"]["useScript"]="true";#$conf["logFilePath"],字串,當 $conf["useScript"] 為 "true" 時,輸出的內容要暫存到哪裡,預設為 ".qbpwcf_tmp/external/callShell/".#$conf["logFilePath"]=".qbpwcf_tmp/external/callShell/";#$conf["inBackGround"],字串,是否要在背景執行,且不會等待程式執行結束再執行下一個指令,"true"代表是,"false"代表不要,預設為"false",如果$conf["command"]有用「;」區隔的多個指令將會出錯.$conf["external::callShell"]["inBackGround"]="true";#備註:#不是所有指令都能用apache的身份執行,目前已知java,javac指令無法執行,使用root身份可能會被selinux阻擋.#參考資料:#exec=>http://php.net/manual/en/function.exec.php#escapeshellcmd=>http://php.net/manual/en/function.escapeshellcmd.php#escapeshellarg=>http://php.net/manual/en/function.escapeshellarg.php$callShell=external::callShell($conf["external::callShell"]);unset($conf["external::callShell"]);#如果執行 remote-viewer 指令失敗if($callShell["status"]=="false"){#設置執行失敗$result["status"]="false";#設置執行錯誤$result["error"]=$callShell;#回傳結果return $result;}#if end#執行的指令$result["cmd"]=$callShell["cmd"];#執行的pid$result["pid"]=$callShell["pid"];#休息一秒,避免設定檔被刪除sleep(1);#移除暫存檔案裡面#涵式說明:#移除檔案#回傳的結果:#$result["status"],"true"代表移除成功,"false"代表移除失敗.#$result["error"],錯誤訊息陣列#$result["warning"],警告訊息陣列#$result["function"],當前執行的函數名稱#必填的參數:#$conf["fileAddress"],字串,要移除檔案的位置.$conf["fileAccess::delFile"]["fileAddress"]=$createTempFile["content"];#$conf["fileArgu"],字串,php變數__FILE__的內容,亦即該檔案在檔案系統的絕對路徑.$conf["fileAccess::delFile"]["fileArgu"]=$conf["fileArgu"];#可省略參數:#$conf["commentsArray"],字串陣列,提示的文字描述,$conf["commentsArray"][$i]代表第($+1)行的描述.#$conf["commentsArray"]=array("");$delFile=fileAccess::delFile($conf["fileAccess::delFile"]);unset($conf["fileAccess::delFile"]);#如果移除暫存檔案失敗if($delFile["status"]==="false"){#設置執行失敗$result["status"]="false";#設置執行錯誤$result["error"]=$delFile;#回傳結果return $result;}#if end#設置執行正常$result["status"]="true";#回傳結果return $result;}#function spice end/*#涵式說明:#尋找指定路徑下的虛擬硬碟,將之重新轉換與壓縮,再取掉代原有的檔案.#回傳結果:#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.#$result["error"],錯誤訊息.#$result["function"],當前執行的函數名稱.#$result["argu"],所使用的參數.#$result["found"],是否有找到可以轉換的檔案,"true"代表有;"false"代表沒有.#$result["content"],有改變的虛擬硬碟位置字串陣列.#必填參數:#$conf["path"],字串,虛擬硬碟檔案的搜尋路徑.#$conf["path"]="";#$conf["fileArgu"],字串,php變數__FILE__的內容,亦即該檔案在檔案系統的絕對路徑#$conf["fileArgu"]=__FILE__;#備註:#目前只支援qcow2格式的虛擬硬碟*/public static function imgConvert(&$conf=array()){#初始化要回傳的結果$result=array();#取得當前執行的函數名稱$result["function"]=__FUNCTION__;#如果沒有參數if(func_num_args()==0){#設置執行失敗$result["status"]="false";#設置執行錯誤訊息$result["error"]="函數".$result["function"]."需要參數";#回傳結果return $result;}#if end#涵式說明:#判斷當前環境為web還是cmd#回傳結果:#$result,"web"或"cmd"if(csInformation::getEnv()==="web"){#設置執行失敗$result["status"]="false";#設置執行錯誤訊息$result["error"][]="函數 ".$result["function"]." 僅能在命令列環境下運行!";#回傳結果return $result;}#if end#取得參數$result["argu"]=$conf;#如果 $conf 不為陣列if(gettype($conf)!=="array"){#設置執行失敗$result["status"]="false";#設置執行錯誤訊息$result["error"][]="\$conf變數須為陣列形態";#如果傳入的參數為 nullif($conf===null){#設置執行錯誤訊息$result["error"][]="\$conf變數不得為null,請檢查函數「".$result["function"]."」的參數設置有無正確!";}#if end#回傳結果return $result;}#if end#函式說明:#檢查必填與可省略的參數,可省略參數可指定預設要給與什麼數值內容。#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.#$reuslt["error"],執行不正常結束的錯訊息陣列.#$result["function"],當前執行的函式名稱.#$result["argu"],設置給予的參數.#$result["passed"],識別要檢查的全體變數是否存在以及型態是否正確的變數,"true"代表檢查全部通過;"false"代表檢查不通過#$result[$shouldBeCheckedVarName]["varExist"],所檢查的變數是否存在,"false"代表不存在;"true"代表存在#$result[$shouldBeCheckedVarName]["varType"],所檢查的變數型態是否正確,"false"代表錯誤;"true"代表正確#$result[$shouldBeCheckedVarName]["error"],每個參數設定的錯誤訊息#$result["shouldNotBeEmpty"],不應該為空字串或控陣列的變數.#$result["argu"],字串陣列,目前輸入的參數名稱陣列.#$result["legalVarName"],字串陣列,合法可用的參數名稱陣列.#$result["notNeedVar"],字串陣列,多餘的參數名稱.#必填寫的參數:#$conf["varInput"],陣列變數,要檢查的陣列變數,請在要檢查的參數前面加上&,這樣變動的結果才能被套用。$conf["variableCheck::checkArguments"]["varInput"]=&$conf;#$conf["referenceVarKey"],字串,$conf參數後面的key值,用於移除不要的參考陣列.$conf["variableCheck::checkArguments"]["referenceVarKey"]="variableCheck::checkArguments";#可以省略的參數:#$conf["mustBeFilledVariableName"],爲必填參數的變數名稱陣列,形態爲陣列變數,元素數量需要跟"mustBeFilledVariableType"參數的元素數量一致,例如: $conf["mustBeFilledVariableName"] = array("id","account","password");$conf["variableCheck::checkArguments"]["mustBeFilledVariableName"]=array("path","fileArgu");#$conf["mustBeFilledVariableType"],爲必填參數的變數陣列應該爲何種變數形態,形態爲陣列,元素數量需要跟"mustBeFilledVariableName"參數的元素數量一致,例如: $conf["mustBeFilledVariableType"] = array("string",integer,"double","resource","object"); , null代表不指定變數形態.$conf["variableCheck::checkArguments"]["mustBeFilledVariableType"]=array("string","string");#$conf["canBeEmptyString"],字串,必填變數內容如果是空字串就不能算是有設置的話,請設為"false",預設爲"true",可以為空字串.$conf["variableCheck::checkArguments"]["canBeEmptyString"]="false";#$conf["canNotBeEmpty"],字串陣列,哪些必填參數的內容不得為空字串或空陣列,僅當$conf["canBeEmptyString"]為"true"時會生效.#$conf["canNotBeEmpty"]=array();#$conf["canBeEmpty"],字串陣列,哪些必填參數的內容可為空字串或空陣列,僅當$conf["canBeEmptyString"]為"false"時會生效.#$conf["canBeEmpty"]=array();#$conf["skipableVariableCanNotBeEmpty"],字串陣列,哪些可省略參數不可以為空字串或空陣列.#$conf["skipableVariableCanNotBeEmpty"]=array();#$conf["skipableVariableName"],陣列字串,爲可省略參數的變數名稱陣列,形態爲陣列變數,例如: $conf["skipableVariableName"] = array("id","account","password");#$conf["skipableVariableName"]=array();#$conf["skipableVariableType"],陣列字串,爲可省略參數的變數名稱陣列,形態爲陣列變數,例如: $conf["skipableVariableType"] = array("string",integer,"double");#$conf["skipableVariableType"]=array();#$conf["skipableVarDefaultValue"],字串陣列,每個不存在的可省略變數要初始化為什麼,null與代表不指定,若預設值是參數之一,請將$conf["mustBeFilledVar"]改成"\$conf["\mustBeFilledVar\"]".#$conf["skipableVarDefaultValue"]=array("");#$conf["disallowAllSkipableVarIsEmpty"],字串,是否允許每個可省略參數都為空字串,預設為"true"允許,反之為"false".#$conf["disallowAllSkipableVarIsEmpty"]="";#$conf["disallowAllSkipableVarIsEmptyArray"],字串,是否允許每個可省略參數都為空陣列,預設為"true"允許,反之為"false".#$conf["disallowAllSkipableVarIsEmptyArray"]="";#$conf["arrayCountEqualCheck"],字串陣列,為檢查哪些陣列參數的元素數量要一樣,$conf["arrayCountEqualCheck"][$i]=array()為第$i組key為哪些的變數其元素數量要相等.#$conf["arrayCountEqualCheck"][]=array();#參考資料來源:#array_keys=>http://php.net/manual/en/function.array-keys.php$checkArguments=variableCheck::checkArguments($conf["variableCheck::checkArguments"]);unset($conf["variableCheck::checkArguments"]);#如果檢查參數失敗if($checkArguments["status"]==="false"){#設置執行失敗$result["status"]="false";#設置執行失敗訊息$result["error"]=$checkArguments;#回傳結果return $result;}#if end#如果檢查參數不通過if($checkArguments["passed"]==="false"){#設置執行失敗$result["status"]="false";#設置執行失敗訊息$result["error"]=$checkArguments;#回傳結果return $result;}#if end#函數說明:#將檔案的位置名稱變成網址,也可以取得檔案位於伺服器上檔案系統的絕對位置.#回傳結果:#$result["status"],"true"爲建立成功,"false"爲建立失敗.#$result["error"],錯誤訊息陣列.#$result["function"],函數名稱.#$result["argu"],使用的參數.#$result["content"],網址,若是在命令列執行,則為"null".#$result["webPathFromRoot"],相對於網頁根目錄的路徑.#$result["fileSystemAbsoulutePosition"],針對伺服器端的絕對位置,亦即從網頁「/」目錄開始的路徑.#$result["fileSystemRelativePosition"],針對伺服器檔案系統的相對位置.#必填參數:#$conf["address"],字串,檔案的相對位置,若為絕對位置則會自動轉換成相對位置.$conf["fileAccess::getInternetAddress"]["address"]=$conf["path"];#$conf["fileArgu"],字串,php變數__FILE__的內容,亦即該檔案在檔案系統的絕對路徑.$conf["fileAccess::getInternetAddress"]["fileArgu"]=$conf["fileArgu"];#可省略參數:#$conf["userDir"],字串,網頁是否置放於家目錄底下,"true"為是,"false"為不是,預設為"true".#$conf["userDir"]="true";$getInternetAddress=fileAccess::getInternetAddress($conf["fileAccess::getInternetAddress"]);unset($conf["fileAccess::getInternetAddress"]);#如果轉換失敗if($getInternetAddress["status"]==="false"){#設置執行失敗$result["status"]="false";#設置執行失敗訊息$result["error"]=$getInternetAddress;#回傳結果return $result;}#if end#取得轉換好的相對路徑$conf["path"]=$getInternetAddress["fileSystemRelativePosition"];#如果不存在要搜尋的路徑if(!file_exists($conf["path"])){#設置執行失敗$result["status"]="false";#設置執行失敗訊息$result["error"][]="path ".$conf["path"]." not found";#回傳結果return $result;}#反之要搜尋的路徑存在else{#初始化儲存要印出的內容$line2print=array();#且路徑是檔案if(is_file($conf["path"])){#檢查副檔名是否為 qcow2#涵式說明:#取得符合特定字首與字尾的字串#回傳的結果:#$result["status"],若爲"true"則代表執行正常;若爲"false"則代表執行失敗。#$result["function"],當前執行的函數名稱.#$result["error"],錯誤訊息陣列.#$result["founded"],若為"true"則代表有找到符合字首條件的結果;若爲"false"則代表沒有找到。#$result["returnString"],爲符合字首條件的字串內容。#必填參數:#$conf["checkString"],字串,要檢查的字串.$conf["search::getMeetConditionsString"]["checkString"]=$conf["path"];#可省略參數:#$conf["frontWord"],字串,用來檢查字首應該要有什麼字串,預設不指定.#$conf["frontWord"]="";#$conf["tailWord"],字串,用來檢查字尾應該要有什麼字串,預設不指定.$conf["search::getMeetConditionsString"]["tailWord"]=".qcow2";#參考資料:#str_spilt(),可以將字串依照字母分割成一個個陣列字串。$getMeetConditionsString=search::getMeetConditionsString($conf["search::getMeetConditionsString"]);unset($conf["search::getMeetConditionsString"]);#如果搜尋失敗if($getMeetConditionsString["status"]==="false"){#設置執行失敗$result["status"]="false";#設置執行失敗訊息$result["error"]=$getMeetConditionsString;#回傳結果return $result;}#if end#如果副檔名不是 qcow2if($getMeetConditionsString["founded"]==="false"){#設置執行失敗$result["status"]="false";#設置執行失敗訊息$result["error"]=$getMeetConditionsString;#回傳結果return $result;}#if end#且副檔案為 qcow2#設置執行正常$findFile["status"]="true";#設置有找到檔案$findFile["found"]="true";#設置找到的檔案路徑$findFile["content"][]=$conf["path"];}#if end#不是檔案else{#涵式說明:#尋找檔案.#回傳結果:#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.#$result["error"],錯誤訊息.#$result["warning"],警告訊息陣列.#$result["function"],當前執行的函數名稱.#$result["argu"],所使用的參數.#$result["found"],是否有找到可以轉換的檔案,"true"代表有;"false"代表沒有.#$result["content"],找到的檔案陣列.#必填參數:#$conf["keyWord"],字串,要搜尋的檔案關鍵字,可用"*"符號,例如"*.qcow2",就代表檔案名成為"qcow2"結尾的檔案.$conf["fileAccess::findFile"]["keyWord"]="*.qcow2";#$conf["path"],字串陣列,虛擬硬碟檔案的搜尋路徑,預設為當前路徑.$conf["fileAccess::findFile"]["path"]=array($conf["path"]);#$conf["fileArgu"],字串,php變數__FILE__的內容,亦即該檔案在檔案系統的絕對路徑$conf["fileAccess::findFile"]["fileArgu"]=$conf["fileArgu"];#參考資料:#http://php.net/manual/en/function.glob.php$findFile=fileAccess::findFile($conf["fileAccess::findFile"]);unset($conf["fileAccess::findFile"]);}#else end}#esle end#如果檢查檔案失敗if($findFile["status"]==="false"){#設置執行失敗$result["status"]="false";#設置執行失敗訊息$result["error"]=$findFile;#回傳結果return $result;}#if end#如果有符合的檔案if($findFile["found"]==="true"){#初始化儲存要印出的內容$line2print=array();#提示內容標題$line2print[]="找到以下檔案可以進行轉換:";#依照找到的數目foreach($findFile["content"] as $qcow2ImgFile){#記錄檔案$line2print[]=$qcow2ImgFile;}#foreach end#提示找到以下檔案可以進行整理#函式說明:#印出多行文字,結尾自動換行.#回傳的結果:#$result["status"],執行是否成功,"true"代表成功,"false"代表失敗.#$result["function"],當前執行的函數名稱.#$result["error"],錯誤訊息陣列.#必填的參數:#$conf["outputStringArray"],字串陣列,每行要印出的文字內容.$conf["cmd::echoMultiLine"]["outputStringArray"]=$line2print;$echoMultiLine=cmd::echoMultiLine($conf["cmd::echoMultiLine"]);unset($conf["cmd::echoMultiLine"]);#如果執行失敗if($echoMultiLine["status"]==="false"){#設置執行失敗$result["status"]="false";#設置執行失敗訊息$result["error"]=$echoMultiLine;#回傳結果return $result;}#if end#如果符合的檔案數量為>0if(count($findFile["content"])>0){#針對每個虛擬硬碟foreach($findFile["content"] as $vdisk){#檢查虛擬硬碟是否有被使用#涵式說明:#取得虛擬硬碟的資訊與檢查是否被使用中#回傳結果:#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.#$result["error"],錯誤訊息.#$result["function"],當前執行的函數名稱.#$result["argu"],所使用的參數.#$result["used"],是否被使用中,"true"代表有;"false"代表沒有.#$result["image"],虛擬硬碟的路徑與名稱.#$result["file format"],虛擬硬碟的格式.#$result["virtual size"],虛擬硬碟實際可以儲存的最大容量.#$result["disk size"],虛擬硬碟檔案所佔的大小.#$result["cluster_size"],佔用空間的最小單位.#必填參數:#$conf["img"],字串,虛擬硬碟檔案的路徑與名稱.$conf["qemu::imgInfo"]["img"]=$vdisk;#$conf["fileArgu"],字串,php變數__FILE__的內容,亦即該檔案在檔案系統的絕對路徑$conf["qemu::imgInfo"]["fileArgu"]=$conf["fileArgu"];$imgInfo=qemu::imgInfo($conf["qemu::imgInfo"]);unset($conf["qemu::imgInfo"]);#如果運行失敗if($imgInfo["status"]==="false"){#設置執行失敗$result["status"]="false";#設置執行失敗訊息$result["error"]=$imgInfo;#回傳結果return $result;}#if end#如果虛擬硬碟檔案使用中if($imgInfo["used"]==="true"){#設置執行失敗$result["status"]="false";#設置執行失敗訊息$result["error"]=$imgInfo;#回傳結果return $result;}#if end#var_dump($imgInfo);#檢查檔案所在位置的分割區剩餘空間是否足夠#涵式說明:#判斷檔案位於哪個分割區#回傳結果:#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.#$result["error"],錯誤訊息.#$result["function"],當前執行的函數名稱.#$result["argu"],所使用的參數.#$result["content"],找到的檔案所屬分割區資訊.#必填參數:#$conf["file"],字串,檔案的路徑與名稱.$conf["fileAccess::addrInMountPoint"]["file"]=$vdisk;#$conf["fileArgu"],字串,php變數__FILE__的內容,亦即該檔案在檔案系統的絕對路徑$conf["fileAccess::addrInMountPoint"]["fileArgu"]=$conf["fileArgu"];$addrInMountPoint=fileAccess::addrInMountPoint($conf["fileAccess::addrInMountPoint"]);unset($conf["fileAccess::addrInMountPoint"]);#如果虛擬硬碟檔案使用中if($addrInMountPoint["status"]==="false"){#設置執行失敗$result["status"]="false";#設置執行失敗訊息$result["error"]=$addrInMountPoint;#回傳結果return $result;}#if end#取得虛擬硬碟檔案歸屬的掛載點$mountPoint=$addrInMountPoint["content"];#函式說明:#透過"df -h"取得伺服器上的磁碟空間用量#回傳結果#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.#$result["error"],錯誤訊息陣列.#$result["function"],當前執行的函數名稱.#$result["argu"],使用的參數#$result["content"],磁碟空間用量.#$result["oriOutput"],原始輸出的逐行內容.#必填參數:#$conf["fileArgu"],字串,__FILE__的內容.$conf["cmd::getStorageUsage"]["fileArgu"]=$conf["fileArgu"];$getStorageUsage=cmd::getStorageUsage($conf["cmd::getStorageUsage"]);unset($conf["cmd::getStorageUsage"]);#如果執行失敗if($getStorageUsage["status"]==="false"){#設置執行失敗$result["status"]="false";#設置執行失敗訊息$result["error"]=$getStorageUsage;#回傳結果return $result;}#if end#debug#var_dump($getStorageUsage);#初始化該分割區可用的空間為0G$availSize="0G";#根據每個儲存區foreach($getStorageUsage["content"] as $block){#如果是所屬的分割區if($block["Mounted"]===$mountPoint){#取得剩下的分割區空間$availSize=$block["Avail"];#分割區大小單位$availSizeUnit=$availSize[strlen($availSize)-1];#取得沒有單位的分割區空間$availSize=substr($availSize,0,strlen($availSize)-1);#var_dump($availSize);#依照單位switch($availSizeUnit){#如果是Kcase "K":#處以1000000,以G為單位$availSize=$availSize/1000/1000;#如果是Mcase "M":#除以1000,以G為單位$availSize=$availSize/1000;#跳出break;#如果是Gcase "G":#跳出break;#如果是Tcase "T";#乘以1000,以G為單位$availSize=$availSize*1000;#跳出break;#其他單位default:#設置執行失敗$result["status"]="false";#設置執行失敗訊息$result["error"]=$getStorageUsage;#設置執行失敗訊息$result["error"][]="not supported unit ".$availSizeUnit;#回傳結果return $result;}#switch end#跳出 foreachbreak;}#if end}#foreach end#取得虛擬硬碟的大小$diskSize=$imgInfo["disk size"];#虛擬硬碟的大小單位$diskSizeUnit=$diskSize[strlen($diskSize)-1];#var_dump($diskSizeUnit);#取得沒有單位的虛擬硬碟大小$diskSize=substr($diskSize,0,strlen($diskSize)-1);#依照單位switch($diskSizeUnit){#如果是Kcase "K":#處以1000000,以G為單位$diskSize=$diskSize/1000/1000;#如果是Mcase "M":#除以1000,以G為單位$diskSize=$diskSize/1000;#跳出break;#如果是Gcase "G":#跳出break;#如果是Tcase "T";#乘以1000,以G為單位$diskSize=$diskSize*1000;#跳出break;#其他單位default:#設置執行失敗$result["status"]="false";#設置執行失敗訊息$result["error"]=$getStorageUsage;#設置執行失敗訊息$result["error"][]="not supported unit ".$diskSizeUnit;#回傳結果return $result;}#switch end#如果虛擬硬碟大小 大於 剩餘空間if($diskSize>=$availSize){#設置執行失敗$result["status"]="false";#設置執行失敗訊息$result["error"][]="剩餘的空間(".$availSize."M)可能不夠虛擬硬碟(".$diskSize."M)轉換";#回傳結果return $result;}#if end#解析檔案的副檔名與名稱#涵式說明:#取得檔案的副檔名#回傳結果:#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.#$result["error"],錯誤訊息.#$result["function"],當前執行的函數名稱.#$result["argu"],所使用的參數.#$result["content"],副檔名.#$result["name"],不含副檔的名稱.#$result["fullName"],含副檔的名稱.#$result["path"],檔案所處的路徑.#必填參數:#$conf["file"],字串,檔案的路徑與名稱.$conf["fileAccess::getExtension"]["file"]=$vdisk;#$conf["fileArgu"],字串,php變數__FILE__的內容,亦即該檔案在檔案系統的絕對路徑$conf["fileAccess::getExtension"]["fileArgu"]=$conf["fileArgu"];$getExtension=fileAccess::getExtension($conf["fileAccess::getExtension"]);unset($conf["fileAccess::getExtension"]);#如果執行失敗if($getExtension["status"]==="false"){#設置執行失敗$result["status"]="false";#設置執行失敗訊息$result["error"]=$getExtension;#回傳結果return $result;}#if end#轉換好的檔案名稱$refreVdisk=$getExtension["path"].$getExtension["name"]."-refreshed.".$getExtension["content"];#轉換與壓縮虛擬硬碟#涵式說明:#呼叫shell執行系統命令,並取得回傳的內容.#回傳的結果:#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.#$result["error"],錯誤訊息陣列.#$result["function"],當前執行的函數名稱.#$result["argu"],使用的參數.#$result["cmd"],執行的指令內容.#$result["fullCmd"],如果參數 $conf["inBackGround"] 為 "true" 則會回傳該值.#$result["output"],爲執行完二元碼後的輸出陣列,若 $conf["inBackGround"] 為 "true",則為當下的輸出.#$result["tmpFileOutput"],儲存輸出的暫存檔案名稱,若 $conf["inBackGround"] 為 "true" 則會回傳該值.#$result["running"],是否還在執行.#$result["pid"],pid#必填的參數#$conf["command"],字串,要執行的指令與.$conf["external::callShell"]["command"]="qemu-img";#$conf["fileArgu"],字串,變數__FILE__的內容.$conf["external::callShell"]["fileArgu"]=$conf["fileArgu"];#可省略參數:#$conf["argu"],陣列字串,指令搭配的參數,預設為空陣列.$conf["external::callShell"]["argu"]=array("convert","-c","-f","qcow2","-O","qcow2",$vdisk,$refreVdisk);#$conf["arguIsAddr"],陣列字串,指令搭配的哪些參數為路徑,為路徑的參數會進行轉換以便符合呼叫當前函數的位置,預設不指定,若有3個參數,其中第3個參數為路徑,則表示為array("false","false","true").#$conf["arguIsAddr"]=array();#$conf["pre"],陣列,要在本指令前執行的每個指令與參數.#$conf["pre"][$i]["cmd"],字串,要在本指令前執行的第$i+1個指令.#$conf["pre"][$i]["param"],陣列字串,要在本指令前執行的第$i+1個指令的參數.#$conf["enablePrintDescription"],字串,是否要印出$conf["printDescription"]的內容,"true"代表要,"false"代表不要,預設為"false".$conf["external::callShell"]["enablePrintDescription"]="true";#$conf["printDescription"],字串,執行該外部程式前要印出來的的文字,預設為$conf["command"]的內容加上使用的$conf["argu"]參數.#$conf["external::callShell"]["printDescription"]="";#$conf["escapeshellarg"],字串,是否要啟用過濾參數,用了比較安全,但可能會出錯,"true"為啟用,"false"為不啟用,預設為"false".$conf["external::callShell"]["escapeshellarg"]="true";#$conf["username"],字串,要用什麼使用者來執行,預設為執行php的使用者,該參數不適用於apache環境.#$conf["username"]="";#$conf["password"],字串,與$conf["username"]搭配的使用者密碼,預設不使用密碼,該參數不適用於apache環境.#$conf["password"]="";#$conf["useScript"],字串,是否要啟用Linux的script指令來記錄輸出,"true"代表要,Fedora的selinux會擋住該操作;"false"代表不要,預設為"false".#$conf["useScript"]="";#$conf["logFilePath"],字串,當 $conf["useScript"] 為 "true" 時,輸出的內容要暫存到哪裡,預設為 "/tmp/.qbpwcf_tmp/external/callShell/".#$conf["logFilePath"]=".qbpwcf_tmp/external/callShell/";#$conf["inBackGround"],字串,是否要在背景執行,且不會等待程式執行結束再執行下一個指令,"true"代表是,"false"代表不要,預設為"false",如果$conf["command"]有用「;」區隔的多個指令將會出錯.#$conf["inBackGround"]="";#備註:#不是所有指令都能用apache的身份執行,目前已知java,javac指令無法執行,使用root身份可能會被selinux阻擋.#參考資料:#exec=>http://php.net/manual/en/function.exec.php#escapeshellcmd=>http://php.net/manual/en/function.escapeshellcmd.php#escapeshellarg=>http://php.net/manual/en/function.escapeshellarg.php$callShell=external::callShell($conf["external::callShell"]);unset($conf["external::callShell"]);#如果執行失敗if($callShell["status"]==="false"){#設置執行失敗$result["status"]="false";#設置執行失敗訊息$result["error"]=$callShell;#回傳結果return $result;}#if end#取代舊的虛擬硬碟#涵式說明:#移動檔案#回傳結果:#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.#$result["function"],當前執行的函數名稱#$result["error"],錯誤訊息.#$result["content"],檔案輸出後的位置與名稱.#必填參數:#$conf["from"],字串,要移動的檔案名稱與位置.$conf["fileAccess::mv"]["from"]=$refreVdisk;#$conf["to"],字串,要移動到的位置與名稱$conf["fileAccess::mv"]["to"]=$vdisk;#$conf["fileArgu"],字串,php變數__FILE__的內容,亦即該檔案在檔案系統的絕對路徑$conf["fileAccess::mv"]["fileArgu"]=$conf["fileArgu"];#可省略參數:#$conf["commentsArray"],字串陣列,提示的文字描述,$conf["commentsArray"][$i]代表第($+1)行的描述.#$conf["commentsArray"]=array("");$mv=fileAccess::mv($conf["fileAccess::mv"]);unset($conf["fileAccess::mv"]);#如果執行失敗if($mv["status"]==="false"){#設置執行失敗$result["status"]="false";#設置執行失敗訊息$result["error"]=$mv;#回傳結果return $result;}#if end#記錄轉換好的檔案$result["content"][]=$vdisk;}#foreach end#初始化儲存要印出的內容$line2print=array();#提示內容標題$line2print[]="以下檔案已轉換完畢:";#依照找到的數目foreach($result["content"] as $qcow2ImgFile){#記錄檔案$line2print[]=$qcow2ImgFile;}#foreach end#提示找到以下檔案可以進行整理#函式說明:#印出多行文字,結尾自動換行.#回傳的結果:#$result["status"],執行是否成功,"true"代表成功,"false"代表失敗.#$result["function"],當前執行的函數名稱.#$result["error"],錯誤訊息陣列.#必填的參數:#$conf["outputStringArray"],字串陣列,每行要印出的文字內容.$conf["cmd::echoMultiLine"]["outputStringArray"]=$line2print;$echoMultiLine=cmd::echoMultiLine($conf["cmd::echoMultiLine"]);unset($conf["cmd::echoMultiLine"]);#如果執行失敗if($echoMultiLine["status"]==="false"){#設置執行失敗$result["status"]="false";#設置執行失敗訊息$result["error"]=$echoMultiLine;#回傳結果return $result;}#if end}#if end}#if end#反之沒有符合的檔案else{#設置執行失敗$result["status"]="false";#設置執行失敗訊息$result["error"]=$findFile;#回傳結果return $result;}#else end#設置執行正常$result["status"]="true";#回傳結果return $result;}#function imgConvert end/*#涵式說明:#取得虛擬硬碟的資訊與檢查是否被使用中#回傳結果:#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.#$result["error"],錯誤訊息.#$result["function"],當前執行的函數名稱.#$result["argu"],所使用的參數.#$result["used"],是否被使用中,"true"代表有;"false"代表沒有.#$result["image"],虛擬硬碟的路徑與名稱.#$result["file format"],虛擬硬碟的格式.#$result["virtual size"],虛擬硬碟實際可以儲存的最大容量.#$result["disk size"],虛擬硬碟檔案所佔的大小.#$result["cluster_size"],佔用空間的最小單位.#必填參數:#$conf["img"],字串,虛擬硬碟檔案的路徑與名稱.#$conf["img"]="";#$conf["fileArgu"],字串,php變數__FILE__的內容,亦即該檔案在檔案系統的絕對路徑#$conf["fileArgu"]=__FILE__;*/public static function imgInfo(&$conf=array()){#初始化要回傳的結果$result=array();#取得當前執行的函數名稱$result["function"]=__FUNCTION__;#如果沒有參數if(func_num_args()==0){#設置執行失敗$result["status"]="false";#設置執行錯誤訊息$result["error"]="函數".$result["function"]."需要參數";#回傳結果return $result;}#if end#涵式說明:#判斷當前環境為web還是cmd#回傳結果:#$result,"web"或"cmd"if(csInformation::getEnv()==="web"){#設置執行失敗$result["status"]="false";#設置執行錯誤訊息$result["error"][]="函數 ".$result["function"]." 僅能在命令列環境下運行!";#回傳結果return $result;}#if end#取得參數$result["argu"]=$conf;#如果 $conf 不為陣列if(gettype($conf)!=="array"){#設置執行失敗$result["status"]="false";#設置執行錯誤訊息$result["error"][]="\$conf變數須為陣列形態";#如果傳入的參數為 nullif($conf===null){#設置執行錯誤訊息$result["error"][]="\$conf變數不得為null,請檢查函數「".$result["function"]."」的參數設置有無正確!";}#if end#回傳結果return $result;}#if end#函式說明:#檢查必填與可省略的參數,可省略參數可指定預設要給與什麼數值內容。#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.#$reuslt["error"],執行不正常結束的錯訊息陣列.#$result["function"],當前執行的函式名稱.#$result["argu"],設置給予的參數.#$result["passed"],識別要檢查的全體變數是否存在以及型態是否正確的變數,"true"代表檢查全部通過;"false"代表檢查不通過#$result[$shouldBeCheckedVarName]["varExist"],所檢查的變數是否存在,"false"代表不存在;"true"代表存在#$result[$shouldBeCheckedVarName]["varType"],所檢查的變數型態是否正確,"false"代表錯誤;"true"代表正確#$result[$shouldBeCheckedVarName]["error"],每個參數設定的錯誤訊息#$result["shouldNotBeEmpty"],不應該為空字串或控陣列的變數.#$result["argu"],字串陣列,目前輸入的參數名稱陣列.#$result["legalVarName"],字串陣列,合法可用的參數名稱陣列.#$result["notNeedVar"],字串陣列,多餘的參數名稱.#必填寫的參數:#$conf["varInput"],陣列變數,要檢查的陣列變數,請在要檢查的參數前面加上&,這樣變動的結果才能被套用。$conf["variableCheck::checkArguments"]["varInput"]=&$conf;#$conf["referenceVarKey"],字串,$conf參數後面的key值,用於移除不要的參考陣列.$conf["variableCheck::checkArguments"]["referenceVarKey"]="variableCheck::checkArguments";#可以省略的參數:#$conf["mustBeFilledVariableName"],爲必填參數的變數名稱陣列,形態爲陣列變數,元素數量需要跟"mustBeFilledVariableType"參數的元素數量一致,例如: $conf["mustBeFilledVariableName"] = array("id","account","password");$conf["variableCheck::checkArguments"]["mustBeFilledVariableName"]=array("img","fileArgu");#$conf["mustBeFilledVariableType"],爲必填參數的變數陣列應該爲何種變數形態,形態爲陣列,元素數量需要跟"mustBeFilledVariableName"參數的元素數量一致,例如: $conf["mustBeFilledVariableType"] = array("string",integer,"double","resource","object"); , null代表不指定變數形態.$conf["variableCheck::checkArguments"]["mustBeFilledVariableType"]=array("string","string");#$conf["canBeEmptyString"],字串,必填變數內容如果是空字串就不能算是有設置的話,請設為"false",預設爲"true",可以為空字串.$conf["variableCheck::checkArguments"]["canBeEmptyString"]="false";#$conf["canNotBeEmpty"],字串陣列,哪些必填參數的內容不得為空字串或空陣列,僅當$conf["canBeEmptyString"]為"true"時會生效.#$conf["canNotBeEmpty"]=array();#$conf["canBeEmpty"],字串陣列,哪些必填參數的內容可為空字串或空陣列,僅當$conf["canBeEmptyString"]為"false"時會生效.#$conf["canBeEmpty"]=array();#$conf["skipableVariableCanNotBeEmpty"],字串陣列,哪些可省略參數不可以為空字串或空陣列.#$conf["skipableVariableCanNotBeEmpty"]=array();#$conf["skipableVariableName"],陣列字串,爲可省略參數的變數名稱陣列,形態爲陣列變數,例如: $conf["skipableVariableName"] = array("id","account","password");#$conf["skipableVariableName"]=array();#$conf["skipableVariableType"],陣列字串,爲可省略參數的變數名稱陣列,形態爲陣列變數,例如: $conf["skipableVariableType"] = array("string",integer,"double");#$conf["skipableVariableType"]=array();#$conf["skipableVarDefaultValue"],字串陣列,每個不存在的可省略變數要初始化為什麼,null與代表不指定,若預設值是參數之一,請將$conf["mustBeFilledVar"]改成"\$conf["\mustBeFilledVar\"]".#$conf["skipableVarDefaultValue"]=array("");#$conf["disallowAllSkipableVarIsEmpty"],字串,是否允許每個可省略參數都為空字串,預設為"true"允許,反之為"false".#$conf["disallowAllSkipableVarIsEmpty"]="";#$conf["disallowAllSkipableVarIsEmptyArray"],字串,是否允許每個可省略參數都為空陣列,預設為"true"允許,反之為"false".#$conf["disallowAllSkipableVarIsEmptyArray"]="";#$conf["arrayCountEqualCheck"],字串陣列,為檢查哪些陣列參數的元素數量要一樣,$conf["arrayCountEqualCheck"][$i]=array()為第$i組key為哪些的變數其元素數量要相等.#$conf["arrayCountEqualCheck"][]=array();#參考資料來源:#array_keys=>http://php.net/manual/en/function.array-keys.php$checkArguments=variableCheck::checkArguments($conf["variableCheck::checkArguments"]);unset($conf["variableCheck::checkArguments"]);#如果檢查參數失敗if($checkArguments["status"]==="false"){#設置執行失敗$result["status"]="false";#設置執行失敗訊息$result["error"]=$checkArguments;#回傳結果return $result;}#if end#如果檢查參數不通過if($checkArguments["passed"]==="false"){#設置執行失敗$result["status"]="false";#設置執行失敗訊息$result["error"]=$checkArguments;#回傳結果return $result;}#if end#檢查檔案是否存在#涵式說明:檢查多個檔案與資料夾是否存在.#回傳的結果:#$result["status"],執行正常與否,"true"代表正常,"false"代表不正常.#$result["error"],錯誤訊息陣列.#$resutl["function"],當前執行的涵式名稱.#$result["argu"],使用的參數.#$result["allExist"],所有檔案皆存在的識別,"true"代表皆存在,"false"代表沒有全部都存在.#$result["varName"][$i],爲第$i個資料夾或檔案的路徑與名稱。#$result["varNameFullPath"][$i],爲第$i個資料夾或檔案的完整檔案系統路徑與名稱,如果不存在則代表路徑是網址.#$result["varNameWebPath"][$i],為第$i個資料夾或檔案的網址#$result["varExist"][$i],爲第$i個資料夾或檔案是否存在,"true"代表存在,"false"代表不存在。#必填參數:#$conf["fileArray"],陣列字串,要檢查是否存在的檔案有哪些,須爲一維陣列數值。$conf["fileAccess::checkMultiFileExist"]["fileArray"]=array($conf["img"]);#$conf["fileArgu"],字串,php變數__FILE__的內容,亦即該檔案在檔案系統的絕對路徑$conf["fileAccess::checkMultiFileExist"]["fileArgu"]=$conf["fileArgu"];#可省略參數#$conf["disableWebSearch"],"字串",是否取消「當檔案找不到時,改用catchWebContent類別的wget函數來檢查檔案是否存在於網路上」的功能,"false"不取消,若要取消該功能請設為"true",若抓到的內容為空字串則會視為檔案不存在,預設為"true".#$conf["disableWebSearch"]="false";#$conf["userDir"],字串,網頁是否置放於家目錄底下,"true"為是,"false"為不是,預設為"true".#$conf["userDir"]="true";#參考資料來源:#http://php.net/manual/en/function.file-exists.php#http://php.net/manual/en/control-structures.foreach.php#備註:#函數file_exists檢查的路徑為檔案系統的路徑$checkMultiFileExist=fileAccess::checkMultiFileExist($conf["fileAccess::checkMultiFileExist"]);unset($conf["fileAccess::checkMultiFileExist"]);#如果檢查檔案是否存在失敗if($checkMultiFileExist["status"]==="false"){#設置執行失敗$result["status"]="false";#設置執行失敗訊息$result["error"]=$checkMultiFileExist;#回傳結果return $result;}#if end#如果虛擬硬碟檔案不存在if($checkMultiFileExist["allExist"]==="false"){#設置執行失敗$result["status"]="false";#設置執行失敗訊息$result["error"]=$checkMultiFileExist;#回傳結果return $result;}#if end#用 qemu-img info 參數來檢查虛擬硬碟檔案是否被使用中#涵式說明:#呼叫shell執行系統命令,並取得回傳的內容.#回傳的結果:#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.#$result["error"],錯誤訊息陣列.#$result["function"],當前執行的函數名稱.#$result["argu"],使用的參數.#$result["cmd"],執行的指令內容.#$result["fullCmd"],如果參數 $conf["inBackGround"] 為 "true" 則會回傳該值.#$result["output"],爲執行完二元碼後的輸出陣列,若 $conf["inBackGround"] 為 "true",則為當下的輸出.#$result["tmpFileOutput"],儲存輸出的暫村檔案名稱,若 $conf["inBackGround"] 為 "true" 則會回傳該值.#$result["running"],是否還在執行.#$result["pid"],pid#必填的參數#$conf["command"],字串,要執行的指令與.$conf["external::callShell"]["command"]="qemu-img";#$conf["fileArgu"],字串,變數__FILE__的內容.$conf["external::callShell"]["fileArgu"]=$conf["fileArgu"];#可省略參數:#$conf["argu"],陣列字串,指令搭配的參數,預設為空陣列.$conf["external::callShell"]["argu"]=array("info",$conf["img"],"2>&1");#$conf["arguIsAddr"],陣列字串,指令搭配的哪些參數為路徑,為路徑的參數會進行轉換以便符合呼叫當前函數的位置,預設不指定,若有3個參數,其中第3個參數為路徑,則表示為array("false","false","true").$conf["external::callShell"]["arguIsAddr"]=array("false","true","false");#$conf["pre"],陣列,要在本指令前執行的每個指令與參數.#$conf["pre"][$i]["cmd"],字串,要在本指令前執行的第$i+1個指令.#$conf["pre"][$i]["param"],陣列字串,要在本指令前執行的第$i+1個指令的參數.#$conf["enablePrintDescription"],字串,是否要印出$conf["printDescription"]的內容,"true"代表要,"false"代表不要,預設為"false".#$conf["enablePrintDescription"]="true";#$conf["printDescription"],字串,執行該外部程式前要印出來的的文字,預設為$conf["command"]的內容.#$conf["printDescription"]="";#$conf["escapeshellarg"],字串,是否要啟用過濾參數,用了比較安全,但可能會出錯,"true"為啟用,"false"為不啟用,預設為"false".$conf["external::callShell"]["escapeshellarg"]="true";#$conf["username"],字串,要用什麼使用者來執行,預設為執行php的使用者,該參數不適用於apache環境.#$conf["username"]="";#$conf["password"],字串,與$conf["username"]搭配的使用者密碼,預設不使用密碼,該參數不適用於apache環境.#$conf["password"]="";#$conf["useScript"],字串,是否要啟用Linux的script指令來記錄輸出,"true"代表要,Fedora的selinux會擋住該操作;"false"代表不要,預設為"false".#$conf["useScript"]="";#$conf["logFilePath"],字串,當 $conf["useScript"] 為 "true" 時,輸出的內容要暫存到哪裡,預設為 "/tmp/.qbpwcf_tmp/external/callShell/".#$conf["logFilePath"]=".qbpwcf_tmp/external/callShell/";#$conf["inBackGround"],字串,是否要在背景執行,且不會等待程式執行結束再執行下一個指令,"true"代表是,"false"代表不要,預設為"false",如果$conf["command"]有用「;」區隔的多個指令將會出錯.#$conf["inBackGround"]="";#備註:#不是所有指令都能用apache的身份執行,目前已知java,javac指令無法執行,使用root身份可能會被selinux阻擋.#參考資料:#exec=>http://php.net/manual/en/function.exec.php#escapeshellcmd=>http://php.net/manual/en/function.escapeshellcmd.php#escapeshellarg=>http://php.net/manual/en/function.escapeshellarg.php$callShell=external::callShell($conf["external::callShell"]);unset($conf["external::callShell"]);#設置檔案未被使用中$result["used"]="false";#如果運行失敗if($callShell["status"]==="false"){/*#desc:虛擬硬碟被使用中的範例輸入與輸出.#input:qemu-img info test.qocw2#output:qemu-img: Could not open 'test.qocw2': Failed to get shared "write" lockIs another process using the image?*/#如果輸出的內容為兩列if(count($callShell["error"][1])===2){#如果輸出的內容為被使用中if(strpos($callShell["error"][1][0],"qemu-img: Could not open '".$conf["img"]."': Failed to get shared \"write\" lock")===0&&strpos($callShell["error"][1][1],"Is another process using the image?")===0){#設置檔案被使用中$result["used"]="true";#設置執行正常$result["status"]="true";#回傳結果return $result;}#if end}#if end#設置執行失敗$result["status"]="false";#設置執行失敗訊息$result["error"]=$callShell;#回傳結果return $result;}#if end/*#desc:虛擬硬碟沒被使用中的範例輸出.image: win10-working-教育版.qcow2file format: qcow2virtual size: 100G (107374182400 bytes)disk size: 73Gcluster_size: 65536Format specific information:compat: 1.1lazy refcounts: falserefcount bits: 16corrupt: false*/#如果輸出大於6行if( count($callShell["output"]) > 6 ){#針對每行輸出foreach($callShell["output"] as $line){#涵式說明:#將固定格式的字串分開,並回傳分開的結果。#回傳結果:#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.#$result["error"],錯誤訊息陣列#$result["function"],當前執行的函數名稱.#$result["oriStr"],要分割的原始字串內容#$result["dataArray"],爲分割好字串的陣列內容,$result["dataArray"][$i]爲第($i+1)段的內容。#$result["dataCounts"],爲總共分成幾段#$result["found"],是否有在$conf["stringIn"]找到$conf["spiltSymbol"],"true"代表有找到,"false"代表沒有找到.#必填的參數:$conf["stringProcess::spiltString"]["stringIn"]=$line;#要處理的字串。$conf["stringProcess::spiltString"]["spiltSymbol"]=": ";#爲以哪個符號作爲分割#可省略參數:#$conf["allowEmptyStr"],是否允許分割出來空字串,預設為"false"不允許;"true"代表允許.$conf["stringProcess::spiltString"]["allowEmptyStr"]="false";$spiltString=stringProcess::spiltString($conf["stringProcess::spiltString"]);unset($conf["stringProcess::spiltString"]);#如果分割失敗if($spiltString["status"]==="false"){#設置執行失敗$result["status"]="false";#設置執行失敗訊息$result["error"]=$spiltString;#回傳結果return $result;}#if end#如果沒有找到分割的關鍵字if($spiltString["found"]==="false" && $spiltString["dataCounts"]!==1){#設置執行失敗$result["status"]="false";#設置執行失敗訊息$result["error"]=$spiltString;#回傳結果return $result;}#if end#如果沒有分割成兩分if($spiltString["dataCounts"]!==2){#跳過continue;}#if end#取得虛擬硬碟的資訊$result[$spiltString["dataArray"][0]]=$spiltString["dataArray"][1];}#foreach end}#if end#取得虛擬硬碟的資訊$result["content"]=$callShell["output"];#設置執行正常$result["status"]="true";#回傳結果return $result;}#function imgInfo end}#class qemu end?>