Yii2.0 快速搭建Restful Api教程

Yii2.0 快速搭建Restful Api教程

    • 首先是安装yii2
    • 配置nginx,开启伪静态
    • 配置config/web.php
    • 单独创建API应用
    • 在api中创建目录结构
    • 新建api接口共用日志
    • api接口安全过滤类validator
    • 创建api接口共用类文件
    • 创建api接口入口文件
    • 定义接口入口类
    • 创建获取接口示例
    • 模拟请求接口

首先是安装yii2

使用composer或者源码安装
这是安装Yii2.0的首选方法。如果你还没有安装 Composer,你可以按照这里的说明进行安装。
安装完 Composer,运行下面的命令来安装 Composer Asset 插件:

php composer.phar global require “fxp/composer-asset-plugin:^1.2.0”

安装高级的应用程序模板,运行下面的命令:

php composer.phar create-project yiisoft/yii2-app-advanced advanced 2.0.13

配置nginx,开启伪静态

server {
    listen       80;
    server_name  api.yii2.com;
    rewrite_log  on;
    root   /usr/share/nginx/html/yii2/web;   
    access_log  /var/log/nginx/yii2.access.log  main;
    location / {
        index  index.php index.html index.htm;
        if (!-e $request_filename){
        rewrite ^/(.*) /index.php?r=$1 last;
        }
    }

    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root   /usr/share/nginx/html;
    }

    location ~ \.php$ {
        root           /usr/share/nginx/html/yii2/web;
        fastcgi_pass   127.0.0.1:9000;
        fastcgi_index  index.php;
        fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;
        include        fastcgi_params;
    }

  
}

配置config/web.php

if (YII_ENV_DEV) {
	//加入以下代码	
    $config['bootstrap'][] = 'api';
    $config['modules']['api'] = [
        'class' => 'app\api\api',
    ];
}

单独创建API应用

单独创建API应用,目的是便于维护,可以避免以下问题

配置的冲突
控制器的命名不便
url美化规则冲突
分工明确index为前台目录;admin为后台目录;api为api接口目录

在yii2根目录下创建目录:api
Yii2.0 快速搭建Restful Api教程_第1张图片
在api目录创建api.php 内容如下:


<?php

namespace app\api;


/**
 * admin module definition class
 */
class api extends \yii\base\Module
{
    /**
     * @inheritdoc
     */
    public $controllerNamespace = 'app\api\controllers';

    /**
     * @inheritdoc
     */
    public function init()
    {
        parent::init();

        // custom initialization code goes here
    }
}


在api中创建目录结构

Yii2.0 快速搭建Restful Api教程_第2张图片

configs 存放api接口配置文件
controller 存放api接口入口文件
logs 存放api接口日志目录
modules 存放api接口各个模块

新建api接口共用日志

新建日志函数:
在api\modules\common\log.php 内容如下:

<?php
namespace app\api\modules\common;
class log
{
    public static function writeLog($data,$dir='')
    {
        $dir_path = __DIR__ .'/../../logs/';
        if($dir){
            $dir_path .= ltrim($dir,'/');
        }
        if (!is_dir($dir_path)) {
            mkdir($dir_path, 0777, true);
        }
        $filepath = rtrim($dir_path,'/') . '/' . date("Ymd") . '.log';
        $delimiter_start = "\n+---------------------------- log start -----------------------------+\n记录时间:" . date("Y-m-d H:i:s") . "\n";
        $delimiter_end = "\n+---------------------------- log end -----------------------------+\n";
        file_put_contents($filepath, $delimiter_start . json_encode($data, JSON_UNESCAPED_UNICODE) . $delimiter_end, FILE_APPEND);
    }
}

api接口安全过滤类validator

在yii2\api\modules\common\validator.php内容如下:

<?php

namespace app\api\modules\common;
/**
 * Class Validator
 * @package app\api\modules\common
 * @name 安全过滤类
 * @name 徊忆羽菲
 */
class validator
{
    /**
     * 安全过滤
     * @param string $str
     * @return string
     */
    private static function clean($str)
    {
        return addslashes(self::_xssClean($str));
    }


    public static function cleanXss($params)
    {
        foreach ($params as $k => &$v) {
            if($v){
                if(is_string($v)){
                    $v = self::clean($v);
                }
            }
        }
        return $params;
    }

    /**
     * 去掉js和html
     *
     * @param string $str
     * @return string
     */
    private static function _xssClean($str)
    {
        //$str = trim($str);
        if (strlen($str) <= 0)
            return $str;
        return @preg_replace(self::$_search, self::$_replace, $str);
    }


    /**
     * seperator
     *
     * @var string
     */
    private static $_sep = ':';

    /**
     * js && html reg
     *
     * @var array
     */
    private static $_search = array(
        "']*?>.*?'si",            // 去掉 javascript
        /*        "'<[\/\!]*?[^<>]*?>'si",          			// 去掉 HTML 标记*/
        "'([\r\n])[\s]+'",                            // 去掉空白字符
        "'&(quot|#34);'i",                            // 替换 HTML 实体
        "'&(amp|#38);'i",
        "'&(lt|#60);'i",
        "'&(gt|#62);'i",
        "'&(nbsp|#160);'i"
    );

    /**
     * replace reg
     *
     * @var array
     */
    private static $_replace = array(
        '',
//        '',
        "\\1",
        "\"",
        "&",
        "<",
        ">",
        ''
    );
}

创建api接口共用类文件

在Controller目录yii2\api\controllers\CommonController.php
具体内容如下:

<?php
namespace app\api\controllers;
/**
 * 徊忆
 */
use app\api\modules\common\log;
use yii\web\Controller;
use Yii;

class CommonController extends Controller
{
    protected static $_res = array('status' => 0, 'msg' => 'success', 'data' => []);
    public $enableCsrfValidation = false;
    protected static $redisExpiration = 0;
    protected static $filterInterface = ['user.phonelogin', 'user.phoneverify', 'user.login'];
    protected static $post=[];
    protected static $globalConfig=[];



    public function init()
    {

       self::$globalConfig = require Yii::$app->basePath . '/api/configs/globalConfig.php';

       // self::$global=require_once (__DIR__.'/../configs/globalConfig.release.php');

        // self::$post=$_POST;
        self::$post=json_decode(Yii::$app->request->getRawBody(),true);
    }
    protected function getSign($params){
        unset($params['sign']);
        ksort($params);
        $str='';
        foreach($params as $k => $v){
            $str.= $k.$v;
        }
        return md5($str);
    }

    //把请求发送到微信服务器换取二维码
    public static function httpRequest($url, $data = '', $method = 'GET')
    {
        $curl = curl_init();
        curl_setopt($curl, CURLOPT_URL, $url);
        curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, 0);
        curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, 0);
        curl_setopt($curl, CURLOPT_USERAGENT, $_SERVER['HTTP_USER_AGENT']);
        curl_setopt($curl, CURLOPT_FOLLOWLOCATION, 1);
        curl_setopt($curl, CURLOPT_AUTOREFERER, 1);
        if ($method == 'POST') {
            curl_setopt($curl, CURLOPT_POST, 1);
            if ($data != '') {
                curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
            }
        }
        curl_setopt($curl, CURLOPT_TIMEOUT, 30);
        curl_setopt($curl, CURLOPT_HEADER, 0);
        curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
        $result = curl_exec($curl);
        curl_close($curl);
        return $result;
    }
}

创建api接口入口文件

在Controller目录yii2\api\controllers\IndexController.php
具体内容如下:


<?php
namespace app\api\controllers;
use yii\db\Exception;
use Yii;
use app\api\modules\common\validator;
use app\api\modules\common\log;
class IndexController extends CommonController
{
    public function init(){
        return parent::init();
    }

    public function actionIndex(){
        try{


            if(!Yii::$app->request->isPost){
                throw new Exception('非正常请求来源!');
            }


            //过滤Xss并验证post参数是否合法
            $post=$this->validate(validator::cleanXss(self::$post));


            $InterfaceConfig=require_once (__DIR__.'/../configs/interface.php');
            $api=$post['m'].'.'.$post['c'];
            //将请求的具体哪个接口写入日志文件中
            log::writeLog($api);
            //将请求的内容写入日志文件中
            log::writeLog($post);
          
            //查询类是否存在
            if(!array_key_exists($api,$InterfaceConfig)){
                throw new Exception('该方法不存在,请重试!');
            }
            //定义命名空间地址
            define('API_CLASS','app\\api\\modules\\'.str_replace('/','\\',$InterfaceConfig[$api]['file']));
            //类文件如果存在就自动引入
            if(!class_exists(API_CLASS,true)){
                throw new Exception('该namespace下不存在指定类,请检查!');
            }
//            //动态分配命名空间及类下的方法
            $result=call_user_func(API_CLASS .'::'.'run',$post);

            if(!$result){
                throw new Exception('网络原因,请求失败,请稍后重试!');
            }
            if($result['status']!==0){
                throw new Exception($result['msg']);
            }
            self::$_res['data']=$result['data'];
        }catch(Exception $e){
            self::$_res['status']=1;
            self::$_res['msg']=$e->getMessage();
        }
        return json_encode(self::$_res);
    }

    /**
     * 参数验证
     */
    public function validate($post){
        //提交过来的是json格式的,所以需要转成数组
        if(!(isset($post['m']) && !empty($post['m'])) || !(isset($post['c']) && !empty($post['c']))){
            throw new Exception('参数缺失!');
        }
        return $post;
    }
}

定义接口入口类

在目录yii2\api\configs\interface.php


<?php
/**
 * 定义接口入口
 * @author guoqiangqiang
 */
return [
    'baidu.index' => ['file' => 'baidu/index', 'class' => 'index'],//获取baidu信息接口
];


创建获取接口示例


Yii2.0 快速搭建Restful Api教程_第3张图片
接口内容如下:


<?php

namespace app\api\modules\baidu;

use app\api\modules\common\common;
use app\api\modules\common\log;

use Yii;
use yii\db\Exception;

/**
 * 百度信息接口
 * Class Login
 */
class index extends common{

    public static function run($post){
        try{
            if(!$post['member_name'] || !$post['member_phone'] ){
                throw new Exception('参数验证失败!');
            }


            $member_name=$post['member_name'];
            $member_phone=$post['member_phone'];
            if(!empty($member_name) && !empty($member_phone)){

                $data=array(
                    'user_age'=>18,
                    'user_sex'=>'男',
                );

            }else{
                throw new Exception('查无此用户信息!');
            }

            log::writeLog("打印返回的数据:".json_encode($data,JSON_UNESCAPED_UNICODE));
            self::$result['data']=$data ? : [];

        }catch(Exception $e){
            self::$result['status']=1;
            $msg=$e->getMessage();
            $str_sql="SQLSTATE";
            if(strpos($msg,$str_sql) !== false){
                self::$result['msg'] = "获取用户信息失败,点击左上角返回稍后再试!";
            }else{
                self::$result['msg'] = $e->getMessage();
            }

        }
        return self::$result;
    }


}

模拟请求接口

在本地apache或nginx环境下,创建文件yiiapi.php具体内容如下:

<?php
session_start(); // 初始化session
class Api{


    public $url= "http://api.yii2.com/api/index/index";


    //post调用接口
    public  function request_post($url = '', $param = '') {
        if (empty($url) || empty($param)) {
            return false;
        }

        $postUrl = $url;
        $curlPost = $param;
        $ch = curl_init();//初始化curl
        curl_setopt($ch, CURLOPT_URL,$postUrl);//抓取指定网页
        curl_setopt($ch, CURLOPT_HEADER, 0);//设置header
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);//要求结果为字符串且输出到屏幕上
        curl_setopt($ch, CURLOPT_POST, 1);//post提交方式
        curl_setopt($ch, CURLOPT_POSTFIELDS, $curlPost);
        $data = curl_exec($ch);//运行curl
        curl_close($ch);

        return $data;
    }


    
    //获取门店列表
        public function memberinfo($member_name,$member_phone){
        //ranking 门店排行
        $post_member=array(
            "m"=>"baidu",
            "c"=>"index",
            "member_name"=>$member_name,
            "member_phone"=>$member_phone
        );

        return $data=$this->request_post($this->url,json_encode($post_member));
    }


}



    $api = new Api();
    


	$member_name="qiangqiang"; //用户姓名
    $member_phone="12345678912";//用户手机号
	$result=$api->memberinfo($member_name,$member_phone);

	echo "
";
	print_r($result);
	
?>


返回如下图:
在这里插入图片描述

你可能感兴趣的:(Php,Yii框架)