根据开发或生产环境实例化 which PHP class

Instantiate which PHP class based on dev or production environment

我已经 integrated SimpleSAMLphp with my application,但是它只适用于生产环境,因为没有连接到其他地方的 IdP 服务器。我如何才能继续在需要身份验证的开发环境中工作?

我编写了一个包装器 class,它向 SimpleSAML_Auth_Simple class 公开了必要的方法。相关代码如下:

需要身份验证的页面

<?php

// (assume autoloading)
$saml = new SAMLWrapper('name-of-sp');
$saml->requireAuthentication('https://[::1]/app/saml-controller.php?callback=1');
$userAttributes = $saml->getAttributes();

// rest of application code below...

包装纸class

class SAMLWrapper extends IAuthentication
{
    private $as;

    public function __construct($sp) {
        require_once('/var/simplesamlphp/lib/_autoload.php');
        // THIS PATH DOES NOT EXIST ON DEV

        $this->as = new \SimpleSAML_Auth_Simple($sp);
    }

    public function requireAuthentication($callback) {
        $this->as->requireAuth(array('ReturnTo' => $callback));
    }

    public function getAttributes() {
        return $this->as->getAttributes();
    }
}

虚拟包装器 class

我考虑过像这样写一个虚拟包装器:

class DummySAML extends IAuthentication
{
    private $attrs;

    public function __construct(array $attrs) {
        $this->attrs = $attrs;
    }

    public function requireAuthentication() {
        return;
    }

    public function getAttributes() {
        return $this->attrs;
    }
}

但是这意味着我必须在所有需要身份验证的页面上在 SAMLWrapperDummySAML class 之间切换:

if (getenv('SLIM_MODE') === 'DEV') {
    // instantiate DummySAML with test attributes
} else {
    // instantiate SAMLWrapper with service provider name
}

有没有更简单更好的方法?

一种选择是将基于环境的切换移动到单个包装器中 class。一个显而易见的缺点是您的测试属性需要在 class 中进行硬编码,或者即使在生产中也始终传递给构造函数。否则,您将无法使用单个构造函数支持这两种情况。

在我自己的应用程序中,我可能会从依赖项注入容器中获取身份验证包装器,注册一个检查环境的工厂和 returns 适当 class(真实或虚拟)的实例).如果您还没有使用 DI,迁移可能会很痛苦,但您始终可以创建一个一次性静态工厂来处理适当包装器的实例化,以减少每个文件顶部的样板文件数量。