在前一篇文章我們已經(jīng)導(dǎo)入使用THinkphp并且測(cè)試了一個(gè)登錄接口,那么這篇文章,我們就來(lái)正兒八經(jīng)的寫(xiě)注冊(cè)和登錄接口啦。
1.注冊(cè)(LoginController.class.php)
我們用LoginController作為用戶管理類,所以注冊(cè)接口也寫(xiě)在其中
那么我們習(xí)慣在寫(xiě)接口的時(shí)候,把相關(guān)信息寫(xiě)在注釋里
/* -------------------------------------------------------------
* 用戶注冊(cè)接口
* URL地址:Home/Login/register
* 方法:POST
* 參數(shù)1:name(用戶名)(String)(必填字段)(示例:admin)
* 參數(shù)2:pass(密碼)(String)(必填字段)(示例:admin)
* 參數(shù)3:sign(個(gè)性簽名)(String)(必填字段)(示例:這個(gè)人太懶,沒(méi)有個(gè)簽)
* 參數(shù)4:face(頭像)(File,jpg,png,ipeg)(必填字段)(示例:jpg,png,ipeg)
* 返回:json{jcode,jmsg.jdata.jmore}
* 字段說(shuō)明:200注冊(cè)成功,400注冊(cè)失敗
* --------------------------------------------------------------
* */
public function register(){
//默認(rèn)數(shù)據(jù)
$res = normal_json();
//接收post數(shù)據(jù),判斷正確后,并且創(chuàng)建數(shù)組
$data['name'] = I('post.name');
$data['pass'] = I('post.pass');
$data['sign'] = I('post.sign');
if($data['name'] && $data['pass']&&$data['sign']){
//上傳頭像
$up = new Upload(); //對(duì)象
$up->maxSize = 315728; //大小
$up->exts = array('jpg','png','jpeg'); //種類
$up->savePath = '/Image/Head/'; //path
$info = $up->upload();
if(!$info){
$res['jcode'] = 400;
$res['jmsg'] = 'head upload error'.$up->getError();
}else{
foreach ($info as $file){
//加載照片地址
$data['face'] = $file['savepath'].$file['savename'];
}
//在model類里處理數(shù)據(jù)
$res = M('\Home\Model\LoginModel:'.self::Customer_Table)->Register($data);
}
}else{
$res['jcode'] = 400;
$res['jmsg'] = "There is some empty field";
}
e_json($res);
}
看起來(lái)很簡(jiǎn)單的樣子,其實(shí)就是接受一些數(shù)據(jù),字符串的話直接交給LoginModel處理(注意這里的用戶表就要換上了self::Customer_Table,我在這里定義了一個(gè)常量),頭像的話,直接交給upload類來(lái)管理,處理完成返回圖像儲(chǔ)存地址,我們?cè)贚oginModel里定義了同名方法,用于操作數(shù)據(jù)庫(kù)
/*注冊(cè)*/
public function Register($data) {
//默認(rèn)json數(shù)據(jù)
$res = normal_json();
//查詢用戶;
$dlist = $this ->where("name='%s'",$data['name']) ->find();
//如果找到,說(shuō)明已經(jīng)有重名用戶
if($dlist){
//用戶存在
$r['jcode'] = 404;
$r['jmsg'] = 'User name already exists';
}else {
//密碼加密
$data['pass'] = md6($data['pass']);
//添加日期
$data['crtime'] = date('Y-m-d H:i:s');
//默認(rèn)更新日期0000
$data['uptime'] = '0000';
//開(kāi)始添加
if ($this->add($data)){
$r['jcode'] = 200;
$r['jmsg'] = 'register was success';
}else{
$r['jcode'] = 404;
$r['jmsg'] = 'Operation database failed';
}
}
//返回$r
return $r;
}
這里主要用到了thinkphp的CURD操作中的add方法,用于添加新用戶數(shù)據(jù),然后根據(jù)具體的操作情況來(lái)返回值,最后在controller 里面返回json
根據(jù)我們的文檔填寫(xiě)必須要的參數(shù),和正確的接口地址,發(fā)送之后可以得到j(luò)son串和提示信息,當(dāng)然你可以根據(jù)能接受的錯(cuò)誤來(lái)進(jìn)行測(cè)試,比如說(shuō)少個(gè)參數(shù),file格式不對(duì)等,全方面的檢查系統(tǒng)的容錯(cuò)能力,這里我就不演示了,我們可以看一下數(shù)據(jù)庫(kù)
Ok已經(jīng)有了本條數(shù)據(jù)了。那么我們的注冊(cè)邏輯也算到這。
2.登錄(LoginController.class.php)
登錄在上一篇文章寫(xiě)過(guò),但是這次的登錄做了一些修改,所以還是貼代碼。
/* -------------------------------------------------------------
* 用戶登錄接口
* URL地址:Home/Login/login
* 方法:POST
* 參數(shù)1:name(用戶名)(String)(必填字段)(示例:admin)
* 參數(shù)2:pass(密碼)(String)(必填字段)(示例:admin)
* 返回:json
* --------------------------------------------------------------
* */
public function login(){
//接受I方法的post數(shù)據(jù),執(zhí)行customer的login方法,返回json數(shù)據(jù)
e_json(M('\Home\Model\LoginModel:'.self::Customer_Table)->Login(I('post.name'), I('post.pass')));
}
那么在LoginModel里coding我們的同名方法
/*登錄*/
public function Login($name, $pass) {
//默認(rèn)json數(shù)據(jù)
$res = normal_json();
//查詢用戶
$map['name'] = $name;
//找到的信息
$dlist = $this ->where( $map) ->find();
//如果找到,進(jìn)行加密比較
if( $dlist){
if( $dlist['pass'] == md6($pass)) {
$r['jcode'] = 200;
$r['jmsg'] = 'Login verification through';
}else {
//密碼錯(cuò)誤
$r['jcode'] = 400;
$r['jmsg'] = 'User name or password entered error';
}
}else {
//未注冊(cè)
$r['jcode'] = 404;
$r['jmsg'] = 'User name not registered';
}
//返回$r
return $r;
}
這里主要是CURD的查找操作,使用where( $map) ->find()查詢數(shù)據(jù),很常見(jiàn),那么剩下的就是if else的一些提示信息了。
那么我們用小白用戶來(lái)測(cè)試一下
可以看到200的狀態(tài)。
當(dāng)我們修改錯(cuò)誤密碼的時(shí)候,可以看到400的狀態(tài)
3.修改用戶信息(除用戶名及頭像)(LoginController.class.php)
這里單獨(dú)分離一個(gè)方法用于修改用戶信息,但是我們規(guī)定用戶名不能隨便改,其實(shí)不太現(xiàn)實(shí),但是可以改的話也并沒(méi)有什么難度,這里只是想以用戶名作為用戶唯一標(biāo)志,實(shí)際情況中,可以以手機(jī)號(hào)作為唯一標(biāo)識(shí)等。
那么看一下這個(gè)方法
/* -------------------------------------------------------------
* 更新用戶信息接口(除頭像)
* URL地址:Home/Login/updateCustomerInfo
* 方法:POST
* 參數(shù)1:name(用戶名)(String)(必填,用于匹配用戶)(示例:admin)
* 參數(shù)2:pass(原密碼)(String)(選填)(示例:admin)
* 參數(shù)2:new_pass(新密碼)(String)(原密碼填寫(xiě)時(shí)本項(xiàng)必填)(示例:admin)
* 參數(shù)3:sign(個(gè)性簽名)(String)(選填)(示例:這個(gè)人太懶,沒(méi)有個(gè)簽)
* 返回:json{jcode,jmsg.jdata.jmore}
* 字段說(shuō)明:200更新成功,400更新失敗
* --------------------------------------------------------------
* */
public function updateCustomerInfo(){
//默認(rèn)數(shù)據(jù)
$res = normal_json();
//接收post數(shù)據(jù),判斷正確后,并且創(chuàng)建數(shù)組
$data['pass'] = I('post.pass');
$data['new_pass'] = I('post.new_pass');
$data['sign'] = I('post.sign');
$data['name'] = I('post.name');
$res = M('\Home\Model\LoginModel:'.self::Customer_Table)->UpdateCustomerInfo($data,$data['name']);
e_json($res);
}
將數(shù)據(jù)封裝在數(shù)組里傳遞給loginmodel,同樣我們看一下loginmodel的同名方法
/*更新用戶信息(除頭像)*/
public function UpdateCustomerInfo($data,$name){
$r = normal_json();
$data['name'] = $name;
if($data['pass']&&$data['new_pass']){
//更新密碼
//檢驗(yàn)舊密碼是否合法
if($data['pass'] == $data['new_pass']){
$r['jcode'] = 400;
$r['jmsg'] = 'The two password value is equal';
}else{
//建立查詢條件
$map['name'] = $data['name'];
$map['pass'] = md6($data['pass']);
//加密密碼
$data['pass'] = md6($data['new_pass']);
$dlist = $this ->where($map) ->save($data);
if($dlist){
$r['jcode'] = 200;
$r['jmsg'] = 'pass update success';
}else{
$r['jcode'] = 400;
$r['jmsg'] = 'pass update failed';
}
}
}
if($data['sign']){
//更新簽名
$dlist = $this ->where("name='%s'",$name) ->save($data);
if($dlist){
$r['jcode'] = 200;
$r['jmsg'] = 'sign update success';
}else{
$r['jcode'] = 400;
$r['jmsg'] = 'sign update failed';
}
}
return $r;
}
那么這里用到的是$this ->where("name='%s'",$name) ->save($data)這樣的語(yǔ)句來(lái)更新數(shù)據(jù)庫(kù),同樣的也是根據(jù)各種情況返回狀態(tài),我們可以看一下演示。
可以看到我們修改操作也是很順利,那么數(shù)據(jù)庫(kù)也會(huì)更新。
可以看到不僅簽名修改了,更新時(shí)間也會(huì)跟著修改,那么后來(lái)我又添加了一個(gè)注冊(cè)時(shí)間,這個(gè)時(shí)間是不能變化的。
4.修改頭像信息(LoginController.class.php)
那么由于頭像是個(gè)文件,那么我們這里單獨(dú)寫(xiě)了一個(gè)方法,修改頭像要考慮的事情還是很多的,其實(shí)在注冊(cè)的時(shí)候可以省略添加頭像的那部分,但是怎么寫(xiě)都一樣,我們暫時(shí)不考慮效率問(wèn)題,
/* -------------------------------------------------------------
* 更新用戶頭像接口
* URL地址:Home/Login/updateHead
* 方法:POST
* 參數(shù)1:face(頭像)(File,jpg,png,ipeg)(必填字段)(示例:jpg,png,ipeg)
* 參數(shù)2:name(用戶名)(String)(必填字段)(示例:admin)
* 返回:json{jcode,jmsg.jdata.jmore}
* 字段說(shuō)明:200更新成功,400更新失敗
* --------------------------------------------------------------
* */
public function updateHead()
{
//默認(rèn)數(shù)據(jù)
$res = normal_json();
$data['name'] = I('post.name');
//上傳頭像
$up = new Upload(); //對(duì)象
$up->maxSize = 315728; //大小
$up->exts = array('jpg', 'png', 'jpeg'); //種類
$up->savePath = '/Image/Head/'; //path
$info = $up->upload();
if (!$info) {
$res['jcode'] = 400;
$res['jmsg'] = 'head upload error' . $up->getError();
} else {
foreach ($info as $file) {
//加載照片地址
$data['face'] = $file['savepath'] . $file['savename'];
}
//在model類里處理數(shù)據(jù)
$res = M('\Home\Model\LoginModel:'.self::Customer_Table)->UpdateHead($data);
}
e_json($res);
}
這里不必多說(shuō),就是使用upload類來(lái)管理上傳,最后獲取上傳后的信息,那么我們來(lái)看一下loginmodel里的同名方法,
可以看到我們不僅寫(xiě)了一個(gè)UpdateHead方法,還有一個(gè)GetHead方法用于獲取原來(lái)的頭像url,當(dāng)我們新頭像url保存成功之后,我們會(huì)使用unlink方法把舊頭像刪除掉,注意參數(shù)(('./Uploads'.$url)最好寫(xiě)成相對(duì)路徑,因?yàn)槲覀冮_(kāi)發(fā)環(huán)境是windows,運(yùn)行環(huán)境是linux,采用相對(duì)路徑會(huì)避免一些錯(cuò)誤
/*更新頭像*/
public function UpdateHead($data){
$r = normal_json();
//獲取頭像鏈接
$url = $this->GetHead($data);
//查詢
$dlist = $this ->where("name='%s'",$data['name'])->save($data);
if($dlist){
//刪除舊頭像
unlink('./Uploads'.$url);
$r['jcode'] = 200;
$r['jmsg'] = 'head update success';
}else{
$r['jcode'] = 400;
$r['jmsg'] = 'head update failed';
}
return $r;
}
/*內(nèi)部方法
* 獲取頭像地址
*/
public function GetHead($data){
//獲取用戶
$dlist = $this ->where("name='%s'",$data['name']) ->find();
if($dlist){
return $dlist['face'];
}else{
return null;
}
}
那么這個(gè)我就不演示了,當(dāng)我們post此接口時(shí),傳遞face照片過(guò)去,服務(wù)器端的舊照片就會(huì)被刪掉,同時(shí)數(shù)據(jù)庫(kù)的url也會(huì)得到更新。
5.文檔
我們可以根據(jù)每個(gè)方法上面的注釋文字,整合成API文檔供前端調(diào)用。
6.Tips
小貼士:當(dāng)你測(cè)試時(shí)候不好觀察結(jié)果時(shí)可以使用Log::record方法記錄日志,通過(guò)Weibo\Runtime\Logs\Home路徑查看日志文件