开发规范摘要,关联模型由于名称一致性导致的问题

 百家乐-前端     |      2020-04-22 20:43

5. 容易犯错的位置

最容易犯错的代码是这样的:

MyPost::with(‘myPostInfo’)->get();

在使用With去eagerLoad关联模型时,必须使用和定义方法同名的key去读取,那么这样读取出来的方法只能是Camel Case的key。其他地方就只能用

$my_post->myPostInfo;

来保证不出问题。

配置信息与环境变量

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

Show Detail

2. 使用关联模型

这里myPostInfo()用的是Camel命名规则,但是我们在读取某一个PostInfo的时候可以用Snake规则。如下面代码都是可行的:

$post = MyPost::find(1);
$post_info = $post->myPostInfo; // example 1
$post_info = $post->my_post_info; // example 2

Laravel允许上述两种方法,但是没有合理的处理使用两种命名造成的冲突。

Repository

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

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

3. 缓存失效

如果我们同时使用了上述两个例子,就会使其中一个缓存失效。在Model的relations变量中,缓存了已经读取过的关联Model,但是当我们用不同规则的名字去读取的时候,却会使得前一个缓存失效。例如

$post_info = $post->myPostInfo; 
// $post->relations = [‘myPostInfo’ => ..];

$post_info = $post->my_post_info;
// $post->relations = [‘myPostInfo’ => …, ‘my_post_info’ => …];

所以如果不希望缓存失效,得在项目中只使用一种命名方法去读取关系模型。Laravel推荐的是Camel Case.

使用基类

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

基类文件如下:

<?php

namespace AppHttpRequests;

use IlluminateFoundationHttpFormRequest;

class Request extends FormRequest
{
    public function authorize()
    {
        // Using policy for Authorization
        return true;
    }
}

表验证类文件参考:

<?php

namespace AppHttpRequests;

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
        ];
    }
}

1. 定义关联模型

在Laravel里面,我们可以通过定义以下Model来完成关联查询。

class MyPost extends Eloquent {
    public function myPostInfo () {
        return $this->hasOne('MyPostInfo');
    }
}

class MyPostInfo extends Eloquent {}

使用基类

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

基类文件如下:

<?php

namespace AppPolicies;

use IlluminateAuthAccessHandlesAuthorization;

class Policy
{
    use HandlesAuthorization;

    public function __construct()
    {
        //
    }

    public function before($user, $ability)
    {
        if ($user->isAdmin()) {
            return true;
        }
    }
}

授权策略类文件参考:

<?php

namespace AppPolicies;

use AppModelsUser;
use AppModelsPhoto;

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

4. toArray() 方法失效

如果同时使用了两者,另外一个问题就是导致Model::toArray()失效。因为toArray()方法首先去relations中查找Snake Case命名的关联模型,没有的话才去看Camel Case的。

所以如果用到了toArray()方法来转换Model,切忌同时使用两者。

代码风格

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

利用 Trait 来扩展数据模型

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

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

开发专用扩展包

路由闭包

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

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

数据模型

Laravel 安全实践

Restful 路由

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

图片 1

Alt text

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

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

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

批量赋值

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

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

<input name="is_admin" value="1" />

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

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

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

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

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

推荐阅读篇

  • PHP开发规范

路由器

控制器

表单验证

加载

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

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

public function register()
{
    if ($this->app->environment() == 'local') {
        $this->app->register('LaracastsGeneratorsGeneratorsServiceProvider');
    }
}