jeudi 20 février 2020

Use instance of child class instead of parent class given a condition (PHP)

I'm working on breaking up a large, monolithic class into several subclasses, but it's too much to do all at once so I'm looking to split them out one by one over several releases as time permits. It's an auth class that authorizes some channel, so currently it looks like this:

$auth = new Auth($user, $data);
$output = $auth->authChannel($channelName);

Inside Auth, it basically looks like this:

public function __construct($user, $data)
{
    $this->user = $user;
    $this->data = $data;
}

public function authChannel($channel)
{
    $this->setUserData();

    if (isset(self::CHANNEL_AUTH_FUNCTIONS[$channel])) {
        $authFunction = self::CHANNEL_AUTH_FUNCTIONS[$channel];
        return $this->$authFunction();
    } else {
        // invalid channel
    }
}

So self::CHANNEL_AUTH_FUNCTIONS is basically ['channelA' => 'authChannelA', 'channelB' => 'authChannelB'], etc., and all those functions are in this one class.

Now what I want to do, one at a time, is if $legacyChannel => callLegacyFunction() / else $newChannel => instantiate its own class and call auth().

So I put Auth.php into its own namespace and have the new Channel.php class in that same namespace. And Channel extends Auth.

Currently I have this:

public function authChannel($channel)
{
    $this->setUserData();

    if (isset(self::CHANNEL_AUTH_LEGACY_FUNCTIONS[$channel])) {
        $authFunction = self::CHANNEL_AUTH_LEGACY_FUNCTIONS[$channel];

        if ($authFunction) {
            return $this->$authFunction();
        } else {
            $authClassName = __NAMESPACE__ . '\\' . ucwords($channel);
            $authClass = new $authClassName($user, $data);
            return $authClass->auth();
        }
    } else {
        // invalid channel
    }
}

Is there a better way to do this? Currently it seems a bit wasteful since two different objects are created and the setUserData() function for example would need to be called again I believe. I'm also wondering if there's a better way to get the dynamic class name other than through __NAMESPACE__ . / . $className.

Any help would be appreciated!

Aucun commentaire:

Enregistrer un commentaire