PHP If-Else-Finally

时间:2014-08-11 08:56:59

标签: php if-statement

我正在寻找更聪明的方法来解决我所谓的 if-else-finally 案例。

案例
根据不同的条件,对象的属性需要不同的值。仅当此属性已更改时,才将对象保留为DB。

示例(伪代码)

if _condition-A_ then
    set object.property to value-A
else if _condition-B_ then
    set object.property to value-B
else if _condition-C_ then
    set object.property to value-C
finally
    object.persist()

我的解决方案

$changed = false;
if ($conditionA) {
    $changed = true;
    $this->property = 'A';
} elseif ($conditionB) {
    $changed = true;
    $this->property = 'B';
} elseif ($conditionC) {
    $changed = true;
    $this->property = 'C';
}
if ($changed) {
    $this->save();
}

是否有更好/更智能的解决方案? switch-case-default构造是不可能的,因为条件是由每个if语句中不同的较小部分条件复合而来的。

4 个答案:

答案 0 :(得分:10)

您可以通过这种方式避免重复$changed = true;

$changed = true;
if ($conditionA) {
    $this->property = 'A';
} elseif ($conditionB) {
    $this->property = 'B';
} elseif ($conditionC) {
    $this->property = 'C';
} else {
    $changed = false;
}
if ($changed) {
    $this->save();
}

答案 1 :(得分:2)

我刚玩过php array

if ( $property = array_search( true, array(
    'A' => $conditionA ,
    'B' => $conditionB ,
    'C' => $conditionC 
)) ){
    $this->property = $property;
    $this->save();
};

答案 2 :(得分:1)

虽然这不是我的问题的真正答案(因为我已经接受了),但我想在这里发布一些关于使用三元运算符的想法,并在这里使用第三方 {{1}功能。

iif代表 Immediate if ,而implementation 可以

iif

我告诉可能因为它不是PHP的原生部分,如果你想使用它,你需要在全球某处定义它,完全取决于你如何定义它,甚至可能

function iif($condition, $true, $false) {
    return ($condition ? $true : $false);
}

(仅举例)。因此,人们不可能永远不确定最终会发生什么臭function iif($condition, $true, $false) { return ($condition && $true ? true : $false); } 。如您所见,此iif可以成功使用 ternary operator ,最终可以直接使用它们。因此,而不是运行此黑盒

iif

使用

时更明亮(在光照条件下)
$this->property = iif($conditionA, // what does this 'iif' do???
    'A',
    iif($conditionB, // what does this 'iif' do???
        'B',
        iif($conditionC, // what does this 'iif' do???
            'C','NONE')));

正如您所看到的,即使使用递归,三元运算符的使用也更具可读性和可预测性。

现在我想告诉你如何创建这样复杂的三元运算符。想象一下,您正在将数据下载到CSV($this->property = $conditionA // ok, if matches then 'A' ? 'A' : $conditionB // ok, if matches then 'B' ? 'B' : $conditionC // ok, if matches then 'C' otherwise 'D' ? 'C' : 'D'; seprarated)文件中。您必须仅在检索到的数据中过滤CSV列,并选择;值(如果存在)。三元非常简单:

trim

运行正常一段时间,直到有人来告诉你他想要显示 / 而不是 1 /两列中 0 。所以,好吧,没什么大不了的,让我们稍微修改一下这个条件:

foreach ($fields as $field) {
    $row[] = array_key_exists($field, $item) // if field is present and contains value trim it
        ? trim($item[$field])))
        : ''; // otherwise use empty string
}

好的......现在它有点复杂,因为我们添加了一个级别,内层的真实表达式包含另一个三元组。如果同一个人又来了并告诉你添加两个新列,可能有值foreach ($fields as $field) { $row[] = array_key_exists($field, $item) // if field is present and contains value ? ($field == 'col1' || $field == 'col2' // if it is a 'col1' or 'col2' field ? ($item[$field] ? 'Yes' : 'No') // display 'Yes'/'No' : trim($item[$field])) // otherwise trim the value : ''; // otherwise use empty string } NULL0,并为每个列显示{{1} },1''?那么,它可能看起来像这样:

No

在这一点上,我停了一会儿,开始考虑重写Yes哪个会有更多的可读性但是我必须把它写在更多的行中,我不想做。代码并没有那么混乱,它的结构很好,所以每个人都可以看到新递归的开始和结束位置。但这是可能的,因为条件本身非常简单和单层。

如果每个三元组的条件更复杂,我会避免使用三元运算符并坚持foreach ($fields as $field) { $row[] = array_key_exists($field, $item) ? ($field == 'col1' || $field == 'col2' ? ($item[$field] ? 'Yes' : 'No') : ($field == 'col1_1' || $field == 'col2_2' ? ($item[$field] === 1 ? 'Yes' : $item[$field] === 0 ? 'No' : '') :trim($item[$field]))) : ''; } 以保持可读性。

答案 3 :(得分:0)

您可以为属性值创建条件的映射。

概念示例:

$conditionA = false;
$conditionB = true;
$conditionC = false;

$conditions = [
  'conditionA' => 'A',
  'conditionB' => 'B',
  'conditionC' => 'C'
];

foreach($conditions as $conditionName => $conditionValue) {
    if (!empty($$conditionName)) {
        $this->property = $conditionValue;
        $this->save();
        break;
    } 
}