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 路由,配合资源控制器使用,见 文档。
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)。
推荐阅读篇
php larval开发规范,Laravel 开发规范摘要相关推荐
- php调用nexmo发送短信,在 Laravel 中 “规范” 的开发短信验证码发送功能
Laravel简介 Laravel是一套简洁.优雅的PHP Web开发框架(PHP Web Framework).它可以让你从面条一样杂乱的代码中解脱出来:它可以帮你构建一个完美的网络APP,而且每行 ...
- php原生开发规范,php开发规范
PHP 开发规范整理 代码样式规范 编码基本规范 a.代码必须遵守 PSR-1. b.文件编码Unicode (UTF-8) 编码保存.同时不要使用 字节序标记(BOM) c.代码必须使用4个空格的缩 ...
- 开发流程与版本管理规范
# 开发流程与版本管理规范## 版本号规则如非特殊说明,所有产品的版本号将遵循 主版本.次版本.BuildNumber 的规则. - 主版本号:发布重大更新时增加 - 次版本号:发布新功能点时增加 - ...
- C++开发要注意的规范?
该博文为原创文章,未经博主同意不得转载,如同意转载请注明博文出处 本文章博客地址:https://cplusplus.blog.csdn.net/article/details/105147982 C ...
- 很久没更新博客了,再发协同开发中SVN使用规范
协同开发中SVN使用规范试用 目标,要求 本次svn提交规范主要针对当前项目中出现的svn管理难,开发流程控制难掌控,项目进度记录不准确等问题而提出.要求每个角色都要进行规范化svn作业. 目录结构与 ...
- 从 ThinkPHP 开发规范 看 PHP 的命名规范和开发建议
稍稍水一篇博客,摘抄自Think PHP 的开发规范,很有引导性,我们可以将这些规范实践到原生 PHP 中. 命名规范 使用ThinkPHP开发的过程中应该尽量遵循下列命名规范: 类文件都是以.cla ...
- amazeui学习笔记二(进阶开发4)--JavaScript规范Rules
amazeui学习笔记二(进阶开发4)--JavaScript规范Rules 一.总结 1.注释规范总原则: As short as possible(如无必要,勿增注释):尽量提高代码本身的清晰性. ...
- 【项目篇】Android团队项目开发之统一代码规范
前言 团队项目开发前的统一三要素:统一需求/开发文档,统一代码规范,统一环境(编译/测试/发布). 一个项目团队,要想有高效的产出,必须在团队协作上下好功夫,必须在项目开发统一进度上做好协调.只有在高 ...
- # 后端开发技巧、常用规范
后端开发技巧.常用规范 开发技巧 equals() 方法的使用 null.equals()会出报空指针,因该是非null的值.equals() 可以使用Objects的equals()方法避免空值,完 ...
- Java开发 高可维护性代码规范
目录 理念与目标 实施目的 关于阿里代码规约 术语 接口方法 功能点方法 子功能点方法 业务逻辑片段方法 实体转换方法 业务方法 rpcservice层 VO(View Object) BO(Busi ...
最新文章
- 图像边缘检测,检测亦或简化
- 文件内容、关键字匹配,split 和 indexOf 均可实现
- ITK:用高斯核计算平滑
- python中gui实现一个登录界面_Python:简单的登陆GUI界面
- Flume将A服务器上的日志实时采集到B服务器
- java 字符串倍_java字符串拼接与性能分析详解
- ORACLE查询不可用状态索引
- 《CUDA C编程权威指南》——2.2 给核函数计时
- 2021年小目标检测最新研究综述
- EMQ X开源版使用
- 多序列比对---ClustalX比对GeneDoc美化
- [转载] 支持支付宝付款的四大国外主机
- 选择运营商3G上网资费套餐其实挺实惠
- php一点通,编程一点通app下载-编程一点通安卓版下载v1.0.1-游迅网
- Go语言学习之net包(The way to go)
- webgis期末考试试题_《WebGIS课程》期末考试复习资料
- 一元线性回归python示例——房价预测
- 汉王 PDF OCR
- 洛谷 AT763【感雨時刻の整理】
- Python编程:封装M3U8格式视频下载类