PHP: операторы switch-case со строками неэффективны? - PullRequest
2 голосов
/ 12 апреля 2011

В моем слое PHP я получаю коды ошибок в виде строк ("NOT_FOUND", "EXPIRED" и т. Д.).Это небольшой список возможных строк, возможно, дюжина.

Какой самый эффективный способ справиться с этим?Использование switch-case для строковых констант, хранящихся в классе, или я должен сначала разобрать их по числам (или чему-то еще)?Или PHP достаточно умен, чтобы это не имело значения?

Ответы [ 3 ]

3 голосов
/ 12 апреля 2011

Вы можете рассмотреть возможность использования констант? Допустим, у вас есть класс Error и вы определите все коды ошибок там следующим образом:

class Error {
   const NOT_FOUND = 0;
   const EXPIRED = 1;
   // and so forth
}

И затем вы можете использовать их в своем коде, обращаясь к ним как Error::NOT_FOUND, и оператору switch не нужно сравнивать строки, но он имеет простые значения без ухудшения читаемости.

2 голосов
/ 12 апреля 2011

Это действительно зависит от того, что вы хотите сделать со строками. Вы хотите выводить сообщения об ошибках? Тогда вместо оператора case вы можете использовать следующую таблицу:

$messages = array(
  'NOT_FOUND' => 'The file was not found',
  'EXPIRED' => 'The cookie expired'
  // ETC
);
echo empty($messages[$error]) ? "Unknown error" : $messages[$error];

В PHP 5.3 вы также можете хранить код в массиве для обработки ситуаций с ошибками:

$handlers = array(
  'NOT_FOUND' => function() { /* Error handling code here */ },
  'EXPIRED' => function() { /* Other error handling code */ }
 );
 if(!empty($handlers[$error])) { 
   $handler = $handlers[$error];
   $handler();
 }
 else {
   echo "Could not handle error!"; die();
 }

Используя такую ​​технику, вы избегаете падежных операторов, занимающих несколько страниц.

С PHP <5.3 вы можете посмотреть на <code>call_user_func для динамической диспетчеризации функций обработки ошибок.

0 голосов
/ 12 апреля 2011

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

switch (className::{$errorCode}) { // $errorCode == name of the constant, like NOT_FOUND
// Cases here.
}
...