保护PHP类免受不希望的实例化?

1 php protection class

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

Der*_*sed 7

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

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

小学班级:

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;
    }
}
Run Code Online (Sandbox Code Playgroud)

单身子类:

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;
    }
}
Run Code Online (Sandbox Code Playgroud)

工厂子类:

final class myFactorySubClass {

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

    public static function getNewInstance(myPrimaryClass $primaryClassInstanceRef) {
        return new myFactorySubClass($primaryClassInstanceRef);
    }
}
Run Code Online (Sandbox Code Playgroud)

关于这个例子的两个注释; 首先,我当然非常简单化了.其次,你可以使用的一个巧妙的技巧是稍微修改子类,这样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;
    }
}
Run Code Online (Sandbox Code Playgroud)

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