views:

1286

answers:

6

I have recently started using Zend Studio which has reported as warning the following type of code:

$q = query("select * from some_table where some_condition");
while ($f = fetch($q)) {
  // some inner workings
}

To stop the warning the code needs to be written like this:

$q = query("select * from some_table where some_condition");
$f = fetch($q);
while ($f) {
  // some inner workings
  $f = fetch($q);
}

Why is this marked as a warning? Is it so bad?

I understand that the warning may be designed to stop errors like this:

$a = 1;
while ($a = 1) {
  // some inner workings
  $a++;
}

which will never terminate because 1 is being assigned to $a which in turn returns 1 to the while statement, rather than being tested against $a and returning false to the while statement when $a is not 1.

Easy error to make which may validate a warning, granted, but so is forgetting to add the extra $f = fetch($q) at the end of the while block in the second example which will also result in a loop that will never terminate. If I change my code to remove the warning and then forget to add the $f = fetch($q) at the end of the while block Zend won't warning be about that!

So by removing the warning concerning a common error I'm setting myself up for a different common error.

Out of the pan, into the fire.

+4  A: 

This is probably marked as a warning because people often use "=" by mistake when they mean "==".

eg:

$a = 1
while($a = 1) {
   $a++;
}

This will never terminate, though if you thought you'd written "==", it should.

Jesse Rusak
This is of course due to PHP's choice of = (equals) as the assignment operator, as opposed to say := (colon equals).
garrow
PHP's choice was influenced by C. As has just about every other language. Don't blame PHP for something C made popular.
epochwolf
A: 

The reason it's bad is alot of people use "=" when then meant "=="

The = operator will return the assigment to the left so if you use if($x=true) the code within the if will be run, if you use if($x=false) the code will not be run. It's a neat trick that can save a line or two of code but it's also dangerous because if you meant if($x == false) and typed if($x = false) it will be a bug that can be difficult to track down.

epochwolf
+3  A: 

while ( ($row = $sql->db_Fetch("MYSQL_ASSOC")) != false)

Iurii
A: 

IMHPO... inline assignments SHOULD be allowable without throwing a warning...

Dok
A: 

Actually, I guess your question has already been answered, somewhat. But to address your actual problem, I think this might help.

//i dont know what is returned if there are no more records to fetch...
//but lets assume it is a boolean value
while (($f = fetch($q))!= false)
{
    $this->doSomethingVeryImportantThatMakesYourBossHappy($f);
}

That should do the trick and the "Assignment in condition"-message should disappear.

As a sidenote: use the equals operator the same way as when you negate stuff. You also use the equals sign with other operators like

if ($falseness != false){$trueness = true}

and not

if ($falseness ! false){$trueness = false}

That helps me to always remember how to compare values and not assign values to them.

easyDaMan
A: 

Nay my friends all assignments in the condition generate this warning. I do not want to turn this off completely, as = instead of == is a syntax error i am prone to. As for question of why it is necessary, I will use an example from the PHP Manual. This is from the section on the "MySQL improved" extensions or mysqli:

Example #1 Object oriented style
<?php
$mysqli = new mysqli("localhost", "my_user", "my_password", "world");

/* check connection */
if (mysqli_connect_errno()) {
    printf("Connect failed: %s\n", mysqli_connect_error());
    exit();
}

$query = "SELECT Name, CountryCode FROM City ORDER by ID DESC LIMIT 50,5";

if ($result = $mysqli->query($query)) {

    /* fetch associative array */
    while ($row = $result->fetch_assoc()) {
        printf ("%s (%s)\n", $row["Name"], $row["CountryCode"]);
    }

    /* free result set */
    $result->close();
}

/* close connection */
$mysqli->close();
?>

unfortunately, I have developed my database functions using this technique and am trying to use them in Zend Studio. This error is popping up enough times to be a real pain. I thank you in advance!

Sinthia V

related questions