2009-11-03 9 views
1

Je travaille sur une bibliothèque PHP dans laquelle nous fournirons à nos clients un code chiffré. Le code inclura des classes principales qui pourront être instanciées pour gérer la vérification des licences et exposer les méthodes pour leur utilisation. La classe principale instanciera plusieurs sous-classes contenues dans leur propre fichier. Comment puis-je empêcher nos clients d'inclure les fichiers de sous-classes et d'instancier eux-mêmes les sous-classes à utiliser? Est-il possible d'empêcher une sous-classe d'être instanciée à l'exception de notre classe principale?Protéger les classes PHP contre l'instanciation indésirable?

+0

pourquoi est ce qui ne fonctionne pas? –

+2

Je ne peux certainement pas instancier votre classe. Vous l'avez rendu invisible! –

+0

Vous devez expliquer ce qui ne fonctionne pas. Postez le code que vous avez déjà écrit. – Yacoby

Répondre

7

conjecture sauvage, mais utiliser un Singleton pour la classe principale, et l'usine/Singleton avec injection de dépendances (de la classe principale) pour toutes les sous-classes. De cette façon les sous-classes ne chargeront même pas sans une référence valide à une instance de votre classe primaire.

EDIT: Depuis que cette réponse a été acceptée j'ai décidé de donner un exemple, pour le bénéfice des futurs lecteurs. Aussi, n'oubliez pas de marquer toutes vos classes comme finales.

classe primaire:

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 Sous-classe:

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

Usine Sous-classe:

final class myFactorySubClass { 

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

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

Deux notes sur cet exemple; D'abord, bien sûr, je simplifie énormément la question. Deuxièmement, une astuce que vous pourriez utiliser est de modifier légèrement les sous-classes de sorte que les méthodes getInstance() n'ont pas toujours besoin d'avoir une instance de la classe primaire passée en argument après la première fois. Je vais vous donner un exemple ici avec la classe 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; 
    } 
} 

S'il vous plaît noter, ce repose en grande partie sur PHP's type-hinting mechanism. En tant que tel, vous devriez read the manual entry on it afin que vous compreniez les nuances (par exemple, la valeur par défaut).

1

Je ne pense pas qu'il y ait un langage supporté, donc ça va être des trucs. Ce que vous pouvez faire est d'ajouter un argument secret aux constructeurs de votre classe privée, qui est seulement connu par votre classe principale. Si ce n'est pas le cas, lancez une exception NotAllowed.

Je sais qu'il est laid, et pas très sûr (oui non-aime la sécurité par l'obscurité-), mais il pourrait assez de travail pour votre cas ...

0

Je sais que ce sujet est un peu vieux maintenant, mais je pensais juste que ce que je ferais en Java est avec Caller Stack Inspection, et PHP n'a pas quelque chose de similaire? En fait, il le fait, mais il est un module PECL:

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

Obtenez la pile d'appels, vérifiez contre vos points de code, jetez une exception si elle ne correspond pas. Vous pourriez même créer une superclasse commune qui fait cette vérification pour vous.