Zend Studio сообщает предупреждение: задание в состоянии. Это так плохо?

Недавно я начал использовать Zend Studio, который сообщил как предупреждение о следующем типе кода:

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

Чтобы остановить предупреждение, код должен быть написан следующим образом:

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

Почему это помечено как предупреждение? Это так плохо?

Я понимаю, что предупреждение может быть предназначено для предотвращения таких ошибок:

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

который никогда не завершится, потому что $a присваивается 1, что, в свою очередь, возвращает 1 оператору while, а не проверяется на $a и возвращает false оператору while, когда $a не равен 1.

Простая ошибка, которая может подтвердить предупреждение, разрешено, но так же забывают добавить дополнительную $f = fetch($q) в конце блока while во втором примере, что также приведет к циклу, который никогда не завершится. . Если я изменю свой код, чтобы удалить предупреждение, а затем забуду добавить $f = fetch($q) в конце блока while, Zend не будет предупреждать об этом!

Таким образом, удаляя предупреждение о распространенной ошибке, я настраиваю себя на другую распространенную ошибку.

Из кастрюли, в огонь.


person Stacey Richards    schedule 10.03.2009    source источник


Ответы (8)


Таким образом, вам не придется переписывать весь свой код без веской причины: вы можете отключить обнаружение этой потенциальной ошибки программирования в Window | Настройки, PHP | Семантический анализ.

person winkbrace    schedule 10.12.2010
comment
На самом деле, я решил пойти с принятым ответом, потому что он функционально более логичен. Я буду избегать выполнения голых присваиваний в качестве условных выражений. - person Erick Robertson; 02.04.2013
comment
Zend Studio необходимо перестроить все проекты из-за этого изменения. Час спустя я понимаю, что нажал «Применить», и теперь беспокоюсь, не придется ли ему снова перестраивать BS. - person Exit; 01.05.2019

Вероятно, это помечено как предупреждение, потому что люди часто используют "=" по ошибке, когда имеют в виду "==".

eg:

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

Это никогда не завершится, хотя, если вы думали, что написали "==", так и должно быть.

person Jesse Rusak    schedule 10.03.2009
comment
Это, конечно, связано с тем, что PHP выбрал = (равно) в качестве оператора присваивания, а не := (двоеточие равно). - person garrow; 10.03.2009
comment
На выбор PHP повлиял C. Как и любой другой язык. Не обвиняйте PHP в том, что C сделал популярным. - person epochwolf; 10.03.2009
comment
Один из способов обнаружить такую ​​ошибку — инвертировать оператор: 1 == $a. PHP выдаст ошибку, потому что левая часть не может быть назначена. - person Maxence; 12.08.2011

Zend Studio пытается помочь вам в написании лучшего кода, который легче отлаживать. Отключение семантической проверки — плохая идея, она просто заметает потенциальные проблемы под ковер, и вы упускаете из виду настоящие проблемы. Это веская причина! Не избегайте предупреждающих сообщений, игнорируя их, изменяйте свой код, реализуя правильное решение.

person Martin    schedule 24.02.2011

Как вы хорошо знаете, Zend Studio построена на eclipse, Java IDE. На языке Java запрещено делать что-то вроде этого:

String s;
while (s = getName()) {
    ...
}

Это связано с тем, что даже если 'getName' возвращает нулевое значение, оно будет присвоено 's', а приведение типов между объектами и логическими значениями (которое является обязательным типом в операторах условия) немного более субъективно, чем в PHP, поэтому оно выдаст исключение во время компиляции.

Ситуация в PHP может быть другой, но разработчики Zend почему-то решили оставить это предупреждение активным по умолчанию, вы можете отключить его, как упоминалось ранее, но я думаю, что это поможет вам, когда произойдет реальное присваивание в условии.

Очистить предупреждение довольно просто, просто назначив результаты, а затем сравнив их следующим образом:

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

Вместо:

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

Как видите, вам не нужны дополнительные пакеты кода.

В любом случае, это просто предупреждение, вам не нужно о них сильно беспокоиться.

person Roger Chacon    schedule 11.08.2011

На самом деле, я думаю, что на ваш вопрос уже был дан ответ. Но для решения вашей реальной проблемы, я думаю, это может помочь.

//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);
}

Это должно помочь, и сообщение «Назначение в состоянии» должно исчезнуть.

В качестве примечания: используйте оператор равенства так же, как и при отрицании. Вы также используете знак равенства с другими операторами, такими как

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

и не

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

Это помогает мне всегда помнить, как сравнивать значения, а не присваивать им значения.

person easyDaMan    schedule 28.09.2010

Причина, по которой это плохо, заключается в том, что многие люди используют "=", когда означают "=="

Оператор = вернет присвоение слева, поэтому, если вы используете if($x=true), код внутри if будет запущен, если вы используете if($x=false), код не будет запущен. Это изящный трюк, который может сэкономить одну или две строки кода, но он также опасен, потому что, если вы имели в виду if($x == false) и набрали if($x = false), это будет ошибка, которую будет трудно отследить.

person epochwolf    schedule 10.03.2009

Нет, мои друзья все задания в условии генерируют это предупреждение. Я не хочу полностью отключать это, так как = вместо == это синтаксическая ошибка, к которой я склонен. Что касается вопроса, зачем это нужно, я воспользуюсь примером из Руководства по PHP. Это из раздела «Улучшенные расширения MySQL» или mysqli:

$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"]);
    }

к сожалению, я разработал свои функции базы данных, используя эту технику, и пытаюсь использовать их в Zend Studio. Эта ошибка появляется достаточно раз, чтобы быть настоящей болью. Я перефразирую предложения здесь, так как я ценю однозначный код, однако я также собираюсь перейти к руководству по PHP и предложить изменить пример, чтобы использовать лучший стиль. Возможно, некоторые из вас могли бы сделать то же самое, и мы могли бы улучшить документацию?!

person Sinthia V    schedule 30.09.2010

person    schedule
comment
+1 просто, мило. Делает намерение выражения более ясным и подавляет предупреждение от студии. - person Fatmuemoo; 11.12.2010