开发者

Error in PHP with bool arithmetic in loops

开发者 https://www.devze.com 2023-02-20 10:53 出处:网络
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 purp

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

0

精彩评论

暂无评论...
验证码 换一张
取 消