PHP Laravel:比这些if语句更好的方法

PHP Laravel:比这些if语句更好的方法,php,laravel,eloquent,Php,Laravel,Eloquent,我需要为新创建的价格分配佣金。佣金可根据客户、类型和价格进行调整。所以,如果有一个类型佣金,它应该首先得到它,回退到客户端,回退到默认值 我的代码可以工作,但感觉有点太“if-y”。也许有更好的方法 private function addDefaultOnlineCommission(Price $price) { $defaultCommission = (object)Commission::DEFAULT_COMMISSIONS; $typeCom

我需要为新创建的价格分配佣金。佣金可根据客户、类型和价格进行调整。所以,如果有一个类型佣金,它应该首先得到它,回退到客户端,回退到默认值

我的代码可以工作,但感觉有点太“if-y”。也许有更好的方法

  private function addDefaultOnlineCommission(Price $price)
   {
       $defaultCommission = (object)Commission::DEFAULT_COMMISSIONS;

       $typeCommission = $price->type->commissions()
           ->where('is_online', '=', true)->first();

       $clientCommission = $price->type->client->commissions()
           ->where('is_online', '=', true)->first();


       if (!$clientCommission && !$typeCommission) {
           $commission = $defaultCommission;
       }

       if ($clientCommission && !$typeCommission) {
           $commission = $clientCommission;
       }

       if ($typeCommission) {
           $commission = $typeCommission;
       }

       $price->commissions()->create([
           'commission_type'   => $commission->commission_type,
           'commission_value'  => $commission->commission_value,
           'min_value'         => $commission->min_value,
           'is_online'         => true,
           'valid_from'        => Carbon::now()->format('Y-m-d H:i:s'),
       ]);
   }
这个怎么样

   if (!$clientCommission && !$typeCommission) {
       $commission = $defaultCommission;
   } else if ($clientCommission && !$typeCommission) {
       $commission = $clientCommission;
   } else {
       $commission = $typeCommission;
   }

纯粹固执己见,但我会用空合并运算符来处理:

$commission = $typeCommission ?? $clientCommission ?? $defaultCommission;

这将使用第一个非空值。因此它设置了从左到右的优先级。

我认为函数看起来是“if-y”,因为您的语句比必须的更复杂。此外,您总是加载所有的备用方案,这在任何情况下都不是必需的。我将重构函数,以便在必要时只加载下一级。这可能看起来像这样:

private function addDefaultOnlineCommission ( Price $price ) {

    // load the type commission
    $commission = $price->type->commissions()->where( 'is_online', '=', true )->first();

    // if there is no type commission, check client commission
    if( empty($commission) ){
        $commission = $price->type->client->commissions()->where( 'is_online', '=', true )->first();
    }

    // if there is no client commission either, fall back to the default
    if( empty($commission) ){
        $commission = (object)Commission::DEFAULT_COMMISSIONS;
    }

    $price->commissions()->create( [
        'commission_type'  => $commission->commission_type,
        'commission_value' => $commission->commission_value,
        'min_value'        => $commission->min_value,
        'is_online'        => true,
        'valid_from'       => Carbon::now()->format( 'Y-m-d H:i:s' ),
    ] );

}
这不仅减少了函数的长度,还使其更具可读性。此外,还可以避免不必要的查询


注意:您可以将empty()替换为is_null(),因为first()在空结果中返回null。

我会说使用elseifs,但超出此范围的任何内容都可能会有点复杂。这样的问题可能会倾向于意见一致,但在CodeReviewHanks上可能会更好。你的观点是对的,但是在codereview中你只会得到一个观点:)如果第一个有效,你也可以合并实际的查询以避免产生第二个。谢谢。这看起来也是避免查询的好方法。