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