2010-10-23 11 views
6

Questa domanda: Best way to return status flag and message from a method in Java è simile alla mia, tuttavia lo farei in PHP, non in Java (che potrebbe fare una leggera differenza qui).Stato di ritorno del metodo: bool, string, const ... (PHP)

Il problema:

C'è un metodo che può avere sia un esito positivo (puo 'cambiare per essere quelli di maggior successo) o di un "problematico" uno. Quest'ultimo significa che l'operazione è fallita, ma è anche importante sapere perché. Immaginate un metodo di una classe di autenticazione:

public function login($name, $password) 
{ 
    if (successful_authentication) 
    { 
     report success 
    } 
    else 
    { 
     report failure, explain why (e.g. wrong name/pass, user banned) 
    } 
} 

Sarebbe banale per tornare vero e falso per il successo e il fallimento, ma come segnalare la causa del fallimento?

Possibili soluzioni:

  • restituire true o false e scrivere un altro metodo (getStatus()) per ottenere il problema specifico: questo si sente un po 'imbarazzante per me
  • utilizzare le eccezioni: dato che non è eccezionale per un utente essere bannato (un'eccezione sarebbe se l'utente morirebbe mentre si digita come un altro autore su questo sito ha sottolineato) l'uso di eccezioni qui in questi casi sarebbe semplicemente sbagliato (tuttavia il metodo potrebbe lanciare un'eccezione del database se una query non riesce)
  • ritorno vero in caso di successo e una stringa in caso di fallimento con un codice di errore che indica il problema: con PHP è possibile in questo modo di avere belle blocchi pulite come segue:

    $loginStatus = $auth->login('name', 'pass'); 
    if ($loginStatus === true) 
    { 
        doSomething(); 
    } 
    else 
    { 
        if ($loginStatus == 'wrong_login_data') 
        ... 
        elseif ($loginStatus == 'banned') 
        ... 
        // or with an array full of error messages: 
        echo $erroMessages[$loginStatus]; 
    } 
    
  • Ritorna uno stato generale (stato) oggetto: molto soluzione elegante e anche a prova di futuro (non è un problema se il numero di stati di varia o poi dati aggiuntivi deve essere restituito), forse il migliore:

    $loginStatus = $auth->login('name', 'pass') 
    if ($loginStatus->isSuccess) 
    ... 
    else 
        echo $errorMessages[$loginStatus->errorCode]; // $errorMessages as by the previous example 
    
  • uno di due precedenti, ma non con lo spago semplice ma costanti di classe:

    $loginStatus = $auth->login('name', 'pass') 
    if ($loginStatus->isSuccess) 
    ... 
    elseif ($loginStatus->errorCode == Auth::ERR_USER_BANNED) 
    ... 
    

    Con questo non sarebbe necessario spiegare i codici di errore nella documentazione e si sentirebbe anche più "naturale" (almeno per me).

La domanda:

Cosa vorresti usare (di quelli di cui sopra o qualsiasi altra soluzione)? Che cosa è stato dimostrato a lungo termine per essere un buon modo?

Grazie in anticipo!

risposta

2

Questo è il modo in cui PEAR lo fa da quando riesco a ricordare. Quindi questo è un metodo provato e testato.

class LoginError { 
    private $reason; 

    public function __construct($reason) 
    { 
     $this->reason = $reason; 
    } 

    public function getReason() 
    { 
     return $this->reason; 
    } 
} 

function isError($response) 
{ 
    return ($response instanceof LoginError); 
} 

public function login($name, $password) 
{ 
    if (successful_authentication) 
    { 
     return true; 
    } 
    else 
    { 
     return new LoginError('The password is incorrect'); 
    } 
} 


$loginStatus = login('name', 'pass'); 
if (!isError($loginStatus)) 
{ 
    doSomething(); 
} 
else 
{ 
    echo $loginStatus->getReason(); 
} 
+0

È un peccato che ho aspettato così tanto ad accettare la risposta :-). – Piedone

2

Invia un'eccezione. Se si verifica il valore restituito è necessario, quindi qualsiasi errore in tal senso consentirà accessi non autorizzati. La mancata verifica di un'eccezione farà esplodere tutto, il che sembra preferibile in questo caso.

In punti meno critici se eseguivo un controllo su un oggetto già esistente, potrei semplicemente restituire il codice del risultato e disporre di una funzione separata per recuperare il messaggio, ma non vorrei fare di tutto per creare qualcosa in un oggetto solo per usare quella tecnica. Altrimenti andrei con un oggetto status contenente il codice del risultato e il messaggio.

+0

Grazie per la tua risposta! Si noti che questo sarebbe solo un metodo di accesso, ma non un metodo per verificare se l'utente è già autenticato (non fare quest'ultimo potrebbe effettivamente causare problemi). Non credo che l'errore di accesso sarebbe un'eccezione (basti pensare a digitare la password errata - non è un caso molto raro) e quindi sarebbe un uso di eccezioni per il normale flusso del programma. Ma non pensiamo solo a un metodo di accesso, mi piacerebbe sapere qual è la tecnica migliore con qualsiasi metodo che possa avere stati riusciti e non riusciti. – Piedone

+0

@piedone - modificato –

1

Vorrei andare con una variazione del tuo "Restituire un oggetto di stato generale (stato)" dove lo stato è descritto dal tuo oggetto auth.

Quindi $ auth-> login ('name', 'pass') è un semplice bool e $ auth-> getState() è un enum o una stringa (destinata all'utente finale forse) che descrive lo stato.

Problemi correlati