Это плохая модель? (Переключатель внутри / для петли foreach)

Я нахожу, что пишу код, например:

foreach($array as $key => $value) { switch($key) { case 'something': doSomething($value); break; case 'somethingelse': doSomethingElse($value); break; } } 

Есть ли лучший способ сделать это? Мне кажется грязным, но я могу просто подумать об этом.

Единственная альтернатива, о которой я могу думать, это утверждение if для каждого ключа, что не кажется лучше. Т.е.:

 if($array[0] == 'something') { doSomething($array[0]); } if($array[1] == 'somethingelse') { doSomethingElse($array[1]); } 

(или что-то типа того)

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

Сопоставление ваших функций с ключами в словаре / ассоциативном массиве является общим подходом для этой ситуации (как упоминал @jldupont) – не только в PHP, но и во многих динамических языках с ассоциативными массивами. Например, у Python и Lua даже нет оператора switch – это почти единственный способ эмуляции коммутатора.

Рассмотрим такой подход:

 <? $arr[] = "bye"; $arr[] = "hi"; function sayHi() { print("Hello.\n"); } function sayBye() { print("Goodbye.\n"); } $funcs["hi"] = sayHi; $funcs["bye"] = sayBye; foreach($arr as $k){ $funcs[$k](); } ?> 

Вывод:

 Прощай.
 Здравствуйте.

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

Это не «плохое» решение, но, как всегда, есть альтернативы. Например, вы можете избавиться от оператора switch и использовать интерпретируемый обработчик для строк. Это похоже на список указателей на функции, но вам не нужно обновлять список, чтобы добавить новое поведение; просто добавление новой функции в обработчик позаботится об этом.

 $array = array( "something" => "itsasecret", "somethingelse" => "i can't tell you", ); class Handler { static function something($value) { printf("something: %s\n", $value); } static function somethingelse($value) { printf("somethingelse: %s\n", $value); } } $handler = new Handler(); foreach($array as $key => $value) { $handler->$key($value); } 

Вероятно, вам понадобится код для дезинфекции входных строк и убедитесь, что метод существует в вашем обработчике, но это может дать вам некоторые идеи.

Я предпочитаю использовать переключатель в цикле foreach. ИМХО менее грязно, чем пучок if.

Вы можете поместить ваш переключатель в другую функцию, например:

 foreach($array as $key => $value) { doTransaction($key , $value); } ... function doTransaction($key, $value){ switch($key) { case 'something': doSomething($value); break; case 'somethingelse': doSomethingElse($value); break; } } 

Существует (по крайней мере) другая возможность: используйте поиск в словаре для отправки работы функции.

Поиск функции с использованием ключа $ в качестве «ключа», получения ссылки на функцию и применения ее с параметром $ value в качестве параметра.

Простите меня, но мой PHP-fu немного ржавый.

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

Пробегайте каждую версию – с помощью переключателя и с if – миллионом раз. Время каждого прогона.

Сообщите нам, какой из них работает быстрее.

В этом нет ничего плохого.

Если у вас есть только 2 или 3 предмета, я бы пошел с помощью if только ради сложности кода. Если у вас больше 5, я бы определенно пошел с переключателем …