简介
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
目录。
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() { } }
Requests
该目录为表单验证类的目录,该目录下的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); } }
Services
该目录下的类文件主要用于业务逻辑的处理,通过注入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, '注销成功'); } }
Traits
该目录下主要定义一些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); } }
Helper
该目录也是为了提高代码复用率,不过该文件夹下定义的是一些自定义函数。
Controllers
该目录下有两个子目录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会递归的拿构造函数和参数进行注入实例。