unity3d開發時,用PHP作為后台是個不錯的選擇。對一些數據吞吐量不是很大的游戲,比如某個游戲的排名,登錄等等,一般的php程序能夠勝任了,並且php語言簡單,開發容易對數據庫尤其是mysql的支持良好,我們還可以通過php對接一些SDK(比如推送)作為unity3d的中轉站。基於以上原因我們完全有理由使用php作為游戲后台。而對於數據吞吐量適中的游戲我們還可以,使用php編寫websocket進行更實時的交互通訊(這里我們討論websocket的情況,有空我再另寫一遍來討論).下面我們來看看unity3d和php的簡單交互。
- unity3d通過get方式請求php.
get方式請求php比較簡單,就是在url里面加上要傳遞的參數就可以了。客戶端代碼:
using UnityEngine; using System.Collections; public class phpUnity2 : MonoBehaviour { private string url = "http://localhost:8081/phptest/phpunity2.php?id=1100001&cid=1200001"; //帶get參數id和cid的url void OnGUI() { if (GUILayout.Button("get php")) { StartCoroutine(OnGet()); } } IEnumerator OnGet() { WWW www = new WWW(url); yield return www; if (www.error != null) { print("php請求錯誤: 代碼為" + www.error); } else { print("php請求成功" + www.text); } } }
新建一個c# script貼上以上代碼,並把它附加到Main Camera中。
php代碼:
<?php /**************************************************************************** * 作者: * 日期: 2016-09-12 * 版本: v1.0 * 說明: 測試 ****************************************************************************/ include_once "dbconfig.php"; if(isset($_GET["id"]) && isset($_GET["cid"])) { echo "get請求成功,id值為:".$_GET["id"].",cid值為:".$_GET["cid"]; } ?>
新建一個php文件貼上以上代碼,運行unity3d將會看到以下結果。
- unity3d通過post方式請求php.
unity3d post方式請求php我們要通過WWWForm類來構造一個表單字段。
客戶端代碼
using UnityEngine; using System.Collections; public class phpUnity1 : MonoBehaviour { private string url = "http://localhost:8081/phptest/phpunity1.php"; // void OnGUI() { if (GUILayout.Button("Post php")) { StartCoroutine(OnGet()); } } IEnumerator OnGet() { //表單 WWWForm form = new WWWForm(); form.AddField("id", 1100001); form.AddField("cid", 1100001); WWW www = new WWW(url, form); yield return www; if (www.error != null) { print("php請求錯誤: 代碼為" + www.error); } else { print("php請求成功" + www.text); } } }
php代碼
<?php /**************************************************************************** * 作者: * 日期: 2016-09-12 * 版本: v1.0 * 說明: 測試 ****************************************************************************/ include_once "dbconfig.php"; if(isset($_POST["id"]) && isset($_POST["cid"])) { echo "post請求成功,id值為:".$_POST["id"].",cid值為:".$_POST["cid"]; } ?>
運行unity3d可以看到以下結果.
- unity3d和php后台通訊實例
通過上面的討論我們了解了unity3d和php的簡單交互了,現在我們來實現一個unity3d登錄的例子.
我們先用ugui簡單的做一個登錄界面,
這里我們為了以后使用方便封裝了一個Extension擴展類和Common公共類
Common.cs:
using UnityEngine; using System.Collections; using System.Security.Cryptography; using System; namespace Commons { /// <summary> /// 擴展類 /// </summary> public static class Extension { /// <summary> /// 判斷字符是否為空 /// </summary> /// <param name="str"></param> /// <returns></returns> public static bool isEmpty(this string str) { if(str.Equals("")) { return true; } else { return false; } } } public class Common { /// <summary> /// 對字符進行MD5加密 /// </summary> /// <param name="str"></param> /// <returns></returns> public static string StrEncrypMd5(string str) { if (str == null) { return "加密字符不能為空"; } MD5 md5 = new MD5CryptoServiceProvider(); byte[] bytRes = System.Text.Encoding.Default.GetBytes(str); ; byte[] targetData = md5.ComputeHash(bytRes); string byte2String = BitConverter.ToString(targetData).Replace("-", ""); ; return byte2String.ToLower(); } } }
客戶端代碼:
using UnityEngine; using UnityEngine.UI; using System.Collections; using Commons; public class login : MonoBehaviour { public InputField userIdField; public InputField passwordField; public Text statusText; private string userId = ""; private string password = ""; private string url = "http://localhost:8081/phptest/login.php"; void OnLogin() { userId = userIdField.text; password = passwordField.text; if (userId.isEmpty() || password.isEmpty()) { print("賬戶和密碼不能為空"); return; } StartCoroutine(logining()); } private IEnumerator logining() { WWWForm form = new WWWForm(); form.AddField("userId", userId); form.AddField("password", Common.StrEncrypMd5(Common.StrEncrypMd5(password))); //雙重加密,由於md5的 WWW www = new WWW(url, form); yield return www; if (www.error != null) { print("error is login:" + www.error); statusText.text = www.error + "..."; } else { print(www.text); statusText.text = www.text; } } }
在MySQL建一個測試的數據表:
DROP TABLE IF EXISTS `tb1`; CREATE TABLE `tb1` ( `userid` varchar(30) NOT NULL, `password` varchar(50) NOT NULL, PRIMARY KEY (`userid`) ) ENGINE=InnoDB DEFAULT CHARSET=latin1; -- ---------------------------- -- Records of tb1 -- ---------------------------- INSERT INTO `tb1` VALUES ('100001', '123456'); INSERT INTO `tb1` VALUES ('100002', '123456'); INSERT INTO `tb1` VALUES ('100003', '123456'); INSERT INTO `tb1` VALUES ('100004', '123456');
PHP端代碼:
為了操作方便我封裝了一個common.php文件和一個dbconfig數據庫操作類
common.php<?php /**************************************************************************** * 作者: * 日期: 2016-09-12 * 版本: v1.0 * 說明: 公共函數 ****************************************************************************/ define("DEBUG", "FALSE"); header("Content-Type: text/html;charset=utf-8"); /* * 說明: 調式函數 */ function debug_trace($_msg) { if(defined("DEBUG")) { if(DEBUG == "TRUE") { echo($_msg); } } } ?>
dbconfig.php
<?php /**************************************************************************** * 作者: * 日期: 2016-09-12 * 版本: v1.0 * 說明: 對數據庫的封裝 ****************************************************************************/ include_once("common.php"); class dbconfig{ //構造函數 function __construct() { if(!$this->mysqli = mysqli_connect($this->host, $this->user, $this->pwd)) { die("Cant connect into database"); } else { debug_trace("連接數據庫成功...<br />"); } $this->select_db($this->db_name); } //析構函數 function __destruct() { mysqli_close($this->mysqli); } /* * 說明: */ public function get_mysql_handle() { return $this->mysqli; } /* * 說明: */ public function select_db($_db) { if($this->mysqli != null) { if(mysqli_select_db($this->mysqli, $_db)) { debug_trace("選擇數據庫成功...<br />"); } else { die("Cant connect into database"); } } } /* * 說明: 執行一個sql無返回值 */ public function execute($_sql) { if(empty($_sql)) { echo "參數不能為空"; return; } if(!mysqli_query($this->mysqli, $_sql)) { debug_trace("執行失敗...<br />"); } } /* * 說明: 執行一個查詢語句,並執行回調函數 */ public function do_query($_sql, $query_callback = "") { if(empty($_sql)) { debug_trace("參數不能為空"); return; } if($result = mysqli_query($this->mysqli, $_sql)) { $num_rows = $result->num_rows; if($num_rows > 0) { while($row = $result->fetch_assoc()) { if(!empty($query_callback)) { call_user_func( $query_callback , $row ); } } return $num_rows; } else { return 0; } mysqli_free_result($result); } else { debug_trace("執行失敗...<br />"); } } //成員變量 private $host = "localhost"; //數據庫地址 private $user = "root"; //用戶名 private $pwd = ""; //用戶密碼 private $db_name = "test"; //數據庫 private $mysqli = null; } ?>
登錄的后台login.php:
<?php /**************************************************************************** * 作者: * 日期: 2016-09-12 * 版本: v1.0 * 說明: 測試 ****************************************************************************/ include_once "dbconfig.php"; $dbcfg = new dbconfig(); $password_md5 = ""; if(isset($_POST["userId"]) && isset($_POST["password"])) { $password = $_POST["password"]; $sql = "select * from tb1 where code='".$_POST['userId']."'"; if($dbcfg->do_query($sql, "login_callback") > 0) { if(md5(md5($password_md5)) == $password) { echo "登錄成功..."; } else { echo "登錄失敗1..."; } } else { echo "登錄失敗2..."; } } function login_callback($row) { global $password_md5; $password_md5 = $row["name"]; } ?>
運行unity3d可以看到以下結果:
好了對於unity3d和php的簡單交互我們就談論到這里,在實際的開發中我們可能通過xml,json向php發送數,我會另外寫一遍來討論。寫的不好,請大家多多指正。