优雅的组织Laravel项目结构

优雅的组织Laravel的项目结构

1.1 简介

​ 在以前的开发中,所有的业务、数据库操作都写到了控制器中,导致控制器过于臃肿,不便阅读,而Laravel是一个优雅的框架,于是就想先组织一个优雅项目结构!~

1.2 目录介绍

更改的只有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目录。

1.2.1 Models目录

该目录下创建的类文件均是模型文件,仅仅定义模型还有其关联模型之间的关联,不进行任何其他的查询操作。

如 UserModel.php :

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Notifications\Notifiable;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Tymon\JWTAuth\Contracts\JWTSubject;

class UserModel extends Authenticatable implements JWTSubject
{
    protected $table = 'users';
    protected $fillable = ['username','password','keyId'];

    use Notifiable;
    // Rest omitted for brevity

    /**
     * Get the identifier that will be stored in the subject claim of the JWT.
     *
     * @return mixed
     */
    public function getJWTIdentifier()
    {
        return $this->getKey();
    }

    /**
     * Return a key value array, containing any custom claims to be added to the JWT.
     *
     * @return array
     */
    public function getJWTCustomClaims()
    {
        return [];
    }
}

1.2.2 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);
    }
}
  • 定义的异常类RequestInvalidException
<?php

namespace App\Exceptions;

use App\Traits\ApiResponseTrait;
use Exception;
use Throwable;

class RequestInvalidException extends Exception
{
    use ApiResponseTrait;
    public function __construct(string $message = "", int $code = 0, Throwable $previous = null) {
        parent::__construct($message, $code, $previous);
    }

    public function render($request){

        // 如果是 AJAX 请求则返回 JSON 格式的数据
//        if ($request->expectsJson()) {
//            return response()->json(['msg' => $this->message], $this->code);
//        }
//        return view('error', ['msg' => $this->message]);
        // 始终返回Json
        return $this->error($this->code,$this->message);
    }
}

  • RegisterRequest.php代码如下 (用来校验用户注册的表单)
<?php

namespace App\Request\AboutUser;

class RegisterRequest extends \App\Request\BaseRequest
{
    public function rules(): array
    {
        return [
            'username' => [
                'required',
                'unique:users',
                'max:11',
                'min:5',
                'regex:/^[0-9a-zA-Z_]*$/'
            ],
            'password' => 'required|max:16|min:8'
        ];
    }

    public function messages() : array
    {
        return [
           'username.required'=>'用户名不能为空',
           'username.max'=>'用户名长度不能超过11个字符',
           'username.min'=>'用户名长度不能少于5个字符',
           'username.unique'=>'用户名已存在',
           'username.regex'=>'用户名只能由字母和数字组成',
           'password.required'=>'密码不能为空',
           'password.max'=>'密码长度不能超过16个字符',
           'password.min'=>'密码长度不能少于8个字符'
        ];
    }
}
  • 在控制器中使用RegisterRequest.php
//用户注册
public function register(RegisterRequest $request): \Illuminate\Http\JsonResponse
    {
        // 1.新增用户
        $account = $request->validated();
        // 2.得到随机字符串 Key
        $account['keyId'] = KeyModel::create(['value'=>Tools::random(16)])->id;
        // 3.将密码进行加密
        $account['password'] = Hash::make($account['password']);
        // 4.插入数据并返回响应
        $user = UserModel::create($account);
        return $this->data($user,'注册成功');
    }

1.2.3 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);
    }
}

1.2.4 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, '注销成功');
    }
}

1.2.5 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);
    }
}

1.2.6 Helper目录

该目录也是为了提高代码复用率,不过该文件夹下定义的是一些自定义函数。

1.2.7 Controllers目录

该目录下有两个子目录ApiMini, ApiPC端接口, 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());
    }
    
}

可以看到一个控制器方法仅有一行代码。

1.3 总结

引进Service和Repository层精简控制器代码,提高了代码的可读性。
Trait和Helper提高代码复用率,且方便集中管理。
通过依赖注入避免了new的使用, Laravel会递归的拿构造函数和参数进行注入实例。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: Laravel 的目录结构如下: ``` laravel/ ├── app/ # 应用程序代码 │ ├── Console/ # Artisan 命令 │ ├── Exceptions/ # 应用程序异常处理器 │ ├── Http/ # HTTP 请求处理器 │ ├── Jobs/ # 队列任务 │ ├── Listeners/ # 事件监听器 │ ├── Policies/ # 授权策略 │ ├── Providers/ # 服务提供商 │ ├── Rules/ # 请求验证规则 │ ├── Services/ # 业务逻辑 │ ├── User.php # 用户模型 │ └── ... # 其它文件 ├── artisan # Artisan 命令行工具 ├── bootstrap/ # 应用程序启动脚本 ├── config/ # 配置文件 ├── database/ # 数据库相关文件 │ ├── factories/ # 数据工厂 │ ├── migrations/ # 数据库迁移 │ ├── seeds/ # 数据填充 │ └── ... ├── public/ # 公共文件,如 CSS、JS 和图片 │ ├── css/ │ ├── js/ │ ├── favicon.ico │ └── index.php # 入口文件 ├── resources/ # 视图、语言文件和原生资源文件 │ ├── lang/ # 多语言文件 │ ├── views/ # 视图文件 │ └── ... ├── routes/ # 路由文件 ├── storage/ # 存储文件 │ ├── app/ # 应用程序文件 │ ├── framework/ # 框架文件 │ ├── logs/ # 日志文件 │ └── ... ├── tests/ # 单元测试 ├── vendor/ # 第三方 Composer 包 ├── .env # 环境 ### 回答2: Laravel 是一种流行的 PHP 框架,其目录结构设计非常合理和组织严密,易于维护和理解。下面是 Laravel 的目录结构的简要介绍: 1. app 目录:这是 Laravel 应用程序的核心目录,包含了应用程序的模型(Models)、视图(Views)和控制器(Controllers)。这里还包含了异常处理、中间件、事件、日志等功能的代码。 2. bootstrap 目录:该目录包含了 Laravel 框架的启动和引导代码,其中包含了自动载入机制和环境配置。 3. config 目录:该目录包含了应用程序的配置文件,可以在这里设置数据库连接、应用程序的环境变量和其他配置选项。 4. database 目录:该目录包含了数据库迁移文件和数据填充文件,可以通过迁移文件来创建和修改数据库表结构,并使用填充文件填充一些初始数据。 5. public 目录:该目录是应用程序的根目录,其中包含了前端资源文件(如 JavaScript、CSS 和图片等),以及一个入口文件 index.php。 6. resources 目录:该目录包含了应用程序的资源文件,包括视图模板文件、原始的 Sass、Less、JavaScript 源码文件等。 7. routes 目录:该目录包含了应用程序的路由文件,可以定义应用程序的路由规则。 8. storage 目录:该目录用于存储一些生成的文件,如日志文件、缓存文件、会话文件等。 9. tests 目录:该目录用于存放应用程序的测试案例。 10. vendor 目录:该目录包含了 Composer 打包工具下载和管理的第三方依赖库。 这些目录组织良好,分别用于存放不同的文件和代码,使得 Laravel项目结构非常清晰和灵活,有助于提高开发效率和代码的可维护性。 ### 回答3: Laravel是一个流行的PHP框架,其目录结构非常清晰和有组织性,方便开发人员管理和维护项目。以下是Laravel的目录结构解释: 1. app目录:这个目录是存放应用程序的核心代码的地方。包括控制器、模型以及其他自定义类。这是你写业务逻辑的地方。 2. bootstrap目录:这个目录包含了自动加载和启动应用程序所需的一些文件。例如,启动框架、配置加载和异常处理。 3. config目录:这个目录包含了应用程序的所有配置文件。你可以在这里设置数据库连接、邮件配置、缓存驱动等等。 4. database目录:这个目录包含了数据库迁移文件和数据填充器。你可以在这里管理和更新数据库的结构,以及初始化一些测试数据。 5. public目录:这个目录是应用程序的入口点,也是Web服务器公开访问的唯一目录。你可以在这里放置静态资源,例如CSS、JavaScript和图像文件。 6. resources目录:这个目录包含了应用程序所需的视图文件、语言文件和其他资源文件。你可以在这里定义布局、页面模板和语言翻译。 7. routes目录:这个目录包含了应用程序的所有路由文件。你可以在这里定义URL和对应的控制器方法,处理用户的请求。 8. storage目录:这个目录包含了应用程序的日志文件、缓存文件和上传的文件。你可以在这里存储应用程序运行过程中的各种数据。 9. tests目录:这个目录包含了应用程序的单元测试和功能测试。你可以在这里编写和运行测试,以确保应用程序的正确性。 总的来说,Laravel的目录结构非常有组织性,使开发人员可以快速找到所需的文件,并进行相关的修改和维护。这种结构也方便团队合作和项目的可维护性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值