2013-09-03 5 views
9

Я только что выпустил PHPMD в первый раз и, как ожидается, у меня есть ошибка, которую я не могу понять. ОшибкаИзбегайте использования статического доступа к Исключению

Избегайте использования статического доступа к классу 'InvalidArgumentException' в методе 'setLang'.

и код

public function setLang($val0) { 
    switch ($val0) { 
    case ENG: 
    case FRE: 
    case SPA; 
     $this->lang = $val0; 
     break; 
    default: 
     throw new InvalidArgumentException("Invalid language choice."); 
    } 
} 

Я пробовал различные вещи, но я думаю, что в конце дня Exception статический завод (???), поэтому он должен иметь статический доступ. Но, ребята PHPMD наверняка умнее меня, так что это бы их не волновало.

Почему это предупреждение существует и как его решить?

ответ

8

Идея этого предупреждения состоит в том, что если вы вставляете имена классов внутри вашего кода с помощью ключевого слова new, будет сложно поменять местами эти классы в методах тестирования и макета или заглушки, которые может вызвать их код. See the explanation в правилах PHPMD.

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

Если вы хотите избавиться от предупреждения здесь, вы можете использовать аннотацию @SupressWarnings.

+0

Спасибо. Итак, могу ли я отключить его или как-нибудь избежать? – Ben

+0

О, я должен сказать, что я просто изменил обработку исключений. Прежде чем я просто использовал 'die()', но это было неправильно. – Ben

+1

Я не intimatily familliar с PHPMD, но он должен понимать ['@ SuppressWarnings'] (http://phpmd.org/documentation/suppress-warnings.html). – complex857

2

Ahh, после небольшого поиска, я нашел ответ прямо из уст лошади.

В файлах конфигурации, расположенных по адресу yourphpdir\data\PHP_PMD\resources\rulesets, cleancode.xml имеет комментарии CDATA, которые объясняют настройку.

Это один говорит:

Статические Гости могут воспользоваться вызывают inexchangable зависимости от других классов и приводит к трудно проверить код. Избегайте использования статического доступа любой ценой, а вместо этого устанавливайте зависимости через конструктор. Единственный случай , когда допустим статический доступ, используется при заводских методах.

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

$foo->setLang("Oh noes!", new InvalidArgumentException("No lang for you.")); 
+2

Да, PHPMD успешно обнаруживает скрытую зависимость от 'InvalidArgumentException' здесь. Однако, как и @ complex857, он также прокомментировал его [ответ] (http://stackoverflow.com/users/1515540/complex857), я бы сказал, что это крайний случай, поскольку для исключения исключения обычно требуется неинжектированный класс- имя. Как и на фабрике, имя класса исключений является свойством вашего кода, а не инъекционной зависимостью (по крайней мере, на этом низком уровне). И вы правильно заменили 'die()' в первую очередь. Сосредоточьтесь на убийстве всех 'die()' s first: D. – hakre

+0

@hakre объяснение хороший. Тем не менее, я должен согласиться с тем, что это кажется ложным, поскольку вы можете возвращать различные исключения из библиотечной процедуры, указывающей на проблему (язык установки может не иметь установленного языка, безопасности пользователя, без переводов и т. Д.) И исключения следовательно, могут быть разных типов, поэтому вызывающий может продолжать/прерывать исходя из этой проблемы. Я думаю, что это нужно настроить в PHP_MD, чтобы игнорировать ложные срабатывания, поскольку я не хочу иметь много кода @ SuppressWarnings (PHPMD.StaticAccess) в коде. –

+2

@StevenScott: Я считаю, что это слишком жестко, чтобы монета «ложно позитивна». Поскольку PHPMD выполняет статический анализ кода, он может указывать только те точки в коде, которые нарушают (или улавливаются) некоторым правилом. Программист должен прочитать этот вывод и понять правило, а затем решить, что делать. Статический анализ кода никогда не может выполнять эти шаги программистов, это всего лишь инструмент, который может помочь в проведении обзора всей базы кодов. Говоря так, могут быть исключения из правил, которые могут иметь смысл (иногда). – hakre

0

Потому что я использую много самости :: для констант, изменить phpmd код, чтобы принять себя :: и родителей ::.

В программе PHP/PMD/Rule/CleanCode/StaticAccess.php в строке 36, изменение:

if ($this->isReferenceInParameter($reference) 
    || $reference->getImage() === 'self' 
    || $reference->getImage() === 'parent' 
    ) { 
    continue; 
} 

Может быть, вы можете использовать, чтобы уточнить код.