Validating user credentials and logging into a Symfony site I have the following code in a Symfony site that validates a user's credentials and logs them in via the Session class:

/**
 * Validates an Affiliate
 */
public function validateUser($username, $password, $session, $securityContext) 
{
    $repo = $this-&gt;em-&gt;getRepository('JCMainBundle:Affiliate');
    $user = $repo-&gt;findOneBy(["username" =&gt; $username]);

    if (!is_object($user)) return false;

    $passwordValidated = password_verify($password, $user-&gt;getPassword());

    if (!$passwordValidated) return false;

    // Create token for user
    $token = new UsernamePasswordToken($user, null, "affiliate_dashbaord", ['ROLE_AFFILIATE']);
    $securityContext-&gt;setToken($token);
    $session-&gt;set('_security_affiliate_dashboard', serialize($token));

    return true;
}


As you can see, the function has very simple return values--just booleans. The function that calls this function looks at the return value of this function and determines whether or not to redirect the user to the affiliate dashboard.

How can I handle the return values better? I have two possible paths than can return false, but the calling function will have no idea what caused "false" to be returned.

In the past I've done something like this:

$response = ["success" =&gt; false, "message" =&gt; "error message here"];


I return the response with the success and a message. Using this design, I can return false AND return what made it return false. However, this seems a bit unorthodox for use on the backend and seems to fit more in a REST API.

I could use an exception, but the role of the function is to validate, so it wouldn't make sense to throw an exception if the user credentials are incorrect.
Note: the suggestion below is founded on a certain vision about readability, that may not be shared by everybody, as illustrated by the totally opposite approach proposed by @Thijs Riezebeek.

A pretty simple, light, and though efficient solution I frequently use in such cases is to merely:


Return the appropriate explainatory message when there is an error.
Do nothing otherwise.


First it makes your function as simple as possible (when successfull you don't even need to return anything).

Then from the app which invokes the function it's easy to use while being readable, assumed you change the function name for something like invalidUser(). So the app can work like this:

if ($errorMessage = invalidUser(...)) {
  // take any appropriate action, using $errorMessage
}
// otherwise merely continue