Cours privés. Se cacher dans php

En php, comme dans la plupart des autres langages OOP, il existe des modificateurs de visibilité. Ce sont les mots-clés public, protected et private. Mais ils s'appliquent exclusivement aux propriétés, méthodes ou constantes. Ces modificateurs sont étroitement liés à la capacité d'encapsuler des données. Il convient de noter que dans des langages tels que java, C #, allez ( https://golang.org/doc/go1.4#internalpackages ), rubis ( https://habr.com/post/419969/ ), cristal ( https : //crystal-lang.org/reference/syntax_and_semantics/visibility.html ) il est possible de limiter la portée des packages (packages) ou classes \ types. En php, il n'y a aucun moyen de limiter la portée des classes - n'importe quelle classe connectée est accessible depuis n'importe quelle autre classe. Cependant, vous pouvez émuler cette fonctionnalité à l'aide de plusieurs astuces.


Pourquoi le masquage au niveau de la classe pourrait être nécessaire:


  • Classes de service (aides) de la bibliothèque - ne jonchent pas l'API de la bibliothèque de classes internes dénuées de sens.
  • Encapsulation avec dissimulation d'objets internes de "logique métier", par exemple, interdiction de génération directe d'objets dépendants contournant une classe plus générale.

Séparément, nous pouvons distinguer la partition de "grandes" classes en petits objets. Il est recommandé de limiter la complexité (et le nombre de lignes) des méthodes et des classes individuelles. Le nombre de lignes ici va comme l'un des marqueurs que la méthode de classe ou la classe elle-même prend la responsabilité inutile. Lors de la refactorisation d'une méthode publique, nous en déplaçons des parties vers des méthodes privées \ protégées. Mais lorsque, pour une raison ou une autre, la classe se développe et que nous en séparons une entité distincte, ces classes très privées \ protégées sont transférées dans une classe distincte, ouvrant ainsi indirectement l'accès à des méthodes qui étaient auparavant limitées à la portée d'une classe.


Maintenant, les méthodes réelles d'émulation des dissimulations elles-mêmes.


Au niveau du code


En utilisant les commentaires PHPDoc, vous pouvez marquer une classe, un trait ou une interface comme internal ( http://docs.phpdoc.org/references/phpdoc/tags/internal.html ). Cependant, certains IDE (tels que PhpStorm) peuvent comprendre de telles étiquettes.


Utiliser les informations d'exécution


Au moment de l'exécution, vous pouvez vérifier d'où le constructeur de classe a été appelé. Par exemple, via la méthode debug_backtrace ( http://php.net/manual/ru/function.debug-backtrace.php ) ou utilisez la fonctionnalité Xdebug similaire pour contrôler le code dans l'environnement dev \ test. Un exemple de solution formalisée se trouve ici ( https://coderwall.com/p/ixvnga/how-emulate-private-class-concept-in-php ).


en utilisant debug_backtrace
 /** * The private class */ final class PrivateClass { /** * defines the only class able to instantiate the current one * * @var string */ private $allowedConsumer = 'AllowedPrivateClassConsumer'; /** * constructor * * @throws Exception */ public function __construct() { /** * here comes the privacy filter, it could be extracted to a private method * or to a static method of another class with few adjustments */ $builder = debug_backtrace(); if (count($builder) < 2 || !isset($builder[1]['class']) || $builder[1]['class'] !== $this->allowedConsumer) { throw new Exception('Need to be instantiated by '.$this->allowedConsumer); } } } 

Utilisez des classes anonymes


Une fonctionnalité relativement nouvelle dans php est les classes anonymes ( http://php.net/manual/ru/language.oop5.anonymous.php ). Après avoir décrit la classe anonyme à l'intérieur de la méthode protégée, nous cherchons à la cacher. Afin de ne pas gâcher la définition d'une classe à l'intérieur d'une fonction, vous pouvez décrire la classe "privée" dans un fichier séparé comme abstraite, et la développer déjà dans la définition d'une classe anonyme. Un bon exemple d'utilisation de cette méthode se trouve sur ce lien ( https://markbakeruk.net/2018/06/25/using-php-anonymous-classes-as-package-private-classes/ ).


Sur la base du matériel trouvé, il est clair que la fonctionnalité des classes de masquage est dans une certaine mesure demandée (et existe dans de nombreuses langues), cependant, la pratique de son utilisation est très limitée, peut-être en raison du manque de description d'exemples dans diverses "meilleures pratiques", collections de modèles et sources similaires. Ce qui, à mon avis, est plutôt étrange, l'accent est mis sur le masquage des méthodes internes et des propriétés des objets, mais presque personne ne fait attention au fait que de plus grands morceaux logiques de code sous la forme de classes de bibliothèque d'utilité ou de domaines de domaine restent dans l'espace de visibilité globale.

Source: https://habr.com/ru/post/fr435894/


All Articles