2010-02-07 2 views
2

Загадка мне это ... в цикле while($row = mysql_fetch_assoc($result) and $runningOK), если вместо используется оператор PHP &&, тогда mysql_fetch_assoc терпит неудачу и возвращает только число 1 при запуске.Почему этот цикл возвращает 1 при использовании && вместо 'и'?

Я пробовал mysql_fetch_array() и на месте, и у меня все еще есть проблема 1. Это когда и только тогда, когда я заменяю && на and, как и текущий while, вывод правильных строк.

Я поставил операторы отладки до, внутри и после, чтобы обеспечить это. Я хотел бы знать, является ли это причудой PHP или чем-то, что я не мог объяснить.

// Query 
$selectQuery = "SELECT * FROM jobs_cache LIMIT 20"; 
// Run the Selection Query. 
$result = mysql_query($selectQuery) 
    or die('Query Failed: '.mysql_error()); 

// Loop through results. 
$runningOK = TRUE; 
$resubmitList = array(); 

while($row = mysql_fetch_assoc($result) and $runningOK) 
{ 
    // Resubmit The Job 
    try 
    { 
     $client->addTaskBackground($row['function_name'],$row['job_data']); 
     $resubmitList[] = (string)$row['job_cache_id']; 
    } 
    catch(Exception $e) 
    { 
     echo "Error adding task for job id: " . $row['job_cache_id']; 
     $runningOK = FALSE; 
    } 
} 

ответ

9

Это связано с приоритетом оператора. См. the manual для получения более подробной информации ... вот соответствующая часть.

// "& &" имеет больший приоритет, чем "и"

// Результат выражения (правда & & ложь) присваивается $ г
// Действует как: ($ г = (истина & & ложь))

$ г = истинная & & ложь;

// Константа верно присваивается $ ч, а затем ложно игнорируется
// Действует как: (($ ч = истина) и ложь)

$ ч = истина и ложь;

var_dump ($ g, $ h);

BOOL (ложь)
BOOL (истина)

Так, с & &, результат выражения присваивается верно, который оценивает 1. С и, она вычисляется в результате функции mysql - больше того, чего вы хотите, я считаю.

Кстати, вы также можете использовать break, чтобы устранить необходимость переменной $ runningOK.Для этого удалите and $runningOK из условия while и смените $runningOK = FALSE; на break;, и он завершит цикл, если активирован блок catch.

+0

Это снайпер из гораздо более крупного ядра рабочего Gearman, работа в порядке используется в нескольких разделах, чтобы гарантировать, что у нас есть действительные вызовы SQL и работоспособность. Какое замечательное и ясное объяснение приоритета! – Urda

+0

Также решетки на 1000 репутации :) – Urda

+2

Спасибо! Я праздную мороженое. – JAL

1

Попробуйте это:

while(($row = mysql_fetch_assoc($result)) and $runningOK) 

Там может быть путаница, так как он оценивает mysql_fetch_assoc($result) and $runningOK ИСТИНА, который затем присваивает $row, который в данном случае является такой же, как 1

Если вы добавите скобки, вы, скорее всего, можете использовать либо &&, либо and, так как вы должным образом разделите две оценки.

Это побочный эффект альтернативных синтаксисов, я уверен.

+0

Мои деньги на этом объяснении. –

+0

@ Дань, я тоже об этом. –

1

Оператор присваивания = и два логических операторы && и AND имеют different precedence: && выполняются перед =, который, в свою очередь, выполняется перед AND

Поэтому в основном заявление:

$row = mysql_fetch_assoc($result) AND $runningOK 

равен до:

($row = mysql_fetch_assoc($result)) AND $runningOK 

в то время как заявление:

$row = mysql_fetch_assoc($result) && $runningOK 

равно:

$row = (mysql_fetch_assoc($result) && $runningOK) 

В последнем случае вы просто присваивающее значение 1 (если mysql_fetch_assoc возвращает значение) или 0.

Смежные вопросы