Pregunta

Estoy trabajando en una librería PHP en el que estaremos suministrando a nuestros clientes con código cifrado. El código incluirá un principales clases que se puede crear una instancia que se encargará de verificar la licencia y exponer métodos para su uso. La clase principal será una instancia de varias subclases contenían cada uno en su propio archivo. ¿Cómo puedo evitar que nuestros clientes de la inclusión de los archivos de subclase y crear instancias de los propios sub-clases para su uso? ¿Hay una manera de prevenir una subclase de ser instanciado excepto de nuestra clase principal?

¿Fue útil?

Solución

conjetura salvaje, pero utilizar un Singleton para la clase principal, y la fábrica / Singleton con la inyección de dependencias (de la clase primaria) para todas las subclases. De esa manera las subclases ni siquiera se carga sin una referencia válida a una instancia de la clase primaria.

EDIT: Desde que se aceptó esta respuesta he decidido dar un ejemplo, para el beneficio de los futuros lectores. Además, no se olvide de marcar todas sus clases como definitiva.

Clase Principal:

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;
    }
}

Singleton Subclase:

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;
    }
}

Subclase de fábrica:

final class myFactorySubClass {

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

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

dos notas acerca de este ejemplo; En primer lugar, por supuesto que estoy simplificando enormemente la materia. En segundo lugar, un buen truco que podría emplear es modificar las subclases ligeramente de modo que los métodos getInstance() no siempre es necesario tener una instancia de la clase primaria pasa como argumento después de la primera vez. Voy a dar un ejemplo aquí con la clase Singleton:

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;
    }
}

Tenga en cuenta que esto depende en gran medida de tipo insinuando mecanismo de PHP . Como tal, debe leer la entrada manual sobre ella por lo a entender los matices (por ejemplo, por defecto nulo).

Otros consejos

No creo que haya una forma de lenguaje soportado, por lo que será hasta trucos. Lo que podría hacer es añadir un argumento secreto para los constructores de su clase privada, que sólo es conocida por su clase principal. Si eso no es actual, lanzar una excepción NOTALLOWED.

Sé que es feo, y no es muy seguro (sí a nadie le gusta la seguridad a través de la oscuridad-), pero podría trabajar lo suficiente para su caso específico ...

Sé que este tema es un poco viejo ahora, pero yo estaba pensando que la forma en que lo haría esto en Java es con Caller Pila de inspección, y no PHP tener algo similar? De hecho lo hace, aunque es un módulo PECL:

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

Obtener la pila de llamadas, comprobarlo con sus puntos de código, una excepción si no coincide. Incluso se podría crear una superclase común que hace esta comprobación para usted.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top