2013-09-03 9 views
9

Ho appena attivato PHPMD per la prima volta e, prevedibilmente, ho un errore che non riesco a capire. L'errore èEvitare di utilizzare l'accesso statico a Exception

Evitare l'utilizzo dell'accesso statico alla classe "InvalidArgumentException" nel metodo "setLang".

e il codice è

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

Ho provato una varietà di cose diverse, ma penso che alla fine della giornata Exception è una fabbrica statica (???) quindi deve essere statica accesso. Ma i ragazzi di PHPMD sono sicuramente più furbi di me, quindi non li avrebbero spaventati.

Perché esiste questo avviso e come risolverlo?

risposta

8

L'idea alla base di questo avviso è che se si incorporano i nomi di classe all'interno del codice con la parola chiave new sarà difficile scambiare queste classi nei metodi di test e mock o stub che il codice in prova potrebbe chiamare su di essi. See the explanation nelle regole PHPMD.

Penso che nel tuo caso questo è un falso positivo poiché le eccezioni di solito non hanno molto comportamento da sole, ma il nome della classe (e la gerarchia di classe dietro di esso) di loro è praticamente l'unica cosa importante su di loro.

Se si desidera eliminare l'avviso qui, è possibile utilizzare l'annotazione @SupressWarnings qui.

+0

Grazie. Quindi, posso spegnerlo o evitarlo in qualche modo? – Ben

+0

Oh, dovrei dire che ho appena cambiato la gestione delle eccezioni. Prima stavo usando 'die()', ma quello mi sembrava sbagliato. – Ben

+1

Non sono intimamente familiare con PHPMD ma dovrebbe comprendere ['@ SuppressWarnings'] (http://phpmd.org/documentation/suppress-warnings.html) annotazione. – complex857

2

Ah, dopo aver scavato un po 'ho trovato la risposta, direttamente dalla bocca del cavallo.

Nei file di configurazione, situati a yourphpdir\data\PHP_PMD\resources\rulesets, lo cleancode.xml ha commenti CDATA che spiegano l'impostazione.

Questo dice:

acccess Statico provoca dipendenze inexchangable ad altre classi e porta alla difficile da testare il codice. Evitare l'uso di accesso statico a tutti i costi e invece di iniettare dipendenze attraverso il costruttore. L'unico caso quando l'accesso statico è accettabile viene utilizzato per i metodi di fabbrica.

Il modo per risolverlo è passare l'eccezione come parametro, quindi è dichiarato al di fuori della classe.

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

Sì, PHPMD individua correttamente la dipendenza nascosta su "InvalidArgumentException" qui. Tuttavia, come @ complex857 ha commentato anche nella sua [risposta] (http://stackoverflow.com/users/1515540/complex857) direi che questo è un caso limite poiché lanciare un'eccezione normalmente richiede una classe non iniettata- nome. Come all'interno della fabbrica, il nome della classe di eccezioni è una proprietà del codice, non una dipendenza iniettabile (almeno non a questo livello basso). E hai fatto bene a sostituire 'die()' in primo luogo. Concentrati sull'uccidere tutti i primi 'die()': D. – hakre

+0

@hakre la spiegazione è buona. Tuttavia, devo ammettere che questo sembra un falso positivo, in quanto potresti restituire varie eccezioni da una routine di libreria che indica il problema (impostazione della lingua potrebbe non avere la lingua installata, sicurezza dell'utente, nessuna traduzione, ecc ...) e l'eccezione potrebbe quindi essere di diversi tipi in modo che il chiamante possa continuare/interrompere in base al problema. Penso che questo debba essere corretto in PHP_MD per aiutare a ignorare i falsi positivi, poiché non voglio avere molti @ SuppressWarnings (PHPMD.StaticAccess) nel codice. –

+2

@StevenScott: Trovo un po 'troppo duro interpretarlo come "falso positivo". Poiché PHPMD esegue l'analisi del codice statico, è in grado di segnalare solo punti all'interno del codice che violano (o sono intercettati) da alcune regole. Spetta al programmatore sia leggere questo output e comprendere la regola, quindi decidere cosa fare. Un'analisi del codice statica non può mai essere utilizzata da questi programmatori, è solo uno strumento che può aiutare a mantenere una visione generale del codebase in generale. Dicendo così, potrebbero esserci delle eccezioni alle regole che possono avere senso (a volte). – hakre

0

Perché io uso un sacco di self :: per le costanti, modificare il codice phpmd ad accettare self :: :: e genitore.

Nel PHP/programma PMD/Regola/CleanCode/StaticAccess.php alla linea 36, ​​modifica:

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

forse è possibile utilizzare che per perfezionare il codice.