以用户注册流程为例
统一响应
这里为了统一响应格式,直接用第三方封装的响应数据包,具体用法参考官方文档:
laravel-response: ???? Provide a standardized and unified response data format for Laravel and Lumen API projects. - 为 Laravel 和 Lumen API 项目提供一个规范统一的响应数据格式。 (gitee.com)
示例
Response::fail();
Response::ok();
Response::success([]);
控制器
创建控制器
php artisan make:controller UserController
控制器校验请求后调用不同 service 进行业务处理,调用 API Resource 转换资源数据返回,示例:
<?php
namespace App\Http\Controllers;
use App\Http\Requests\UserRequest;
use App\Services\SmsService;
use App\Services\UserService;
use Jiannei\Response\Laravel\Support\Facades\Response;
class UserController extends Controller
{
private $userId; //用户id
private $userService; //用户业务层
public function __construct(UserService $userService)
{
$this->userService = $userService;
$this->userId = 1;
}
/**
* 获取用户信息
*/
public function info()
{
return Response::success($this->userService->getUserInfo($this->userId));
}
/**
* 注册
*
* @param UserRequest $request
* @param SmsService $smsService
* @return \Illuminate\Http\JsonResponse|\Illuminate\Http\Resources\Json\JsonResource
* @throws \Illuminate\Auth\Access\AuthorizationException
* @throws \Illuminate\Validation\ValidationException
*/
public function register(UserRequest $request, SmsService $smsService)
{
//参数验证
$request->validate('register');
//短信验证码验证
if (!$smsService->check($request->mobile, 'register', $request->code)){
return Response::fail('验证码错误');
}
try{
//新增用户
$this->userService->addUser($request->all());
//绑定推荐人...
//其他服务操作...
return Response::ok();
}catch (\Exception $e){
return Response::fail($e->getMessage());
}
}
}
重点事项:
- 将注入的
Illuminate\Http\Request
换成自定义的FormRequest
验证器
创建基础验证器
php artisan make:request BaseRequest
创建的验证器在app/Http/Requests/BaseRequest.php
然后修改其内容为:
<?php
namespace App\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Http\Exceptions\HttpResponseException;
use Illuminate\Contracts\Validation\Validator;
/**
* 基础验证器
* Class AbstractRequest
* @package App\Http\Requests
*/
class BaseRequest extends FormRequest
{
public $scenes = []; //场景集合
public $currentScene; //当前场景
public $autoValidate = false; //是否注入之后自动验证
public function authorize()
{
return true;
}
/**
* 设置场景
* @param $scene
* @return $this
*/
public function scene($scene)
{
$this->currentScene = $scene;
return $this;
}
/**
* 覆盖自动验证方法
*/
public function validateResolved()
{
if ($this->autoValidate) {
$this->handleValidate();
}
}
/**
* 验证方法
* @param string $scene
* @throws \Illuminate\Auth\Access\AuthorizationException
* @throws \Illuminate\Validation\ValidationException
*/
public function validate($scene = '')
{
if ($scene) {
$this->currentScene = $scene;
}
$this->handleValidate();
}
/**
* 根据场景获取规则
* @return array|mixed
*/
public function getRules()
{
$rules = $this->container->call([$this, 'rules']);
$newRules = [];
if ($this->currentScene && isset($this->scenes[$this->currentScene])) {
$sceneFields = is_array($this->scenes[$this->currentScene])
? $this->scenes[$this->currentScene] : explode(',', $this->scenes[$this->currentScene]);
foreach ($sceneFields as $field) {
if (array_key_exists($field, $rules)) {
$newRules[$field] = $rules[$field];
}
}
return $newRules;
}
return $rules;
}
/**
* 覆盖设置 自定义验证器
* @param $factory
* @return mixed
*/
public function validator($factory)
{
return $factory->make(
$this->validationData(), $this->getRules(),
$this->messages(), $this->attributes()
);
}
/**
* 最终验证方法
* @throws \Illuminate\Auth\Access\AuthorizationException
* @throws \Illuminate\Validation\ValidationException
*/
protected function handleValidate()
{
$instance = $this->getValidatorInstance();
if ($instance->fails()) {
$this->failedValidation($instance);
}
$this->passedValidation();
}
/**
* 重写验证失败返回
*/
protected function failedValidation(Validator $validator)
{
$error = $validator->errors()->all();
throw new HttpResponseException(response()->json([
'code' => 505,
'msg' => $error['0'],
'data' => []
]));
}
}
接下来创建其他验证器的时候继承BaseRequest就可以了,比如创建一个UserRequest
php artisan make:request UserRequest
然后修改其内容为:
<?php
namespace App\Http\Requests;
/**
* 用户模块验证
*/
class UserRequest extends BaseRequest
{
/**
* Determine if the user is authorized to make this request.
*
* @return bool
*/
public function authorize()
{
return true;
}
/**
* 验证规则
* Get the validation rules that apply to the request.
*
* @return array
*/
public function rules()
{
return [
'mobile' => 'required|regex:/^1[3-9]\d{9}$/',
'password' => 'required|min:6',
];
}
/**
* 验证字段
* Get custom attributes for validator errors.
*
* @return array
*/
public function attributes()
{
return [
'mobile' => '手机号码',
'password' => '登录密码'
];
}
/**
* 自定义提示信息
* Get custom messages for validator errors.
*
* @return array
*/
public function messages()
{
return [
'*.required' => ':attribute不能为空',
'*.regex' => ':attribute格式不正确',
'*.min' => ':attribute不能少于6位',
];
}
/**
* 定义验证场景和对应的验证字段
*/
public $scenes = [
//注册
'register' => [
'mobile',
'password'
],
//登录
'login' => [
'mobile',
'password'
],
];
}
服务
创建服务
php artisan phpno1:service User
上面的命令会生成app/Services/UserService.php
,他会自动绑定对应的仓库App\Repository\Contracts\UserRepository
<?php
namespace App\Services;
use App\Repository\Contracts\UserRepository;
class UserService
{
/**
* @var UserRepositoryEloquent
*/
protected $userRepository;
public function __construct(UserRepository $userRepository)
{
$this->userRepository = $userRepository;
}
/**
* 添加用户
*/
public function addUser($data)
{
$this->userRepository->create($data);
}
/**
* 查找用户
* @param $id
* @return \Illuminate\Database\Eloquent\Builder
*/
public function getUserInfo($id)
{
return $this->userRepository->find($id);
}
}
仓库
创建仓库
php artisan phpno1:repository User
执行命令之后会生成app/Repository/Contracts/UserRepository.php
和app/Repository/Eloquent/UserRepositoryEloquent.php
;我们平时写数据库查询逻辑在UserRepositoryEloquent
中写就可以了
模型
创建模型
php artisan make:model User
模型里面只保留默认的表属性和关联绑定方法即可,不处理业务
<?php
namespace App\Models;
use App\Traits\SerializeDate;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
use Laravel\Sanctum\HasApiTokens;
class User extends Authenticatable
{
use HasApiTokens, HasFactory, Notifiable, serializeDate;
/**
* The attributes that are mass assignable.
*
* @var array<int, string>
*/
protected $fillable = [
'name',
'mobile',
'password',
];
/**
* The attributes that should be hidden for serialization.
*
* @var array<int, string>
*/
protected $hidden = [
'password',
'updated_at',
'remember_token',
'email_verified_at',
];
/**
* The attributes that should be cast.
*
* @var array<string, string>
*/
protected $casts = [
];
}