2010-10-23 9 views
6

Esta pregunta: Best way to return status flag and message from a method in Java es similar a la mía, sin embargo lo haría en PHP, no en Java (lo que podría hacer una pequeña diferencia aquí).Estado de devolución del método: bool, string, const ... (PHP)

El problema:

No es un método que puede tener ya sea un resultado exitoso (esto puede cambiar para ser los más exitosos) o una "problemática" uno. Esto último significa que la operación falló, pero también es importante saber por qué. Imagínese un método de una clase de autenticación:

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

sería trivial para volver verdadero y falso para el éxito y el fracaso, pero la manera de informar la causa del fracaso?

soluciones posibles: true

  • Retorno o falsas y escribir otro método (getStatus()) para obtener el problema específico: esto se siente un poco incómodo para mí
  • Use excepciones: ya que no es excepcional para que un usuario sea prohibido (una excepción sería si el usuario muriera mientras teclea como ha señalado otro autor en este sitio) el uso de excepciones aquí en estos casos sería completamente incorrecto (sin embargo, el método podría arrojar una excepción de base de datos si falla una consulta)
  • Volver cierto en el éxito y una cadena en caso de fallo con un código de error que indica el problema: con PHP es posible de esta manera tener buenos bloques limpios de la siguiente manera:

    $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]; 
    } 
    
  • devolver un estado general (estado) de objeto: muy solución elegante y también a prueba de futuro (no hay problema si el número de estados varía o temprano debe ser devuelto datos adicionales), tal vez la mejor:

    $loginStatus = $auth->login('name', 'pass') 
    if ($loginStatus->isSuccess) 
    ... 
    else 
        echo $errorMessages[$loginStatus->errorCode]; // $errorMessages as by the previous example 
    
  • Cualquiera de los dos anteriores, pero no con una cuerda simple pero constantes de clase:

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

    Con esto no sería necesario explicar los códigos de error en la documentación y se sentiría más "natural" también (al menos para mí).

La pregunta:

Lo usaría (de los anteriores o cualquier otra solución)? ¿Qué se ha demostrado a largo plazo que es una buena manera?

¡Gracias de antemano!

Respuesta

2

Así es como PEAR lo ha estado haciendo durante tanto tiempo como puedo recordar. Así que este es un método probado y probado.

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

Es una lástima que haya esperado tanto tiempo para aceptar la respuesta :-). – Piedone

2

Lance la excepción. Si se requiere verificar el valor de retorno, cualquier falla al hacerlo permitirá inicios de sesión no autorizados. Si no se verifica una excepción, se explotará todo, lo que parece preferible en este caso.

En lugares menos críticos si estaba haciendo una comprobación contra un objeto que ya existía, podría devolver el código de resultado y tener una función separada para recuperar el mensaje, pero no me desviaría de hacer algo en un objeto solo para usar esa técnica. De lo contrario, iría con un objeto de estado que contiene el código y el mensaje de resultado.

+0

Gracias por su respuesta! Tenga en cuenta que esto solo sería un método de inicio de sesión, pero no un método para verificar si el usuario ya está autenticado (si no lo hace, esto último causaría problemas). No creo que la falla al iniciar sesión sea una excepción (solo piense en escribir mal su contraseña, no es un caso muy raro) y, por lo tanto, sería un uso de excepciones para el flujo normal del programa. Pero no solo pensemos en un método de inicio de sesión, me gustaría saber cuál es la mejor técnica con cualquier método que pueda tener estados exitosos y fallidos. – Piedone

+0

@piedone - editado –

1

Iría con una variación de su "Devolver un estado general (estado) objeto" donde el estado es descrito por su objeto de autenticación.

So $ auth-> login ('nombre', 'pase') es un simple bool, y $ auth-> getState() es una enumeración o cadena (destinada para el usuario final quizás) que describe el estado.

Cuestiones relacionadas