如何处理用户状态

At the moment I have User entity with predefined statuses as constants. User has STATUS_NOT_CONFIRMED by default.

interface UserInterface
{
   const STATUS_ENABLED  = 1;
   const STATUS_DISABLED = 2;
   const STATUS_BANNED   = 3;
   const STATUS_NOT_CONFIRMED = 4;
}

But I'm stuck with a question of what the best (or better) way to manage User statuses:

  • using just one method like $user->changeStatusTo($status) which is similar to $user->setStatus($status);

  • create methods like $user->enable(), $user->disable(), $user->ban() which is more eloquent but can lead to the problem if I have more statuses in the future;

I'll glad to see any answers and advices, thanks!

I would create both variants and let them call each other. So calling ban would call setStatus. If you later add new statuses, you could extend setStatus and if really needed, add a new method.

For convinience reasons, I would also extend the UserInterface interface to save the max value. That way, you could change the interface without touching your setStatus method.

interface UserInterface
{
   const STATUS_ENABLED  = 1;
   const STATUS_DISABLED = 2;
   const STATUS_BANNED   = 3;
   const STATUS_NOT_CONFIRMED = 4;

   const STATUS_MAX = self::STATUS_NOT_CONFIRMED;
}

class User implements UserInterface {

    // ...
    function setStatus($status) {
        if ($status < 0 || $status > UserInterface::STATUS_MAX) {
            throw InvalidArgumentException('status');
        }
        $this->status = $status;
    }

    function ban() {
        $this->setStatus(UserInterface::STATUS_BAN);
    }
    // ...

}

I can suggest to use magic method __get() with userInterface and check constant dynamically in below way

<?php

interface UserInterface
{
   const STATUS_ENABLE  = 1;
   const STATUS_DISABLE = 2;
   const STATUS_BAN = 3;
   const STATUS_NOT_CONFIRM = 4;
   const STATUS_DEFAULT = self::STATUS_NOT_CONFIRM;
}

class User implements UserInterface{
    public $status = UserInterface::STATUS_DEFAULT;
    private function setStatus($status) {
        if ($status < 0 || $status > UserInterface::STATUS_DEFAULT) {
            throw InvalidArgumentException('status');
        }
        $this->status = $status;
    }
    public function getStatus() {
        return $this->status;
    }

    function __call($fn_name,$args)
    {
        if(strpos($fn_name,'make')==0)
        {
            $statusChangeTo = "STATUS_".strtoupper(substr($fn_name,4));
            $constant= 'UserInterface::'.$statusChangeTo;
            if(defined($constant))
            {
                $this->setStatus(constant($constant));
            }
            else
            {
                throw new Exception("Invalid method ".$fn_name);
            }
        }
        else
        {
            throw new Exception("Invalid method ".$fn_name);
        }
    }

}
$user= new User();
var_dump($user->getStatus());
$user->makeBan();
var_dump($user->getStatus());
?>