用Yii2构建自己的API框架(三、创建api应用)

215 阅读2分钟

提示

本教程相关代码托管在Gitee:gitee.com/toshcn/micr…

在根目录创建api目录

api用作存放接口代码目录

cd micro-hau
mkdir api

api目录结构如下:

api/                            // 接口代码存放目录
    - commponents               // api应用公共的组件存放目录
    - controllers               // api应用公共的控制器类存放目录
        - TestController.php    // 测试控制器
    - config                    // api应用公共的配置存放目录
        - .gitignore            // Git配置文件
        - bootstrap.php         // 应用公共的预配置文件
        - main.php              // api应用的主配置文件
        - main-local.php        // api应用的本地环境配置文件
        - params.php            // api应用的主参数配置文件
        - params-local.php      // api应用的本地环境参数配置文件
    - language                  // api应用的国际化语言翻译对应文件存放目录
    - models                    // api应用的模型类存放目录
    - modules                   // api应用的模块存放目录
        - v1                    // V1模块 api v1版本接口代码存放目录
            - controllers       // V1模块的控制器目录
            - Module.php        // V1模块的类文件
    - runtime                   // api应用运行目录
    - web                       // api应用web入口目录
        - index.php             // api应用入口脚本

设置根别名

在common/config目录下的bootstrap.php文件,在文件追加如下内容:

<?php
Yii::setAlias('@common', dirname(__DIR__));
Yii::setAlias('@api', dirname(dirname(__DIR__)) . '/api'); // 追加的内容

创建main.php主配置文件

在api/config目录下,创建main.php文件,在文件内添加如下内容:

<?php
/**
 * @link https://gitee.com/toshcn/micro-hau
 * @copyright Copyright (c) 2022/4/14 micro-hau
 * @author toshcn <toshcn@foxmail.com>
 */

/**
 * 只api才生效的公共主配置文件 本地配置文件里相同项会覆盖主配置文件里的相同项
 */

// 合并参数
$params = array_merge(
    require __DIR__ . '/../../common/config/params.php',
    require __DIR__ . '/../../common/config/params-local.php',
    require __DIR__ . '/params.php',
    require __DIR__ . '/params-local.php'
);

return [
    'id' => 'micro_hau_api', // 设置应用ID
    'basePath' => dirname(__DIR__), // api应用根目录
    'controllerNamespace' => 'api\controllers', // 配置api应用的控制器命名空间
    'bootstrap' => ['log'], // 引导前就加载日志组件
    // 配置公共组件
    'components' => [
        // 日志组件
        'log' => [
            'traceLevel' => YII_DEBUG ? 3 : 0,
            'targets' => [
                [
                    'class' => 'yii\log\FileTarget',
                    'levels' => ['error', 'warning'],
                ],
            ],
        ],
        // 错误处理组件
        'errorHandler' => [
            'errorAction' => null,
        ],
        // 配置api接收请求组件
        'request' => [
            'csrfParam' => '_csrf-api',
            // 配置api接收JSON数据
            'parsers' => [
                'application/json' => 'yii\web\JsonParser',
            ]
        ],
        // 配置api请求返回组件
        'response' => [
            // 配置api 返回JSON格式
            'format' => \yii\web\Response::FORMAT_JSON
        ],
        // 配置user组件
        'user' => [
            'identityClass' => 'common\models\User', // 使用common/models下的user模型类
            'enableAutoLogin' => false, // 关闭自动登录 api使用token作为用户登录凭证
            'loginUrl' => null, // 登录url 设置为null
            'on afterLogin' => ['common\models\User', 'afterLoginHandler'] // 配置事件登录成功后的处理器
        ],
        // 路由组件
        'urlManager' => [
            'enablePrettyUrl' => true, // 美化路由
            //此属性决定是否开启严格的请求解析 如果设置为true启用,请求的URL必须至少匹配 rules 中的一条规则
            'enableStrictParsing' => false,
            'showScriptName' => false, // false隐藏入口脚本名称
            'rules' => [
                // 配置url规则 如果enableStrictParsing为true 必需配置至少一条路由规则
                // 'login' => 'account/login',
                // 'captcha' => 'account/captcha',
                // 'sms/captcha' => 'sms/captcha'
            ],
        ]
    ],
    // 配置模块
    'modules' => [
        //api v1版本模块
        'v1' => [
            'class' => 'api\modules\v1\Module',
        ],
    ],
    'params' => $params
];

创建main-local.php本地配置文件

在api/config目录下,创建main-local.php文件,在文件内添加如下内容:

<?php
// api应用 本地相关配置项
return [
];

创建params.php公共参数文件

在api/config目录下,创建params.php文件,在文件内添加如下内容:

<?php
return [
];

创建params-local.php本地环境参数文件

在api/config目录下,创建params-locall.php文件,在文件内添加如下内容:

<?php
return [
];

创建v1模块

在api/modules目录下,创建v1目录,并在v1目录内创建Module.php模块类,在Module.php类文件内添加如下内容:

<?php
/**
 * @link https://gitee.com/toshcn/micro-hau
 * @copyright Copyright (c) 2022/4/14 micro-hau
 * @author toshcn <toshcn@foxmail.com>
 */

namespace api\modules\v1;

/**
 * APP Api
 * api v1 module definition class
 */
class Module extends \yii\base\Module
{
    /**
     * 模块的控制器命名空间
     * {@inheritdoc}
     */
    public $controllerNamespace = 'api\modules\v1\controllers';

    /**
     * 模块初始化方法
     * {@inheritdoc}
     */
    public function init()
    {
        parent::init();

        // custom initialization code goes here
    }
}

创建api应用的入口脚本

在api/web下,创建index.php文件,并在文件内添加如下:内容

<?php
/**
 * @link https://gitee.com/toshcn/micro-hau
 * @copyright Copyright (c) 2022/4/14 micro-hau
 * @author toshcn <toshcn@foxmail.com>
 */

// 是否开启debug模式
defined('YII_DEBUG') or define('YII_DEBUG', true);
// 设置环境常量 为dev开发环境 prod为生产环境
defined('YII_ENV') or define('YII_ENV', 'dev');

// 加载composer第三方引导文件
require __DIR__ . '/../../vendor/autoload.php';
// 引入Yii框架
require __DIR__ . '/../../vendor/yiisoft/yii2/Yii.php';
// 公共应用里的引导配置 主要初始化 根别名
require __DIR__ . '/../../common/config/bootstrap.php';
// 当前api应用的引导配置
require __DIR__ . '/../config/bootstrap.php';

$config = yii\helpers\ArrayHelper::merge(
    require __DIR__ . '/../../common/config/main.php',
    require __DIR__ . '/../../common/config/main-local.php',
    require __DIR__ . '/../config/main.php',
    require __DIR__ . '/../config/main-local.php'
);

(new yii\web\Application($config))->run();

一切就序,开始写个测试控制器

在api/controllers下,创建TestController.php文件,并在文件内添加如下内容:

<?php
/**
 * @link https://gitee.com/toshcn/micro-hau
 * @copyright Copyright (c) 2022/4/14 micro-hau
 * @author toshcn <toshcn@foxmail.com>
 */

namespace api\controllers;

use yii\filters\Cors;
use yii\helpers\ArrayHelper;
use yii\rest\Controller;

/**
 * 测试控制器类
 * Class TestController
 * @package api\controllers
 */
class TestController extends Controller
{
    /**
     * 配置控制器行为
     * @return array
     */
    public function behaviors()
    {
        $behaviors = ArrayHelper::merge([
            'corsFilter' => [
                'class' => Cors::class,
                'cors' => [
                    'Origin' => ['*'], // 跨域配置 *允许全部域名
                    // 可过滤请求的动作类型 如: 可配置只允许POST和GET
                    'Access-Control-Request-Methods' => ['POST', 'PUT', 'GET', 'OPTIONS'], 
                    'Access-Control-Request-Headers' => ['*']
                ]
            ]
        ], parent::behaviors());
        // 是否在HTTP头带上目前的速率限制信息
        $behaviors['rateLimiter']['enableRateLimitHeaders'] = false;
        return $behaviors;
    }

    /**
     * 测试动作
     * @return array
     */
    public function actionIndex()
    {
        return [
            'code' => 0,
            'message' => 'success',
            'data' => 'Hello micro-hau'
        ];
    }
}

配置Web服务器

使用Apache
  • 在 Apache 的 httpd.conf 文件或在一个虚拟主机配置文件中使用如下配置。 注意,你应该将 path/to/api/web 替换为实际的 api/web 目录。
# 设置文档根目录为 "api/web"
DocumentRoot "path/to/api/web"

<Directory "path/to/api/web">
    # 开启 mod_rewrite 用于美化 URL
    RewriteEngine on
    # 如果请求的是真实存在的文件或目录,直接访问
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d
    # 如果请求的不是真实文件或目录,分发请求至 index.php
    RewriteRule . index.php

    # 如果UrlManager组件中的 $showScriptName 设为 false , 不允许Url带.php访问
    RewriteRule ^index.php/ - [L,R=404]
    
    # ...其它设置...
</Directory>
使用Niginx
  • 将 PHP 安装为 FPM SAPI 了。 你可以使用如下 Nginx 配置,将 path/to/api/web 替换为实际的 api/web 目录, mysite.local 替换为实际的主机名以提供服务。
server {
    charset utf-8;
    client_max_body_size 128M;
    listen       80;
    server_name  www.mysite.local mysite.local;
    root   "path/to/api/web";
    
    location / {
        index  index.php;
        try_files $uri $uri/ /index.php$is_args$args;
        #autoindex  on;
    }
    location ~ \.php(.*)$ {
        fastcgi_pass   127.0.0.1:9000;
        fastcgi_index  index.php;
        fastcgi_split_path_info  ^((?U).+\.php)(/?.+)$;
        fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;
        fastcgi_param  PATH_INFO  $fastcgi_path_info;
        fastcgi_param  PATH_TRANSLATED  $document_root$fastcgi_path_info;
        include fastcgi_params;
    }
    location ~* /\. {
        deny all;
    }
}

访问test控制器

打开浏览器,在地址栏输入www.mysite.local/test/index mysite.local 替换为实际的主机名,将会看到输出xml如下内容:

<?xml version="1.0" encoding="utf-8"?>
<response>
    <code>0</code>
    <message>success</message>
    <data>Hello micro-hau</data>
</response>

用Postman模拟请求,设置content-typeapplication/json; charset=UTF-8 将会看到如下内容:

{
    "code": 0,
    "message": "success",
    "data": "Hello micro-hau"
}