Swoft HTTP Controller 控制器

  • Swoft控制器Controller作为HTTP服务的核心组件,串接起一次请求的整个生命周期。
  • Swoft控制器可通过注解Annotation的方式访问路由,简化代码。

创建控制器

$ docker-machine ls
$ docker-machine ip default
192.168.99.100
$ docker-machin ssh default
docker@default ~$ docker ps -a
docker@default ~$ docker exec -it myswoft bash
  • 通过命令行gen:controller命令快捷创建控制器类
php bin/swoft gen:controller test --prefix=/test -y
root@db68453f8674:/var/www/swoft# php bin/swoft gen:controller test --prefix=/test -y
Class data:
{
    "name": "test",
    "suffix": "Controller",
    "namespace": "App\\Controllers",
    "className": "TestController",
    "prefix": "/test",
    "idVar": "{id}"
}
Target File: /var/www/swoft/app/Controllers/TestController.php

OK, write successful!

查看项目swoft/app/Controllers/TestController.php控制器文件

$ vim app/Controllers/TestController.php
<?php
/**
 * This file is part of Swoft.
 *
 * @link https://swoft.org
 * @document https://doc.swoft.org
 * @contact group@swoft.org
 * @license https://github.com/swoft-cloud/swoft/blob/master/LICENSE
 */

namespace App\Controllers;

use Swoft\Http\Server\Bean\Annotation\Controller;
use Swoft\Http\Server\Bean\Annotation\RequestMapping;
use Swoft\Http\Server\Bean\Annotation\RequestMethod;
// use Swoft\View\Bean\Annotation\View;
// use Swoft\Http\Message\Server\Response;

/**
 * Class TestController
 * @Controller(prefix="/test")
 * @package App\Controllers
 */
class TestController{
    /**
     * this is a example action. access uri path: /test
     * @RequestMapping(route="/test", method=RequestMethod::GET)
     * @return array
     */
    public function index(): array
    {
        return ['item0', 'item1'];
    }
}

重启容器后使用浏览器访问

docker@default:~$ docker restart myswoft

使用浏览器访问http://192.168.99.100/test查看显示结果

注意观察:

通过Swoft命令创建的控制器类TestController中存在默认的方法index

首先需要提前引入注解类

use Swoft\Http\Server\Bean\Annotation\Controller;
use Swoft\Http\Server\Bean\Annotation\RequestMapping;
use Swoft\Http\Server\Bean\Annotation\RequestMethod;

然后有两个值得注意的注解Annotation

  • @Controller(prefix="/test")
  • @RequestMapping(route="/test", method=RequestMethod::GET)

这两个注解有什么作用呢?那这里就不得不聊到Swoft中的路由了!

创建路由Route

根据约定大于配置的规则,路由应该在用户看到URI的时候,就能找到与之对应的Controller/Action

路由配置httpRouter

Swoft中HTTP路由的配置文件在/swoft/config/beans/base.php

    'httpRouter'       => [
        'ignoreLastSlash'  => false,
        'tmpCacheNumber' => 1000,
        'matchAll'       => '',
    ],

配置参数解析

  • ignoreLastSlash
    表示是否忽略最后一个斜杠,若设置为false/user/index/user/index/表示两个不同的路由。
  • tmpCacheNumber
    表示缓存路由的数量,默认最近1000条。缓存到路由对象的重启后会失效,只会缓存动态路由。
  • matchAll
    表示匹配所有,也就是所有请求都会匹配到这个URL或闭包中。

路由注解 @Controller + @RequestMapping

Swoft中路由主要通过注解@Controller+@RequestMapping实现,注解@Controller定义前缀,注解@RequestMapping定义后缀。

1. 类注解 @Controller

@Controller表示类注解,使用在控制器类上,标记当前类是一个HTTP控制器类。

使用:

  • 显式指定路由前缀
    @Controller(prefix="/route")
    @Controller("/route")
  • 隐式指定路由前缀
    @Controller() 默认自动解析为controller class控制器类名,注意使用驼峰法命名格式。

2. 方法注解 @RequestMapping

@RequestMapping表示方法注解,用于控制器类的动作方法Action上。

格式:@RequestMapping(route, method)

/**
  * @RequsetMapping(route, method)
  */
public function actionName(){}

参数:

  • route 表示设置的路由路径path,是默认参数。
  • method 表示允许的请求方法,可设置多个。

使用:

  • 显式指定路由后缀
    @RequestMapping()
    @RequestMapping("index")
    @RequestMapping(route="index")
  • 隐式指定路由后缀
    如果不使用@RequestMapping@RequestMapping()则默认解析方法名为后缀。
  • 限定HTTP方法
    @RequestMapping(route="index", method=RequestMethod::GET)
    @RequestMapping(route="index", method={RequestMethod::GET,RequestMethod::POST})
  • 指定路由参数,在Action动作方法中可直接使用$name作为方法参数。
    @RequestMapping(route="index/{$name}", method=RequestMethod::GET)

说明:

  • 使用注解必须要提前引入对应注解类
  • 完整的路由path由控制器Controller的前缀prefix后跟动作方法Action的路由route共同组成
  • 当动作方法Action上的路由以/开头时,完整的路由就是它。

创建视图View

以后台登录为例,将路由、控制器、视图三者联系起来。

首先创建后台登录控制器

$ vim /swoft/app/Controllers/Admin/LoginController.php
<?php
namespace App\Controllers\Admin;

use Swoft\Http\Server\Bean\Annotation\Controller;
use Swoft\Http\Server\Bean\Annotation\RequestMapping;
use Swoft\Http\Server\Bean\Annotation\RequestMethod;
use Swoft\View\Bean\Annotation\View;
use Swoft\Http\Message\Server\Request;
use Swoft\Http\Message\Server\Response;

/**
 * Class LoginController
 * @Controller(prefix="/admin/login")
 * @package App\Controllers
 */
class LoginController{
    /**
     * this is a example action. access uri path: /admin
     * @RequestMapping(route="index", method={RequestMethod::GET, RequestMethod::POST})
     * @View(template="admin/login/index")
     * @param Request $request
     * @return array
     */
    public function index(Request $request):array
    {
        $data = [];
        $data["name"] = "admin:login:index";
        
        return $data;
    }
}

命名空间

namespace App\Controllers\Admin;

注解

  • @Controller(prefix="/admin/login")
use Swoft\Http\Server\Bean\Annotation\Controller;
  • @RequestMapping(route="index", method={RequestMethod::GET, RequestMethod::POST})
use Swoft\Http\Server\Bean\Annotation\RequestMapping;
use Swoft\Http\Server\Bean\Annotation\RequestMethod;
  • @View(template="admin/login/index")
use Swoft\View\Bean\Annotation\View;

创建视图

$ vim /swoft/resources/views/admin/login/index.php
<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport"
          content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title><?= $name ?></title>
</head>
<body>

</body>
</html>

最后重启容器后在浏览器输入http://192.168.99.100:80/admin/login查看最终效果

docker@default:~$ docker restart myswoft
myswoft

小结:这里完成了最基本请求、路由、视图的流程,接下来需要重点掌握HTTP请求与响应两部分,这是在Web开发中使用最为频繁的地方。

未完待续...

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,463评论 6 497
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,868评论 3 391
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 161,213评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,666评论 1 290
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,759评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,725评论 1 294
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,716评论 3 415
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,484评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,928评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,233评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,393评论 1 345
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,073评论 5 340
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,718评论 3 324
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,308评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,538评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,338评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,260评论 2 352