It looks there is an error in PHP with boolean arithmetic in loops.
In this particular example I test if all important form fields (represented by objects) were set. The var_dump
is for debuging purposes.
$allset = true;
foreach ($forms as $one):
$allset 开发者_StackOverflow中文版= $one->wasSet() and $allset;
endforeach;
var_dump($allset);
foreach ($more as $one):
$allset = $one->wasSet() and $allset;
endforeach;
var_dump($allset);
$allset = $iwasthere->wasSet() and $allset;
var_dump($allset);
This code may fail. It is possible the first dump returns false and the second returns true.
My question.
How can I avoid this error and have short and clean code?
P.S.
I use if
blocks for now.
The problem here is that the =
operator has a higher precedence than and
operator. So the assignment expression is just part of a logical expression and the whole expression is equivalent to this:
($allset = $one->wasSet()) and $allset;
Either put the logical expression in parentheses or use &&
instead of and
:
$allset = ($one->wasSet() and $allset);
$allset = $one->wasSet() && $allset;
Shouldn't there be a
$allset = true;
before the second foreach loop?
(code below is compatible with php 5 only)
Your code has another mistake:
$allset = $iwasthere->wasSet(); // this overwrites all previous checks
Should be
$allset = $iwasthere->wasSet() && $allset;
Also it would be better if you have a class for form instead array of fields
class Form{ protected $fields = array(); function addField($field){ $this->fields = $field; return $field; } function allSet(){ $allSet = true; foreach($this->fields as $field){ $allSet = $allSet && $field->wasSet(); } return $allSet; } }
to add fields you can (option one) extend the class:
RegisterForm extends Form{
function __construct(){
$name = $this->addField(new FormField('name'));
$action = $this->addField(new FormField('action'));
$action->hidden = true;
}
}
then you use it like this:
$form = new RegisterForm();
Or (option two) you can add fields after you create the form
$form = new Form();
$name = $form->addField(new FormField('name'));
....
and then usage is pretty simplified:
....
if(!$form->allSet()){ // that looks like clean code
...error...
}
if you have 2 forms:
$allSet = $form1->allSet() && $form2->allSet();
if( !$allSet ){
...error...
}
if you need to make the same loop twice your code is already diry
精彩评论