【问题标题】:PHP: Extend authentication class by methods of childsPHP:通过孩子的方法扩展身份验证类
【发布时间】:2016-11-30 07:47:01
【问题描述】:

我想声明一个由多个子类扩展的类认证。

// Parent class that should be called
abstract class auth
{
    // Force child classes to implement this method
    abstract public function authUser($uid, $pw);
}

class configAuth1 extends auth
{
    public function authUser($uid, $pw)
    {
        // Do some authentication stuff
        return false;
    }
}

class configAuth2 extends auth
{
    public function authUser($uid, $pw)
    {
        // Do some authentication stuff
        return true;
    }
}

现在我想调用父类并尝试所有子类方法authUser(),直到其中一个返回 true。

所以我会说手动实例化所有孩子是没有意义的。 我该如何处理?

更新

目前我用get_declared_classes()ReflectionClass 解决了这个问题。这可以通过更好的方式解决吗?

【问题讨论】:

    标签: php class authentication parent-child


    【解决方案1】:

    父类不应该知道自己的孩子。反射 API 和相关函数不是实现高级逻辑的好选择。 在您的情况下,您可以使用类似 Strategy 的模式。

    首先,我们声明认证方法的通用接口:

    /**
     * Common authentication interface.
     */
    interface AuthStrategyInterface
    {
        public function authUser($uid, $pw);
    }
    

    接下来,我们添加这个接口的一些自定义实现:

    /**
     * Firsts implementation.
     */
    class FooAuthStrategy implements AuthStrategyInterface
    {
        public function authUser($uid, $pw)
        {
            return true;
        }
    }
    
    /**
     * Second implementation.
     */
    class BarAuthStrategy implements AuthStrategyInterface
    {
        public function authUser($uid, $pw)
        {
            return false;
        }
    }
    

    然后我们创建另一个包含特定策略集合的实现。 它的authUser() 方法依次将身份验证参数传递给每个内部策略,直到其中一个返回 true。

    /**
     * Collection of nested strategies.
     */
    class CompositeAuthStrategy implements AuthStrategyInterface
    {
        private $authStrategies;
    
        public function addStrategy(AuthStrategyInterface $strategy)
        {
            $this->authStrategies[] = $strategy;
        }
    
        public function authUser($uid, $pw)
        {
            foreach ($this->authStrategies as $strategy) {
                if ($strategy->authUser($uid, $pw)) {
                    return true;
                }
            }
            return false;
        }
    }
    

    这不是解决问题的唯一方法,只是一个例子。

    【讨论】:

    • 谢谢。在这种情况下,我需要添加每个子类的实例 - 这不是自动可能的吗?
    • 该任务也可以通过多种方式解决。选择的方法取决于您的应用程序设计。例如,阅读Service LocatorDependency Injection。此外,实例的自动创建和绑定通常称为“自动装配”,许多库和框架都提供此功能。
    猜你喜欢
    • 1970-01-01
    • 2012-05-10
    • 1970-01-01
    • 2015-02-08
    • 2011-06-28
    • 1970-01-01
    • 1970-01-01
    • 2020-07-03
    • 2014-02-20
    相关资源
    最近更新 更多