Laravel默认的项目结构不太符合个人使用习惯,也不太适合大型项目使用。
原本把app/Http/目录下的Controllers目录丶Middleware目录丶Kernel.php均
移至app目录下了,但是有些快速生成Laravel的命令就使用不了了,不想自己去额外实现这些命令,
还是将其改回去了。由于动刀的仅有app目录,贴上目录结构:
├── Console
│ └── Kernel.php
├── Exceptions
│ ├── ApiException.php
│ ├── Handler.php
│ └── RequestInvalidException.php
├── Helper
├── Http
│ ├── Controllers
│ ├── Kernel.php
│ └── Middleware
├── Models
│ └── UserModel.php
├── Providers
│ ├── AppServiceProvider.php
│ ├── AuthServiceProvider.php
│ ├── BroadcastServiceProvider.php
│ ├── EventServiceProvider.php
│ └── RouteServiceProvider.php
├── Repositories
├── Requests
│ ├── Api
│ ├── BaseRequest.php
│ └── Mini
├── Services
│ ├── Api
│ ├── BaseService.php
│ └── Mini
└── Traits
└── ApiResponseTrait.php
新增加了目录Requests, Repositories, Services, Traits, Helper, Models目录。
该目录下创建的类文件均是模型文件,仅仅定义模型还有其关联模型之间的关联,不进行任何其他的查询操作。
如UserModel.php:
<?php
namespace App\Models;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
use Tymon\JWTAuth\Contracts\JWTSubject;
class UserModel extends Authenticatable implements JWTSubject
{
use Notifiable;
protected $table = 'users';
/**
* @var array
*/
protected $fillable = [
'name', 'email', 'password',
];
/**
* @var array
*/
protected $hidden = [
'password', 'remember_token',
];
/**
* @return mixed
*/
public function getJWTIdentifier()
{
return $this->getKey();
}
/**
* @return array
*/
public function getJWTCustomClaims()
{
return [];
}
// 关联用户详情表
public function userInfo()
{
}
}
该目录为表单验证类的目录,该目录下的Request类需要继承BaseRequest类, 然后通过注入到控制器中进行表单验证。
BaseRequest代码如下:
<?php
namespace App\Requests;
use App\Traits\ApiResponseTrait;
use Illuminate\Contracts\Validation\Validator;
use Illuminate\Foundation\Http\FormRequest;
use App\Exceptions\RequestInvalidException;
class BaseRequest extends FormRequest
{
use ApiResponseTrait;
/**
* 默认允许访问, 权限控制中间件已经进行过滤了!
* @return bool
*/
public function authorize()
{
return true;
}
// 验证失败抛接口异常。
public function failedValidation(Validator $validator)
{
$error = $validator->errors()->first();
throw new RequestInvalidException($error, 10000);
}
}
LoginRequest.php代码如下:
<?php
namespace App\Requests\Api\User;
use App\Requests\BaseRequest;
class LoginRequest extends BaseRequest
{
public function rules()
{
return [
'username' => 'required',
'password' => 'required',
];
}
public function messages()
{
return [
'username.required' => '账号必填',
'password.required' => '密码必填',
];
}
}
在控制器中使用LoginRequest, 如:
// 用户登录
public function login(LoginRequest $request)
{
// $request->validated()这里拿到的数据即是验证成功后的数据。
return $this->service->login($request->validated());
}
Repositories
该目录下的类文件作用是进行数据的操纵(增删改查), 通过依赖注入方式引入模型类进行操作。
如UserRepository代码:
<?php
namespace App\Repositories;
use App\Models\UserModel;
class UserRepository
{
protected $model;
public function __construct(UserModel $model)
{
$this->model = $model;
}
public function getUserById($id)
{
return $this->model->find($id);
}
}
该目录下的类文件主要用于业务逻辑的处理,通过注入Repository类进行数据操纵, 该目录下的Service都必须继承一个基类BaseService:
<?php
namespace App\Services;
use App\Traits\ApiResponseTrait;
/**
* Class BaseService
* @package App\Services
*/
class BaseService
{
use ApiResponseTrait;
}
处理用户相关业务逻辑的UserService.php代码如下:
<?php
namespace App\Services\Api;
use App\Repositories\UserRepository;
use App\Services\BaseService;
class UserService extends BaseService
{
protected $repository;
public function __construct(UserRepository $repository)
{
$this->repository = $repository;
}
/**
* 用户登录
* @param $params
* @return false|string
*/
public function login($params)
{
// 这里仅作演示,不必在意细节
return $this->repository->getUserById($params['id']);
}
/**
* 用户注销
*/
public function logout()
{
return $this->data(true, '注销成功');
}
}
该目录下主要定义一些Trait,提高代码复用率。 如ApiResponseTrait.php代码:
<?php
namespace App\Traits;
/** 接口返回格式定义
* Class ApiResponseTrait
* @package App\Traits
*/
trait ApiResponseTrait
{
/**
* 返回成功数据
* @param $data
* @param string $msg
* @return false|string
*/
public function data($data, $msg='')
{
$resp = [
'status' => 1,
'data'=>$data,
'msg' => $msg,
'errno' => 0
];
return response()->json($resp);
}
/**
* 返回错误信息
* @param $errno
* @param string $msg
* @return false|string
*/
public function error($errno, $msg='')
{
$resp = [
'status' => 0,
'errno' => $errno,
'data' => [],
'msg' => $msg,
];
return response()->json($resp);
}
}
该目录也是为了提高代码复用率,不过该文件夹下定义的是一些自定义函数。
该目录下有两个子目录Api和Mini, Api是PC端接口, Mini是小程序端接口。
贴上一个控制器代码:
<?php
namespace App\Http\Controllers\Api;
use App\Http\Controllers\Controller;
use App\Requests\Api\User\LoginRequest;
use App\Services\Api\UserService;
/**
* 用户相关模块
* Class UserController
* @package App\Http\Controllers\Api
*/
class UserController extends Controller
{
public function __construct(UserService $service)
{
$this->service = $service;
}
// 用户登录
public function login(LoginRequest $request)
{
return $this->service->login($request->validated());
}
}
可以看到一个控制器方法仅有一行代码。
引进Service和Repository层精简控制器代码,提高了代码的可读性。
Trait和Helper提高代码复用率,且方便集中管理。
通过依赖注入避免了new的使用, Laravel会递归的拿构造函数和参数进行注入实例。
标签: laravel