2013-10-01 2 views
0

У меня есть массив со строками и числами как индексы, которые я итерацией по сравнению с использованием «» Еогеасп петли и переключателем заявления: -переключателя лечения целого числа как «» truthy значения

$test = array(1, 2, 3, 'test' => 'value'); 
foreach ($test as $k => $v) 
{ 
    switch ($k) 
    { 
     case 'test': 
      echo $v . "\n"; 
      break; 
    } 
} 

Выходом.

1 
value 

Переключатель, похоже, обрабатывает строку 'test' и целое число 1 как одно и то же, это не кажется правильным.

+1

положить перерыв в каждом случае заявление. – nurakantech

+0

@vascowhite Я нашел его. Но проблема 0 скрыта в трехлетнем комментарии и решена так же: преобразование в строку. – ortreum

+0

Я отозвал свой голос, мои извинения за то, что я не правильно прочитал вопрос. Это интересная проблема, если я найду хорошее решение, я отправлю ответ. – vascowhite

ответ

1

Решение заключается в преобразовании индексов в строки.

switch ($k . '') 
{ 
    ... 
} 
0

Вы должны использовать break для этого избежать как этот

switch ((string)$k) 
{ 
    case 'test': 
     echo $v . "\n"; 
     break; 
    default: echo "-\n"; 
} 
+0

Это не проблема, я отредактировал вопрос, чтобы сделать его более понятным. – vascowhite

+0

@vascowhite Я исправлю его ответ – Winston

+0

Это не имеет никакого отношения к перерыву; – vascowhite

1

Я не 100% уверен, почему это происходит, но я подозреваю, что, как switch использует свободные сравнения (== а не ===), он видит 0 как «правдивый» и поэтому выполняет ваш случай.

Один из способов заключается в проверке, что передаваемое значение является строкой: -

$test = array(1, 2, 3, 'test' => 'value'); 
foreach ($test as $k => $v) 
{ 
    switch (is_string($k)) 
    { 
     case 'test': 
      echo $v . "\n"; 
      break; 
    } 
} 

See it working.

Однако я не уверен, что это лучше, чем ваше решение, хотя для меня это имеет смысл.

3

Это связано с тем, что любая строка, если она по-разному сравнивается с целым числом, преобразуется в целое число. Если строка не начинается с числового символа, результат этого приведения обычно равен нулю.

$test = 'test'; 
var_dump((int) $test); // int(0) 

case сравнения в switch являются рыхлые сравнения, а не строгие (== против ===).

Учитывая вышеизложенное, вот что происходит в цикле, так как вы переключаетесь на ключа (0-индексированные) не значение:

0 == 'test'  // true 
1 == 'test'  // false 
2 == 'test'  // false 
'test' == 'test' // true 

См string conversion to numbers для получения дополнительной информации.

1

Ваш ответ прост.

Поскольку switch выполняет сравнение с нормальным PHP типа-судейством, ваш первый элемент массива будет пройти проверку, так как он есть 0 ключа, который равен test, потому что (INT) бросание 'test' является 0.

Вы можете присвоить любое значение элементу с индексом 0 и увидеть его в вашей проверке. Но если вы будете делать

$test = array(1=>1,2=>2, 3=>3, 'test' => 'value'); 

-you'll видеть только 'value' прошел чек

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