CCENOTE-API

开发之前,你需要将项目克隆到本地

#克隆项目
git clone https://github.com/ccenote/php-ccenote-blog-api.git
#or
git clone https://gitee.com/ChinaClowns/php-ccenote-blog-api.git
#打开项目
cd ccenote-api
#安装项目所需依赖
composer config -g repo.packagist composer https://mirrors.aliyun.com/composer/
composer install

然后启动服务器环境,访问 http://localhost/api/back/admin/getVerifyCode

出现验证码数据内容之后,你将成功的部署好了此项目

作者推荐使用服务器环境软件:phpStudyopen in new window

目录结构

|-app
|   |-Console
|   |   |-Commands------自定义artisan命令
|   |   |   |-Repositories.php
|   |   |   |-Services.php
|   |   |-Kernal.php
|   |-Exceptions------全局异常处理
|   |   |-Handler.php
|   |-Helpers
|   |-Http
|   |   |-Controllers------控制器
|   |   |-Middleware------中间件
|   |   |-Requests------表单验证类
|   |   |-Kernel.php------中间件组配置文件
|   |-Mail------邮箱配置类
|   |-Models------Models
|   |-Providers------服务提供者
|   |-Repositories------数据层
|   |-Services------业务层
|   |   |-BackService------后台业务层
|   |   |-FrontService------前台业务层
|   |   |-Project------业务层配置
|   |   |-BaseService.php------业务层基类
|   |-Traits------和Go的组合功能类似
|   |-Utils------工具类
|-config
|   |-jwt.php------jwt配置文件
|   |-filesystems.php------文件储存配置文件
|-database
|   |-factories
|   |-migrations------数据迁移表
|   |-seeders------数据填充
|-resources
|   |-css
|   |-lang
|   |-views------模板文件
|   |   |-email
|-routes
|   |-api.php
|   |-backApi.php------后台路由
|   |-frongApi.php------前台路由
|   |-web.php
|-storage
|   |-app
|   |-file
|   |-images
|   |   |-article------文章图片文件夹
|   |   |   |-default
|   |   |   |   |-ArticleDefault.jpg
|   |   |-avatar------头像文件夹
|   |   |   |-back
|   |   |   |-front
|   |   |   |-avatar.jpg
|   |   |-banner------banner图片文件夹
|   |   |-logo------logo文件夹
|   |   |   |-logo.png
|   |   |-partner------友情链接图片文件夹
|-.env------项目配置文件

功能开发

如果你学习过Laravel,那么你很熟悉如何开发一个新的功能,但是为了更加方便的开发,我在原基础上,增加了数据层和业务层等逻辑

数据层

在app目录下,添加了Repositories目录,里面提供每个功能的数据层操作

你可以通过以下命令来生成一个新的功能数据层操作

php artisan make:repositories MyRepository

新的功能数据层操作默认继承了 BaseRepository 抽象类,此抽象类提供了一般公共的数据层操作,如图:

Repositories

此基类中的公共方法:

在新建的数据层操作中你需要通过构造方法来指定你要操作的数据库实体类模型:

接下来你可以按照自己的功能需求来添加你自己的操作方法。

业务层

所有业务层的类都继承了 BaseService 类,BaseService 类中使用了多个Trait,它们能够在你日常的业务开发中提供帮助

Services

当然,我们不主动采取去 new 一个对象的操作

public function getMyData(AdminRepository $repository,RoleRepository $roleRepository): JsonResponse
{
    
}

同样的,通过形参,你可以使用你数据层中的任何操作

表单验证

接下来,我们来聊一下表单验证,一般的封装表单验证让我感到十分鸡肋,于是,我试图封装了一个request的基类

Request

当你生成了一个自定义表单验证类时,你可以继承此基类,来实现更简单方便的表单验证,自定义表单验证类格式如下:

<?php
class PartnerRequest extends BaseRequest
{
    protected $rules = [
        'add'=>[
            'url'=>['url','nullable'],
            'title'=>['string','nullable'],
            'img'=>['image','image_min:1','image_max:5120','mimes:jpeg,png,webp']
        ],
        'update'=>[
            'id'=>['integer', 'required'],
            'url'=>['url','nullable'],
            'title'=>['string','nullable'],
            'img'=>['image','image_min:1','image_max:5120','mimes:jpeg,png,webp']
        ],
        'partner'=>[
            'id'=>['integer', 'required']
        ],
        'delete'=>[
            'id'=>['integer','required']
        ]
    ];

    protected $rulesMsg = [
        'add'=>[
            'url'=>'链接',
            'title'=>'描述',
            'img'=>'图片'
        ],
        'update'=>[
            'id'=>'id',
            'url'=>'链接',
            'title'=>'描述',
            'img'=>'图片'
        ],
        'partner'=>[
            'id'=>'id'
        ],
        'delete'=>[
            'id'=>'id'
        ]
    ];

    public function authorize()
    {
        return true;
    }
    public function rules()
    {
        return $this->getRules();
    }
}

这个表单验证类的字段数组是如何实现的?

默认截取请求地址的最后一段 / ,比如文章添加的路径是 api/article/add ,所需要的请求参数有标题、内容、那么你可以写成这样:

protected $rules = [
    'add'=>[
        'title'=>['string','nullable'],
        'content'=>['string','required']
    ],
];
protected $rulesMsg = [
    'add'=>[
        'title'=>'标题',
        'content'=>'内容'
    ],
];

当请求时出现参数异常时,便会从基类中生成一个错误信息,具体错误信息可查看基类中的 $errorMsg

protected $errorMsg = [
    'required' => '不能为空',
    'min' => '最少字符为:min',
    'max' => '最大字符为:max',
    'string' => '必须为字符串格式',
    'unique' => '以存在',
    'json' => '不是有效得json格式',
    'array' => '必须是数组格式',
    'between' => '长度必须在:min和:max之间',
    'integer' => '必须为整型',
    'email' => '格式不正确',
    'url' => '格式不正确',
    'nullable' => '可为空',
    'date_format' => '格式不正确',
    'boolean' => '必须为布尔值',
    'mobile'=>'手机号格式不对',
    'image_min'=>'文件最小为:image_min'.'kb',
    'image_max'=>'文件最大为:image_max'.'kb',
    'video_min'=>'文件最小为:video_min'.'kb',
    'video_max'=>'文件最大为:video_max'.'kb',
    'mimes'=>'格式不正确',
    'image'=>'不正确',
];

接下来,你便可以在控制器中使用了,只需要定义在形参即可:

public function getPartner(PartnerRequest $request,PartnerService $service,PartnerRepository $repository): JsonResponse
{
    return $service->getPartner($request,$repository);
}

Traits

Traits中定义了许多类似组合似的功能供你使用,具体可查看每个Trait中的方法注释