我正在寻找更聪明的方法来解决我所谓的 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
语句中不同的较小部分条件复合而来的。
答案 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
}
,NULL
和0
,并为每个列显示{{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;
}
}