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发送数,我会另外写一遍来讨论。写的不好,请大家多多指正。