用cakephp创建RESTful API

新建controller

新建RecipeController,写入代码:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
<?php

namespace App\Controller;

class RecipesController extends AppController
{
    // 初始化controller
    public function initialize()
    {
        parent::initialize();
        $this->loadComponent('RequestHandler');
    }

    // 默认访问的action,可以将取得所有数据的操作再次处理
    public function index()
    {
        $this->autoRender = false;
        $para = $this->request->getQuery('para'); // 获取Parameter参数
        $result = array('status' => 0, 'method' => 'index', 'data' => '', 'msg' => '', 'para' => $para);
        echo json_encode($result);
    }

    // 带id的action,如果要取得单条数据,可以在此处理
    public function view($id)
    {
        $this->autoRender = false;
        $result = array('status' => 0, 'method' => 'view', 'data' => '', 'msg' => '', 'id' => $id);
        echo json_encode($result);
    }

    // 添加数据的action,会接受POST请求的处理
    public function add()
    {
        $this->autoRender = false;
        $this->request->allowMethod(['post', 'put']);
        $data = $this->request->getData(); // 获取POST的json数据
        $result = array('status' => 0, 'method' => 'add', 'data' => $data, 'msg' => '');
        $message = 'Error';
        if ($this->request->is(['post', 'put'])) {
            $message = 'Saved';
        }
        $result['msg'] = $message;
        echo json_encode($result);
    }

    // 会接受PUT以及PATCH的请求,并且会带上ID
    public function edit($id)
    {
        $this->autoRender = false;
        $this->request->allowMethod(['patch', 'post', 'put']);
        $data = $this->request->getData(); // 获取POST的json数据
        $result = array('status' => 0, 'method' => 'edit', 'data' => $data, 'msg' => '', 'id' => $id);
        $message = 'Error';
        if ($this->request->is(['patch', 'post', 'put'])) {
            $message = 'Saved';
        }
        $result['msg'] = $message;
        echo json_encode($result);
    }

    // 接受DELETE请求
    public function delete($id)
    {
        $this->autoRender = false;
        $this->request->allowMethod(['delete']);
        $result = array('status' => 0, 'method' => 'delete', 'data' => '', 'msg' => '', 'id' => $id);
        $message = 'Deleted';
        $result['msg'] = $message;
        echo json_encode($result);
    }
}

Tips

Cake\Http\ServerRequest::getQueryParams()
Cake\Http\ServerRequest::getQuery($name)
获取请求路径中的查询部分,即“?”之后的部分。
参考资料CakePHP中获取Request请求数据的几种方式
示例:

1
2
3
4
//URL:www.abc.com/users/index?page=2&sort=id&direction=DESC

$this->request->getQuery('page'); //2
$this->request->getQueryParams(); //返回数组,包含所有查询参数

设置路由

在config/route.php中添加代码:

1
2
3
4
$routes->scope('/', function (RouteBuilder $routes) {
    $routes->setExtensions(['json']);
    $routes->resources('Recipes', ['id' => '.*']);
});

这样就会自动将recipes的请求进行RESTful处理,各个请求方法的处理如下:

HTTP请求方法 URL 对应controller的action
GET /recipes RecipesController::index()
GET /recipes/123 RecipesController::view(123)
POST /recipes RecipesController::add()
PUT /recipes/123 RecipesController::edit(123)
PATCH /recipes/123 RecipesController::edit(123)
DELETE /recipes/123 RecipesController::delete(123)

配置好之后运行,用postman测试各个接口,结果如下:

get:
restful api get
get by id:
restful api get id
post:
restful api post
put by id:
restful api put id
patch by id:
restful api patch id

添加额外的action

如果需要添加action的话,还要在路由中做额外的处理
首先在controller中添加一个新的action:

1
2
3
4
5
6
7
8
    public function deleteAll(){
        $this->autoRender = false;
        $this->request->allowMethod(['delete']);
        $result = array('status' => 0, 'method' => 'deleteAll', 'data' => '', 'msg' => '');
        $message = 'deleteAll';
        $result['msg'] = $message;
        echo json_encode($result);
    }

直接访问这个接口实际访问的是delete接口:
restful api delete all

需要在路由中添加映射 config/route.php:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
$routes->scope('/', function (RouteBuilder $routes) {
    $routes->setExtensions(['json']);
    $routes->resources('Recipes',[
        'id' => '.*',
        // 添加deleteAll action的映射
        'map' => [
            'deleteAll' => [
                'action' => 'deleteAll',
                'method' => 'DELETE'
            ]
        ]
    ]);
});

然后再访问就可以看到访问成功了:
restful api delete all

RESTful子路由

创建一个新的controller CommentsController:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
<?php

namespace App\Controller;

class CommentsController extends AppController
{
    public function initialize()
    {
        parent::initialize();
        $this->loadComponent('RequestHandler');
    }

    public function index()
    {
        $this->autoRender = false;
        // 获取上一层路由的id
        $id = $this->request->getParam('recipe_id');
        $result = array('status' => 0, 'method' => 'index', 'data' => '', 'msg' => '', 'id' => $id);
        echo json_encode($result);
    }

    public function view($id)
    {
        $this->autoRender = false;
        $recipeId = $this->request->getParam('recipe_id');
        $result = array('status' => 0, 'method' => 'view', 'data' => '', 'msg' => '', 'id' => $id, 'recipeId' => $recipeId);
        echo json_encode($result);
    }

    public function add()
    {
        $this->autoRender = false;
        $this->request->allowMethod(['post', 'put']);
        $data = $this->request->getData(); // 获取POST的json数据
        $result = array('status' => 0, 'method' => 'add', 'data' => $data, 'msg' => '');
        $message = 'Error';
        if ($this->request->is(['post', 'put'])) {
            $message = 'Saved';
        }
        $result['msg'] = $message;
        echo json_encode($result);
    }

    public function edit($id)
    {
        $this->autoRender = false;
        $this->request->allowMethod(['patch', 'post', 'put']);
        $data = $this->request->getData(); // 获取POST的json数据
        $result = array('status' => 0, 'method' => 'edit', 'data' => $data, 'msg' => '', 'id' => $id);
        $message = 'Error';
        if ($this->request->is(['patch', 'post', 'put'])) {
            $message = 'Saved';
        }
        $result['msg'] = $message;
        echo json_encode($result);
    }

    public function delete($id)
    {
        $this->autoRender = false;
        $this->request->allowMethod(['delete']);
        $result = array('status' => 0, 'method' => 'delete', 'data' => '', 'msg' => '', 'id' => $id);
        $message = 'Deleted';
        $result['msg'] = $message;
        echo json_encode($result);
    }
}

然后配置路由中的子项:

1
2
3
4
    // 添加子路由
    $routes->resources('Recipes', function (RouteBuilder $routes) {
        $routes->resources('Comments');
    });

postman查看效果:
restful api

getParam方法

Cake\Http\ServerRequest::getParam($name)
获取请求路由中的参数信息,如控制器名称、方法名称、方法参数等。
参考资料CakePHP中获取Request请求数据的几种方式
一些常用示例:

1
2
3
4
5
6
7
//URL:www.abc.com/users/edit/3

$this->request->getParam('controller'); //users
$this->request->getParam('action'); //edit
$this->request->getParam('pass'); //3

//$this->request->getParam('paging'); //获取分页相关信息,返回数组

上面代码中的$this->request->getParam('recipe_id')的recipe_id是固定的,格式为{上一层controller名字去掉结尾的s}_id

routes->resources和routes->connect的区别

$routes->connect就是普通的绑定路由
$routes->resources只需要绑定控制器,控制器中的方法会自动绑定,但是要注意,resources只支持以下几种方法
routes resources
参考资料Laravel中resource详解

cakephp中查看所有路由

在项目目录中执行

1
bin\cake routes

就能查看所有路由信息,其中可以看到部分路由的id信息等