php larval开发规范,Laravel 开发规范摘要

环境说明

一般情况下,一个项目 应该 有以下三个基本的项目环境:

Local - 开发环境

Staging - 线上测试环境, develop 分支

Production - 线上生产环境, master 分支

开发专用扩展包

安装

安装开发专用扩展包时 必须 使用 --dev 参数,如:

composer require laracasts/generators --dev

加载

开发专用的 provider 绝不在 config/app.php 里面注册,必须在

app/Providers/AppServiceProvider.php 文件中使用如以下方式:

public function register()

{

if ($this->app->environment() == 'local') {

$this->app->register('Laracasts\Generators\GeneratorsServiceProvider');

}

}

配置信息与环境变量

在此统一规定:所有程序配置信息 必须 通过 config() 来读取,所有的 .env 配置信息 必须 通过 config() 来读取,绝不 在配置文件以外的范围使用 env()。

辅助函数

必须 把所有的『自定义辅助函数』存放于 bootstrap 文件夹中。

并在 bootstrap/app.php 文件的最顶部进行加载:

require __DIR__ . '/helpers.php';

...

代码风格

代码风格 必须 严格遵循 PSR-2 规范。所以使用代码格式化插件要配置为PSR-2

路由器

路由闭包

绝不 在路由配置文件里书写『闭包路由』或者其他业务逻辑代码,因为一旦使用将无法使用 路由缓存 。

路由器要保持干净整洁,绝不 放置除路由配置以外的其他程序逻辑。

Restful 路由

必须 优先使用 Restful 路由,配合资源控制器使用,见 文档。

cde12e6ab2da

Alt text

使用 resource 方法时,如果仅使用到部分路由,必须 使用 only 列出所有可用路由:

Route::resource('photos', 'PhotosController', ['only' => ['index', 'show']]);

使用 except,对于新增方法没有保护作用,而 only 相当于白名单,相对于 except 更加直观。路由使用白名单有利于养成『安全习惯』。

路由模型绑定

在允许使用路由 模型绑定 的地方 必须 使用。

模型绑定代码 必须 放置于 app/Providers/RouteServiceProvider.php 文件的 boot 方法中:

public function boot()

{

Route::bind('user_name', function ($value) {

return User::where('name', $value)->first();

});

Route::bind('photo', function ($value) {

return Photo::find($value);

});

parent::boot();

}

全局路由器参数

出于安全考虑,应该 使用全局路由器参数限制,详见 文档。

必须 在 RouteServiceProvider 文件的 boot 方法里定义模式:

/**

* 定义你的路由模型绑定,模式过滤器等。

*

* @param \Illuminate\Routing\Router $router

* @return void

*/

public function boot(Router $router)

{

$router->pattern('id', '[0-9]+');

parent::boot($router);

}

模式一旦被定义,便会自动应用到所有使用该参数名称的路由上:

Route::get('users/{id}', 'UsersController@show');

Route::get('photos/{id}', 'PhotosController@show');

只有在 id 为数字时,才会路由到控制器方法中,否则 404 错误。

路由命名

除了 resource 资源路由以外,其他所有路由都 必须 使用 name 方法进行命名。

Route::post('users/{id}/follow', 'UsersController@follow')->name('users.follow');

数据模型

放置位置

所有的数据模型文件,都 必须 存放在:app/Models/ 文件夹中。

命名空间:

namespace App\Models;

忽略此块

User.php 初始化模型处理

Laravel 5.5 默认安装会把 User 模型存放在 app/User.php,必须 移动到 app/Models 文件夹中,并修改命名空间声明为 App/Models。

为了不破坏原有的逻辑点,必须 全局搜索 App/User 并替换为 App/Models/User。

使用基类

所有的 Eloquent 数据模型 都 必须 继承统一的基类 App/Models/Model,此基类存放位置为 /app/Models/Model.php,内容参考以下:

namespace App\Models;

use Illuminate\Database\Eloquent\Model as EloquentModel;

class Model extends EloquentModel

{

public function scopeRecent($query)

{

return $query->orderBy('created_at', 'desc');

}

}

以 Photo 数据模型作为例子继承 Model 基类:

namespace App\Models;

class Photo extends Model

{

protected $fillable = ['id', 'user_id'];

public function user()

{

return $this->belongsTo(User::class);

}

}

命名规范

基本命名规范:

变量命名 必须 使用「Snake Case」写法,如:$user_id, $post_id

方法命名 必须 使用「驼峰」写法,并且首字母小写,如:getUserInfo

类命名 必须 使用「驼峰」写法,并且首字母大写,如:UserInfo

数据模型相关的命名规范:

数据模型类名 必须 为「单数」, 如:App\Models\Photo

数据库表名字 必须 为「单数」,多个单词情况下使用「Snake Case」 如:photo, my_photo

数据库字段名 必须 为「Snake Case」,如:view_count, is_vip

数据库表主键 必须 为「id」

数据模型变量 必须 为「resource_id」,如:$user_id, $post_id

利用 Trait 来扩展数据模型

有时候数据模型里的代码会变得很臃肿,应该 利用 Trait 来精简逻辑代码量,提高可读性

存放于文件夹:app/Models/Traits 文件夹中。

Repository

绝不 使用 Repository,因为我们不是在写 JAVA 代码,太多封装就成了「过度设计(Over Designed)」,极大降低了编码愉悦感,使用 MVC 够傻够简单。

PS: 那么MVC M 和 C 我们怎么定义呢?M* 写什么 C 写什么,对于一些公共的方法我们该写在哪里(Traits?)*

全局作用域

Laravel 的 Model 全局作用域 允许我们为给定模型的所有查询添加默认的条件约束。

所有的全局作用域都 必须 统一使用 闭包定义全局作用域,如下:

/**

* 数据模型的启动方法

*

* @return void

*/

protected static function boot()

{

parent::boot();

static::addGlobalScope('age', function(Builder $builder) {

$builder->where('age', '>', 200);

});

}

控制器

资源控制器

必须 使用资源的复数形式,如:

类名:PhotosController

文件名:PhotosController.php

错误的例子:

类名:PhotoController

文件名:PhotoController.php

保持短小精炼

必须 保持控制器文件代码行数最小化,还有可读性。

不应该 为「方法」书写注释,这要求方法取名要足够合理,不需要过多注释;

应该 为一些复杂的逻辑代码块书写注释,主要介绍产品逻辑 - 为什么要这么做;

不应该 在控制器中书写「私有方法」,控制器里 应该 只存放「路由动作方法」;

绝不 遗留「死方法」,就是没有用到的方法,控制器里的所有方法,都应该被使用到,否则应该删除;

绝不 在控制器里批量注释掉代码,无用的逻辑代码就必须清除掉。

表单验证

表单请求验证类

必须 使用 表单请求 - FormRequest 类 来处理控制器里的表单验证。

使用基类

创建 app/Http/Requests/Request.php 基类,所有表验证类 必须 继承此基类。

基类文件如下:

namespace App\Http\Requests;

use Illuminate\Foundation\Http\FormRequest;

class Request extends FormRequest

{

public function authorize()

{

// Using policy for Authorization

return true;

}

}

表验证类文件参考:

namespace App\Http\Requests;

class PhotoRequest extends Request

{

public function rules()

{

switch($this->method())

{

// CREATE

case 'POST':

{

return [

// CREATE ROLES

];

}

// UPDATE

case 'PUT':

case 'PATCH':

{

return [

// UPDATE ROLES

];

}

case 'GET':

case 'DELETE':

default:

{

return [];

};

}

}

public function messages()

{

return [

// Validation messages

];

}

}

授权策略

必须 使用 授权策略 类来做用户授权。

使用基类

所有授权策略类 必须 继承 app/Policies/Policy.php 基类。

基类文件如下:

namespace App\Policies;

use Illuminate\Auth\Access\HandlesAuthorization;

class Policy

{

use HandlesAuthorization;

public function __construct()

{

//

}

public function before($user, $ability)

{

if ($user->isAdmin()) {

return true;

}

}

}

授权策略类文件参考:

namespace App\Policies;

use App\Models\User;

use App\Models\Photo;

class PhotoPolicy extends Policy

{

public function update(User $user, Photo $photo)

{

return $user->isAuthorOf($photo);

}

public function destroy(User $user, Photo $photo)

{

return $user->isAuthorOf($photo);

}

}

Artisan 自定义命令行

必须 有项目的命名空间。

如:

php artisan phphub:clear-token

php artisan phphub:send-status-email

...

错误的例子为:

php artisan clear-token

php artisan send-status-email

...

Laravel 安全实践

SQL 注入

Laravel 的 查询构造器 和 Eloquent 是基于 PHP 的 PDO,PDO 使用 prepared 来准备查询语句,保障了安全性。

在使用 raw() 来编写复杂查询语句时,必须 使用数据绑定。

错误的做法:

$name = "admin"; // 假设用户提交

$password = "xx' OR 1='1"; // // 假设用户提交

$result = DB::select(DB::raw("SELECT * FROM users WHERE name ='$name'

and password = '$password'"));

dd($result);

以下是正确的做法,利用 select 方法 的第二个参数做数据绑定:

$name = "admin"; // 假设用户提交

$password = "xx' OR 1='1"; // // 假设用户提交

$result = DB::select(

DB::raw("SELECT * FROM users WHERE name =:name and password = :password"),

[

'name' => $name,

'password' => $password,

]

);

dd($result);

DB 类里的大部分执行 SQL 的函数都可传参第二个参数 $bindings ,详见:API 文档 。

批量赋值

Laravel 提供白名单和黑名单过滤($fillable 和 $guarded):

举例,users 表里的 is_admin 字段是用来标识用户『是否是管理员』,某不怀好意的用户,更改了『修改个人资料』的表单,增加了一个字段

这个时候如果你更新代码如下:

Auth::user()->update(Request::all());

此用户将获取到管理员权限。可以有很多种方法来避免这种情况出现,最简单的方法是通过设置 User 模型里的 $guarded 字段来避免:

protected $guarded = ['id', 'is_admin'];

PS: 使用 Request::all() 方法时必须定义好黑名单($guarded)。

推荐阅读篇

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值