记录自己在使用thinkphp6 开发API报错,但是,输出不是JSON而是HTML的问题. 调整后,就是天塌下来也得给我输出json.

 

我说的是说应用模式.

我需要的只是API应用需要json返回,其他应用不受影响.

 

新建一个应用

 

 

php think build api

 

注:think的build 命令只有安装了多应用才有.

 

安装完之后,访问xxx.xxx/api  浏览器看到是HTML内容.

 

为了完整隔离API应用,

我没有在APP默认的文件上修改.

而是通过在api应用中新增文件来处理.

 

 

 

API文件夹新增三文件

 

复制

ExceptionHandle.php

provider.php

Request.php

 

这3个文件都在/app/文件夹内可以找到,复制到 app/api/ 目录

 

 

改命名空间

将三个文件原来的命名空间

 

namespace app;

改成

namespace app\api;

 

Request.php

除了命名空间,无需再编辑

 

provider.php

除了命名空间

 

还需要注释掉'think\Request'

 

 

<?php
namespace app\api;
// 容器Provider定义文件
return [
//    'think\Request'          => Request::class,
    'think\exception\Handle' => ExceptionHandle::class,
];

 

ExceptionHandle.php

改成如下

    public function render($request, Throwable $e): Response
    {
        //判断应用名字
        if ($this->app->http->getName() === 'api') {
            return json([
                'error' => 1,
                'msg' => $e->getMessage(),
                'trace' => $e->getTrace()
            ]);
        }
        return parent::render($request, $e);
    }

 

现在API所有的异常都会 按json返回. 4xx错误 5xx错误都会按json返回.

 

 

按版本划分API

 

要实现v1 v2之类按版本划分API

 

新建版本文件夹

比如v1

app\api\controller\v1\

 

新建一个测试控制器

注意命名空间

 

<?php


namespace app\api\controller\v1;

use app\api\Basecontroller;

class test extends Basecontroller
{
    public function index()
    {
        return json([
            'version' => app()->version(),
        ]);
    }
}

 

那么通过浏览器

域名/api/v1.test/index

 

省略网址是

 

index是默认操作名,可以省略

域名/api/v1.test/

 

即可访问

 

路由

通过路由,省略掉v1和test中间 那个 [.] 点.

 

1.在/app/api/目录新建一个route目录

2.在route目录新建一个api.php (貌似这个文件名字必须和应用同名)

内容如下

 

<?php
use think\facade\Route;


//将多级分层的 "." 改为 "/"
Route::rule('v1/:control/:action', 'v1.:control/:action');

 

 

那么现在就可以使用不带 点 的url路径访问

 

域名/api/v1/test/index

 

这个这个通用路由有个bug

就是就是必须要传入操作名

 

 

如果想要省略操作名,可以使用路由分组功能.