让php开发更优雅-ThinkPHP篇

前言


随着开发经验的增加,也伴随团队开发的积累,规范开发显得越来越重要,本文给大家提供一些ThinkPHP框架开发API接口的进阶思路和经验,让大家开发更加统一规范,代码看起来更加优雅。

1.更多使用第三方库。团队开发的时候,各个人的开发经验和思考方式不同,也有一些思维局限性,可以多多使用第三方库,统一代码开发规范。

2.抛弃传统MVC模式,在结构上分出更新的结构分层,防止Controller过于臃肿和复杂,需要进行代码解耦。一般分为下面几层:

  • 数据验证层(Validate):负责验证请求参数,单独创建一个验证请求器,避免验证逻辑放在控制器中验证,例如:

    Laravel框架使用FormRequest Laravel中使用FormRequest进行表单验证及对验证异常进行自定义处理_51CTO博客_laravel 表单验证

  • 控制器层(Controller):负责接收参数、验证参数、调用各个模块的服务层(可以用事务包裹,用到其他服务的可以注入多个服务)、返回响应、返回视图等

  • 服务层(Service):负责具体的业务逻辑实现,将原本控制器的负责流程按模块拆分为一个个小的服务,方便给控制器层组合调用,一般不要跨模块调用服务,服务中可以调用本模块的仓库层方法

  • 仓库层(Repository):调用模型层封装一些负责的查询,方便服务层调用,一般负责只查询本模块的内容

  • 模型层(Model):只包含默认的表属性(表名、字段等)和联表关系

  • (更多层级)

环境搭建


开发示例


用Think5.1框架以用户注册流程为例

  • 控制器(Controller)

    创建空白的用户控制器

     php think make:controller api/User --plain

    控制器校验请求参数后调用不同 service 进行业务处理,调用转换器将数据返回,示例:

    <?php
    
    namespace app\api\controller;
    
    use app\common\service\UserService;
    use app\common\transform\UserTransform;
    use app\common\validate\UserValidate;
    use think\App;
    use think\Db;
    
    class User extends Controller
    {
        protected $service;
    
        public function __construct(App $app = null, UserService $service)
        {
            parent::__construct($app);
            $this->service = $service;
        }
    
        /**
         * 获取用户信息
         */
        public function info(UserTransform $transform)
        {
            $userInfo = $this->service->getUserById(1);
            $this->success($transform->userInfo($userInfo)); //使用转化器
        }
    
        /**
         * 用户注册
         *
         * @param UserValidate $validate 用户验证器
         * @param SmsService $smsService 短信服务
         * @return void
         */
        public function register(UserValidate $validate, SmsService $smsService){
            //参数验证
            $data = $this->request->param();
            if (!$validate->scene('register')->check($data)) {
                $this->fail($validate->getError()); // 继承的Controller里use trait CustomResponse,所以这里可以直接使用fail方法;
            }
    
            //短信验证码验证
            if (!$smsService->check($data['mobile'], 'register', $data['sms_code'])){
                $this->fail('验证码错误');
            }
    
            Db::startTrans();
            try{
                //新增用户
                $this->userService->addUser($data);
    
                //绑定推荐人...
    
                //其他服务操作...
    
                // 提交事务
                Db::commit();
            }catch (\Exception $e){
                // 回滚事务
                Db::rollback();
    
                $this->error($e->getMessage());
            }
    
            $this->ok('注册成功');
        }
    }
  • 验证器(Validate)

    创建验证器

    php think make:validate UserValidate

    在验证器中添加验证规则、提示信息和验证场景

    <?php
    
    namespace app\common\validate;
    
    use think\Validate;
    
    class UserValidate extends Validate
    {
        /**
         * 定义验证规则
         * 格式:'字段名'    =>    ['规则1','规则2'...]
         *
         * @var array
         */
        protected $rule = [
            'mobile' => 'require|regex:/^1[3-9]\d{9}$/',
            'password' => 'require|min:6',
            'sms_code' => 'require|length:6|number',
        ];
    
        /**
         * 定义错误信息
         * 格式:'字段名.规则名'    =>    '错误信息'
         *
         * @var array
         */
        protected $message = [
            'mobile.require' => '手机号码必填',
            'mobile.regex' => '手机号码格式不正确',
            'password.require' => '密码不能为空',
            'sms_code.require' => '短信验证码不能为空',
            'sms_code.length' => '请输入6位短信验证码',
        ];
    
        /**
         * 定义验证场景和对应的验证字段
         */
        protected $scene = [
            //注册
            'register' => [
                'mobile',
                'password',
                'sms_code'
            ],
    
            //登录
            'login' => [
                'mobile',
                'password'
            ],
        ];
    }
  • 模型(Model)

    创建模型

    php think make:model User

    User模型的默认内容为

    <?php
    
    namespace app\common\model;
    
    use think\Model;
    
    class User extends Model
    {
        //
    }
  • 服务层(Service)

    创建服务

    php think make:service UserService

    生成的UserService自动绑定对应的仓库

    <?php
    
    namespace app\common\service;
    
    use app\common\repository\UserRepository;
    
    class UserService
    {
        /**
         * 绑定仓库
         * @var UserRepository
         */
        protected $repository;
    
        public function __construct(UserRepository $repository)
        {
            $this->repository = $repository;
        }
    
        /**
         * 添加用户
         */
        public function addUser($data)
        {
            //密码加密、用户数据处理
            ...
    
            //创建用户
            $this->repository->create($data);
        }
    
        /**
         * 查找用户
         * @param $id
         * @return \Illuminate\Database\Eloquent\Builder
         */
        public function getUserById($id)
        {
            return $this->repository->find($id);
        }
    }
  • 仓库层(Repository)

    创建仓库

    php think make:repository UserRepository

    生成的UserRepository自动绑定对应的模型,里面定义一些联表等复杂查询操作

    <?php
    
    namespace app\common\repository;
    
    use think\App;
    use app\common\model\User;
    use Jian1098\TpRepository\Repository;
    
    /**
     * Class UserRepository
     */
    class UserRepository extends Repository
    {
        protected $model;
    
        public function __construct()
        {
            parent::__construct(new App());
            //绑定模型
            $this->model = new User();
        }
    
    }
  • 转换器

    转换器用于转换查询到的数据结果接口,可用可不用,如果需要对多个字段进行处理,使用转换器比较美观优雅

    创建转换器

    php think make:transform UserTransform

    默认内容如下

    <?php
    
    namespace app\common\transform;
    
    use Jian1098\TpRepository\Command\Transform;
    
    class UserTransform extends Transform
    {
        //用户信息
        public function userInfo($items)
        {
            return [
                'user_id'       => $items['id'],
                'user_name'     => $items['nickname'],
            ];
        }
    }
本作品采用《CC 协议》,转载必须注明作者和本文链接
讨论数量: 25
陈先生

咱都用 thinkphp 了,就先别考虑什么优雅和规范了。

2个月前 评论
jian1098 (楼主) 2个月前
bneglect 2个月前
陈先生 (作者) 2个月前
gowithwind 3周前
twitf 1周前
陈先生 (作者) 1周前
yangweijie
2个月前 评论
jian1098 (楼主) 2个月前
yangweijie (作者) 2个月前
陈先生

试试我前几天写的包吧 think-constant

2个月前 评论
陈先生 (作者) 2个月前
jian1098 (楼主) 2个月前
jian1098 (楼主) 2个月前
jian1098 (楼主) 2个月前
陈先生 (作者) 2个月前
jian1098 (楼主) 2个月前
陈先生 (作者) 2个月前
jian1098 (楼主) 2个月前
zds

tp自带一种光环

2个月前 评论
陈先生 2个月前
yangweijie

packagist.org/packages/yangweijie/... 又开发了新的think-trace 支持定位sql产生位置

2个月前 评论

顶一个!期待TP能超越Symfony的那一天!

3周前 评论
twitf 1周前
yangweijie

github.com/yangweijie/think-debugb... 又开发了 支持ajax监听了,开发更方便了。定位sql 和log 产生位置

2周前 评论

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!