PHP:仅在所有变量都存在时才执行计算,而不使用条件


PHP: Only execute calculation if all variables exist — without using conditional

因此,在将一些用户输入保存到数据库之前,我需要进行大量例行计算。

    $cData['cCashFlow'] = $uData['uMonthlyIncome'] - $uData['uMonthlyExpenses'];
    $cData['cLiquidAssets'] = $uData['uCashSavings'] + $uData['uRetirementSavings'] + $uData['uOtherInvestments'];
    $cData['cDebt'] = $uData['uStudentLoans'] + $uData['uCreditCardDebt'] +$uData['uAutoLoanDebt'] + $uData['uOtherDebt'];
    $cData['cConsumerDebt'] = $uData['uCreditCardDebt'] + $uData['uAutoLoanDebt'] + $uData['uOtherDebt'];
    $cData['cLiquidNetWorth'] = $cData['cLiquidAssets'] - $cData['cDebt'];
    $cData['cMonthlyDebt'] = $uData['uStudentLoanPayments'] + $uData['uAutoLoanPayments'] + $uData['uCreditCardPayments'] + $uData['uOtherDebtPayments'];
    $cData['cHomeEquity'] = $uData['uHomeValue'] - $uData['uMortgageBalance'];
    $cData['cNetWorth'] = $cData['cLiquidNetWorth'] + $cData['cHomeEquity'];

$cData是计算的数据,$uData来自用户。

不会在每次保存时执行某些计算,因为用户可能尚未填写所有字段。

当然,我可以将每个计算包装在一个条件中:

if($uData['uMonthlyIncome'] && $uData['uMonthlyExpenses']) :
    $cData['cCashFlow'] = $uData['uMonthlyIncome'] - $uData['uMonthlyExpenses'];
endif;

但它会变得非常混乱和劳动密集型,特别是如果我必须添加更多这些计算。

有没有一种简单的方法可以在计算中的所有变量都存在时才执行这样的计算?

您可以通过将其包装到函数中(期望它在类中)来使条件更具语义性:

private $uData;
private function isFilled()
{
    // get all function arguments as an array
    $args = func_get_args();
    // check each argument as an index to uData is empty 
    foreach ($args as $arg) {
        if (empty($this->uData[$arg])) {
            return false;
        }
    }
    return true;
}
public function process()
{
    $this->uData = $uData;
    if ($this->isFilled('uMonthlyIncome', 'uMonthlyExpenses')) {
        // do the calculations
         $cData['cCashFlow'] = $this->uData['uMonthlyIncome'] - $this->uData['uMonthlyExpenses'];
    }
}

如果重点是维护可读的代码,你可以使用内联条件并使用对齐来摆脱混乱。

$cData['cCashFlow']     = isset($uData['uMonthlyIncome']) && !empty($uData['uMonthlyIncome']) ? $uData['uMonthlyIncome'] - $uData['uMonthlyExpenses']                               : null;
$cData['cLiquidAssets'] = isset($uData['uCashSavings'])   && !empty($uData['uCashSavings'])   ? $uData['uCashSavings'] + $uData['uRetirementSavings'] + $uData['uOtherInvestments'] : null;

还干净吧?如前所述,您可以将条件包装在一个函数中,该函数接收必须检查的键并返回布尔值。

这是我最终做的事情:

我构建了一个回调函数来补充array_sum:

function array_subtract($array){
  $result = $array[0];
  foreach($array as $key => $value) :
    if($key !== 0) :
      $result -= $value;
    endif;
  endforeach;
  return $result;
}

然后,我构建了一个函数来检查所有输入变量,然后处理计算(如果所有输入都存在):

public function calculator($function, $args){
  foreach ($args as $arg) :
    if($arg === null) :
      return null;
    endif;
  endforeach;
  return $function($args);
}

然后我调用了"checker"函数,并将回调函数和数据输入为数组:

$cData['cCashFlow'] = $this->calculator('array_subtract', array($uData['uMonthlyIncome'], $uData['uMonthlyExpenses']));
$cData['cLiquidAssets'] = $this->calculator('array_sum', array($uData['uCashSavings'], $uData['uRetirementSavings'], $uData['uOtherInvestments']));
$cData['cDebt'] = $this->calculator('array_sum', array($uData['uStudentLoans'], $uData['uCreditCardDebt'], $uData['uAutoLoanDebt'], $uData['uOtherDebt']));
$cData['cConsumerDebt'] = $this->calculator('array_sum', array($uData['uCreditCardDebt'] + $uData['uAutoLoanDebt'] + $uData['uOtherDebt']));
$cData['cLiquidNetWorth'] = $this->calculator('array_subtract', array($cData['cLiquidAssets'], $cData['cDebt']));
$cData['cMonthlyDebt'] = $this->calculator('array_sum', array($uData['uStudentLoanPayments'], $uData['uAutoLoanPayments'], $uData['uCreditCardPayments'], $uData['uOtherDebtPayments']));
$cData['cHomeEquity'] = $this->calculator('array_subtract', array($uData['uHomeValue'], $uData['uMortgageBalance']));
$cData['cNetWorth'] = $this->calculator('array_sum', array($cData['cLiquidNetWorth'], $cData['cHomeEquity']));

如果每个计算的所有输入值都不存在,则 NULL 将存储到数据库中,这正是我想要的。

试试这样的事情

<?php
$uData = array();
@$uData['bla'] = $_POST['bla'];
@$uData['blaa'] = $_POST['blaa'];
@$uData['blaaa'] = $_POST['blaaa'];
$userInputs = array('bla', 'blaa', 'blaaa');
function checkUserInput($Inputs, $uData){
foreach($Inputs as $value){
    if($uData[$value] == null){
         return false;
    }
}
return true;
}
if(checkUserInput($userInputs, $uData) == true)
{
    echo "All here!";
}