1

我正在开发一个 PHP 库,我们将在其中为我们的客户提供加密代码。该代码将包括一个他们可以实例化的主要类,这些类将处理许可证验证并公开其使用方法。主类将实例化几个子类,每个子类都包含在自己的文件中。如何防止我们的客户包含子类文件并实例化子类以供使用?有没有办法防止子类被实例化,除了我们的主类?

4

3 回答 3

7

疯狂的猜测,但是对主类使用单例,对所有子类使用带有依赖注入(主类的)的工厂/单例。这样,如果没有对主类实例的有效引用,子类甚至不会加载。

编辑:由于这个答案被接受,我决定提供一个例子,以使未来的读者受益。另外,不要忘记将所有课程标记为最终课程。

初级班:

final class myPrimaryClass {

    private static $instance = null;

    private function __construct() {
        // do something or not
        return $this;
    }

    public static function getInstance() {
        if (is_null(self::$instance) || !(self::$instance instanceof myPrimaryClass))
            self::$instance = new myPrimaryClass;
        return self::$instance;
    }
}

单例子类:

final class mySingletonSubClass {

    private static $instance = null;

    private function __construct(myPrimaryClass $primaryClassInstanceRef) {
        return $this;
    }

    public static function getInstance(myPrimaryClass $primaryClassInstanceRef) {
        if (is_null(self::$instance) || !(self::$instance instanceof mySingletonSubClass))
            self::$instance = new mySingletonSubClass($primaryClassInstanceRef);
        return self::$instance;
    }
}

工厂子类:

final class myFactorySubClass {

    private function __construct(myPrimaryClass $primaryClassInstanceRef) {
        return $this;
    }

    public static function getNewInstance(myPrimaryClass $primaryClassInstanceRef) {
        return new myFactorySubClass($primaryClassInstanceRef);
    }
}

关于这个例子的两个注意事项;首先,我当然把事情过分简单化了。其次,您可以采用的一个巧妙技巧是稍微修改子类,以便getInstance()方法在第一次之后并不总是需要将主类的实例作为参数传递。我将在此处提供一个带有单例类的示例:

final class mySingletonSubClass {

    private static $instance = null;
    private static $classInstanceRef = null;

    private function __construct(myPrimaryClass $primaryClassInstanceRef) {
        return $this;
    }

    public static function getInstance(myPrimaryClass $primaryClassInstanceRef = null) {
        if (!is_null($primaryClassInstanceRef))
            self::$classInstanceRef = $primaryClassInstanceRef;

        if (is_null(self::$instance) || !(self::$instance instanceof mySingletonSubClass))
            self::$instance = new mySingletonSubClass(self::$classInstanceRef);

        return self::$instance;
    }
}

请注意,这在很大程度上依赖于PHP 的类型提示机制。因此,您应该阅读它的手册条目,以便了解细微差别(例如默认空值)。

于 2009-11-03T23:19:14.697 回答
1

我不认为有语言支持的方式,所以这将取决于技巧。您可以做的是向您的私有类的构造函数添加一个秘密参数,该参数只有您的主类知道。如果不存在,则抛出 NotAllowed 异常。

我知道这很丑陋,而且不是很安全(是的,没有人喜欢通过默默无闻的安全性),但它可能足以满足您的具体情况......

于 2009-11-03T23:17:32.737 回答
0

我知道这个话题现在有点老了,但我只是在想我在 Java 中如何做到这一点是使用调用堆栈检查,PHP 没有类似的东西吗?事实上它确实如此,尽管它是一个 PECL 模块:

http://www.php.net/manual/en/function.apd-callstack.php

获取调用堆栈,根据您的代码点检查它,如果不匹配则抛出异常。你甚至可以创建一个通用的超类来为你做这个检查。

于 2011-02-04T06:40:00.150 回答