laravel项目开发规范第一天

前言

本次实践是对一个现有的app的项目的后台进行代码规范,通过对比来实现bad code 到 good code 的一次实践
目的是提高代码的可读性

关于规范

  • 高效编码 - 避免了过多的选择造成的『决策时间』浪费;
  • 风格统一 - 最大程度统一了开发团队成员代码书写风格和思路,代码阅读起来如出一辙;
  • 减少错误 - 减小初级工程师的犯错几率。

开发哲学

DRY –「Don’t Repeat Yourself」不写重复的逻辑代码;
约定俗成 - 「Convention Over Configuration」,优先选择框架提倡的做法,不过度配置;
KISS - 「Keep it Simple, Stupid」提倡简单易读的代码,不写高深、晦涩难懂的代码,不过度设计;
主厨精选 - 让有经验的人来为你选择方案,不独创方案;
官方提倡 - 优先选择官方推崇的方案

感受

在一个项目中如果出现风格不统一的写法,即使几种写法你都能明白,也是规则允许的写法,即便是单人开发的项目,你在阅读过程中,也会因为这个原因出现短暂的停顿或者在写代码时会出现一个小的决策选择,所以风格的统一是非常重要的,尤其是多人开发的项目中,更应该注意开发规范。

与其无休止的争论哪种选项最好,还不如只知道 一种选项。这 一种选项 能覆盖大部分的用例,且兼备开发效率、程序执行效率、扩展性、安全性等最佳实践,当再次遇到此类需求时,毫不犹豫地使用这 一种选项 直接了当地解决问题。

决策已提前做好,没必要浪费时间多次决策,节省时间,提高效率。

开发规范一旦统一,所有团队成员严格遵守,你会发现,你的队友写的代码就如你自己写的一样,编码愉悦感提高了,整个项目代码阅读起来更加流畅,工作效率自然也会因此提高,同时代码的健壮性也得到了保障。

环境说明

一般情况下,一个项目 应该 有以下三个基本的项目环境:
Local - 开发环境
Staging - 线上测试环境
Production - 线上生产环境

关于多人开发

多人开发,我们应该保证各自计算机系统的统一,开发环境的统一,编码工具的统一,只有各方面都是统一的,才有利于形成工作流和使用经验的传承

代码风格规范

代码风格 必须 严格遵循 PSR-2 规范。

1.行文规范

  • 问题分析
    • 没必要的注释
    • 没对齐的 ->
    • 没有使用更简洁的代码
  • bad code
//地址列表
    public function fetchList(Request $request)
    {
        $data = DB::table('goldcat_address')
                ->whereNull('deleted_at')
                        ->where([
                        'user_id' => $request->user_id,
                    ])->get();

        return success($data);
    }
  • good code
    public function fetchList(Request $request)
    {
        $data = DB::table('goldcat_address')
                    ->whereNull('deleted_at')
                    ->where('user_id', $request->user_id)
                    ->get();

        return success($data);
    }

2.重复的代码片段,变量,以及没必要的else

修改前 代码字数统计2545 97行

  whereNull('deleted_at')
                    ->where([
                        'user_id' => $request->user_id,
                    ])->get();

        return success($data);
    }

    //添加地址
    public function add(Request $request)
    {
        $data = $request->all();
        if ($request->default == 1) {
            DB::table('goldcat_address')->where([
                'user_id' => $request->header('uid'),
            ])->update([
                'default' => 0,
            ]);
        }

        $id = DB::table('goldcat_address')->insertGetId($data);

        return $this->fetchOne($id);
    }

    public function fetchOne($id)
    {
        $data = DB::table('goldcat_address')->find($id);

        return success($data);
    }

    //更新
    public function update(Request $request)
    {
        $data = DB::table('goldcat_address')->find($request->id);

        if (isset($data->user_id) && $request->header('uid') == $data->user_id) {
            $addressData = $request->all();

            if ($request->default == 1) {
                DB::table('goldcat_address')->where([
                    'user_id' => $request->header('uid'),
                ])->update([
                    'default' => 0,
                ]);
            }

            unset($addressData['user_id']);
            unset($addressData['id']);
            DB::table('goldcat_address')->where([
                'id' => $request->id,
            ])
            ->update($addressData);

            return $this->fetchOne($request->id);
        } else {
            return fail('授权失败');
        }
    }

    //删除地址
    public function del(Request $request)
    {
        DB::table('goldcat_address')
        ->where([
            'id' => $request->id,
        ])
        ->update([
            'deleted_at' => date('Y-m-d H:i:s'),
        ]);

        return success('删除成功');
    }
}

修改后 代码字数统计2157 80行

all();
        if (1 == $request->default) {
            DB::table('goldcat_address')
                ->where('user_id', $request->header('uid'))
                ->update(['default' => 0]);
        }

        $id = DB::table('goldcat_address')->insertGetId($data);

        return $this->fetchOne($id);
    }

    public function update(Request $request)
    {
        $addressId = $request->id;
        $authorId = DB::table('goldcat_address')
                        ->where('id', $addressId)
                        ->value('user_id');

        if ($authorId && $request->header('uid') == $authorId) {
            $addressData = $request->all();

            if ($request->default == 1) {
                DB::table('goldcat_address')
                    ->where('user_id', $authorId)
                    ->update(['default' => 0]);
            }

            unset($addressData['user_id']);
            unset($addressData['id']);
            DB::table('goldcat_address')
                ->where('id', $addressId)
                ->update($addressData);

            return $this->fetchOne($addressId);
        }

        return fail('授权失败');
    }

    public function fetchOne($id)
    {
        $data = DB::table('goldcat_address')->find($id);

        return success($data);
    }

    public function fetchList(Request $request)
    {
        $data = DB::table('goldcat_address')
                    ->whereNull('deleted_at')
                    ->where('user_id', $request->user_id)
                    ->get();

        return success($data);
    }

    public function del(Request $request)
    {
        DB::table('goldcat_address')
            ->where('id', $request->id)
            ->update(['deleted_at' => date('Y-m-d H:i:s')]);

        return success('删除成功');
    }
}

数据查询时的一些格式规范

  • 注意WHERE条件为1个和多个时的格式统一
  • 使用新函数updateOrInsert 来代替先验证是否存在,再根据结果进行新增或者更新的操作,以使代码阅读起来逻辑性更强
//银行卡的添加
    public function cardAdd(Request $request)
    {
        //查看该用户的银行卡数量是否超过3张,超过则不能继续添加
        $count = DB::table('goldcat_bank_card')
                    ->where([
                        'uid' => $request->header('uid'),
                        'status' => 1,
                    ])
                    ->count();

        if ($count >= 3) {
            return fail('最多只能添加三张银行卡');
        }

        $card = $request->card;
        //对银行卡号进行校验,得到基本信息
        $info = BankCard::info($card);

        $validated = $info['validated'];
        if (!$validated) {
            return fail('卡号有误');
        }
 //查看该银行卡是否已经存在
        $realName = DB::table('goldcat_user_certification')
                    ->where([
                        'uid' => $request->header('uid'),
                        'status' => 1,
                    ])
                    ->value('name');
        $idCard = DB::table('goldcat_user_certification')
                    ->where([
                        'uid' => $request->header('uid'),
                        'status' => 1,
                    ])
                    ->value('identity_card_number');

        $exists = DB::table('goldcat_bank_card')->where([
            'card' => $card,
            'status' => 1,
        ])
        ->exists();
        if ($exists) {
            return fail('该银行卡已被绑定');
        }
        //对银行卡进行真实性检验:正式服调用实名信息,是否与申请人的姓名与身份证号一致
       $check = $this->juheCheck($card, $realName, $idCard);
if (!$check) {
            return  fail('认证信息不匹配,银行卡无效');
        }

        $name = $info['bankName'];
        $cardTypeName = $info['cardTypeName'];
        $bank = $info['bank'];
        $exists = DB::table('goldcat_bank_card')->where([
            'card' => $card,
        ])
        ->exists();
        if ($exists) {
            DB::table('goldcat_bank_card')
            ->where([
                'card' => $card,
            ])
        ->update([
            'uid' => $request->header('uid'),
            'card' => $card, //卡号
            'type' => $cardTypeName, //卡片类型
            'bank' => $bank,
            'name' => $name,  //银行名称
            'status' => 1,
        ]);
        } else {
            DB::table('goldcat_bank_card')
            ->insert([
                'uid' => $request->header('uid'),
                'card' => $card, //卡号
                'type' => $cardTypeName, //卡片类型
                'bank' => $bank,
                'name' => $name,  //银行名称
                'status' => 1,
            ]);
        }

        return success('添加成功');
    }

修改之后的

    //银行卡的添加
    public function cardAdd(Request $request)
    {
        $card = $request->card;

        //查看该用户的银行卡数量是否超过3张,超过则不能继续添加
        $count = DB::table('goldcat_bank_card')->where([
            ['uid', '=', $request->header('uid')],
            ['status', '=', 1],
        ])->count();

        if ($count > 2) {
            return fail('最多只能添加三张银行卡');
        }

        //对银行卡号进行校验,得到基本信息
        $info = BankCard::info($card);

        if (!isset($info['validated']) || !$info['validated']) {
            return fail('卡号有误');
        }

        //查看该银行卡是否已经存在
        $exists = DB::table('goldcat_bank_card')->where([
            ['status', '=', 1],
            ['card', '=', $card],
        ])->exists();

        if ($exists) {
            return fail('该银行卡已被绑定');
        }

        //对银行卡进行真实性检验:正式服调用实名信息,是否与申请人的姓名与身份证号一致
        $userInfo = DB::table('goldcat_user_certification')->where([
            ['uid', '=', $request->header('uid')],
            ['status', '=', 1],
        ])->select('name'.'identity_card_number')->first();

        if (!$userInfo) {
            return fail('请先完成实名认证');
        }

        $check = $this->juheCheck($card, $userInfo->name, $userInfo->identity_card_number);

        if (!$check) {
            return  fail('认证信息不匹配,银行卡无效');
        }

        $bank = $info['bank'];
        $name = $info['bankName'];
        $cardTypeName = $info['cardTypeName'];

        DB::table('goldcat_bank_card')->updateOrInsert([
            'card' => $card,                    //卡号
            'uid' => $request->header('uid'),
            'type' => $cardTypeName,            //卡片类型
            'bank' => $bank,
            'name' => $name,                    //银行名称
            'status' => 1,
        ]);

        return success('添加成功');
    }

一段有问题的代码

    //根据银行卡号返回银行卡的银行信息(银行卡位数为16.17.19)
    //预显示 输入第六位时就开始尝试解析
    public function backInfo(Request $request)
    {
        $card = $request->card;

        //对于一个六位数至十位数的数字,对其进行后补零操作,使其分别变成三个数字,分别是16位,17位,19位
        $cardLen = strlen($card);
        $zeroNum = 16 - $cardLen;
        $zero = '';
        for ($i = 0; $i < $zeroNum; ++$i) {
            $zero .= '0';
        }
        $card = $card.$zero;

        for ($i = 17; $i < 20; ++$i) {
            $card .= '0';

            $info = BankCard::info($card);
            $validated = $info['validated'];
            if ($validated) {
                return success([
                    'backName' => $info['bankName'],
                    'cardTypeName' => $info['cardTypeName'],
                ]);
            }
        }
    }
  • 问题分析
    1.错误时会没有返回值
    2.逻辑有点混乱,让人有些看不到
    3.对于大于16位的数字无法处理
    4.漏掉了对16位的数字的验证

  • 修复后的代码

    //根据银行卡号返回银行卡的银行信息(银行卡位数为16.17.18 19)
    //预显示 输入第六位时就开始尝试解析
    public function backInfo(Request $request)
    {
        $card = $request->card;

        //对于一个小于20位的数字,补0使其位数逐渐增大,在此过程中匹配信息
        for ($i = strlen($card); $i < 20; ++$i) {
            $info = BankCard::info($card);
            if ($card > 15) {
                $validated = $info['validated'];
                if ($validated) {
                    return success([
                        'backName' => $info['bankName'],
                        'cardTypeName' => $info['cardTypeName'],
                    ]);
                }
            }

            $card .= '0';
        }

        return fail('无法自动判断');
    }

一段丑陋的代码会使人失去阅读的欲望

public function rewardRead(Request $request)
    {
        $popreward20 = DB::table('goldcat_message')
            ->where(
                [
                                            'uid' => $request->header('uid'),
                                            'status' => 0,
                                            'type' => 4,
                                            'user_type' => 1,
                                            ]
            )
            ->value('type');

        //注册奖励20的弹窗
        if ($popreward20) {
            DB::table('goldcat_message')
                ->where(
                    [
                    'uid' => $request->header('uid'),
                    'type' => 4,
                    ]
                )
                ->update(
                    [
                    'status' => 1,
                    ]
                );

            return success(
                [
                'img' => 'pop-reward-20.png',
                ]
            );
        }
        //认证奖励30弹窗
        $popreward30 = DB::table('goldcat_message')
            ->where(
                [
                                            'uid' => $request->header('uid'),
                                            'status' => 0,
                                            'type' => 5,
                                            'user_type' => 1,
                                            ]
            )
            ->value('type');

        if ($popreward30) {
            DB::table('goldcat_message')
                ->where(
                    [
                        'uid' => $request->header('uid'),
                        'type' => 5,
                        ]
                )
                ->update([
                        'status' => 1,
                        ]
                );

            return success(
                [
                    'img' => 'pop-reward-30.png',
                    ]
            );
        }

        return fail('无需弹窗提醒');
    }

修复后

//认证成功奖励到账弹窗提示
    public function rewardRead(Request $request)
    {
        $popreward20 = DB::table('goldcat_message')->where([
            'uid' => $request->header('uid'),
            'status' => 0,
            'type' => 4,
            'user_type' => 1,
        ])->value('type');

        //注册奖励20的弹窗
        if ($popreward20) {
            DB::table('goldcat_message')->where([
                'uid' => $request->header('uid'),
                'type' => 4,
            ])->update(['status' => 1]);

            return success(['img' => 'pop-reward-20.png']);
        }
        //认证奖励30弹窗
        $popreward30 = DB::table('goldcat_message')->where([
            'uid' => $request->header('uid'),
            'status' => 0,
            'type' => 5,
            'user_type' => 1,
        ])->value('type');

        if ($popreward30) {
            DB::table('goldcat_message')->where([
                'uid' => $request->header('uid'),
                'type' => 5,
            ])->update(['status' => 1]);

            return success(['img' => 'pop-reward-30.png']);
        }

        return fail('无需弹窗提醒');
    }
  • 问题 阅读代码发现是要找出type为4或者为5的,并返回对应的图片和修改所返回的记录的状态为1
    //认证成功奖励到账弹窗提示
    public function rewardRead(Request $request)
    {
        $uid = 7; //$request->header('uid')
        $res = DB::table('goldcat_message')->where([
            'uid' => $uid,
            'status' => 0,
            'user_type' => 1,
        ])->where(function ($query) {
            $query->where('type', '=', 4)
                ->orWhere('type', '=', 5);
        })->select('id', 'type')->get();

        $res = $res->toArray();

        if (!$res) {
            return fail('无需弹窗提醒');
        }

        $type = $res[0]->type;
        DB::table('goldcat_message')->where([
            'uid' => $uid,
            'type' => $type,
        ])->update(['status' => 1]);
        //注册奖励20或3认证奖励30的弹窗
        return $type == 4 ? success(['img' => 'pop-reward-20.png']) : success(['img' => 'pop-reward-30.png']);
    }

代码由68行变为了26行,代码数也由2081变为了840,缩减了约60%,读起来也更加的逻辑清晰了。

你可能感兴趣的:(laravel项目开发规范第一天)