Bonjour à tous!
Ce mois-ci, nous avons terminé le premier ensemble du
cours Backend PHP Developer et nous les embauchons avec puissance et main (autant que possible pendant les vacances). Le cours a été réapprovisionné par un autre enseignant -
Evgeny Volosatov , que beaucoup connaissent probablement. Eh bien, nous partageons traditionnellement des choses intéressantes.
Allons-y.
Dans toute application, certaines parties du code «croisent» plusieurs parties de l'architecture en même temps.
Ce problème n'est pas si évident lorsque vous travaillez avec un cadre entièrement fonctionnel. Votre problème sera très probablement répandu, et il y aura une chance que le cadre l'ait déjà résolu en sacrifiant une division des responsabilités ou en fournissant une abstraction au-dessus du cadre. De nombreux frameworks utilisent une architecture orientée événement pour résoudre les problèmes de fonctionnalité de bout en bout. Mais il arrive toujours un moment où le cadre n'est pas en mesure de fournir le niveau de contrôle souhaité sur un morceau de logique particulier. Cela est particulièrement vrai lors de l'utilisation de microframes ou du développement avec des bibliothèques spécialisées. Plus votre application prend en compte les principes de séparation des responsabilités, plus le rôle de la fonctionnalité de bout en bout dans votre architecture sera important.

Programmation PHP orientée aspect
La programmation orientée aspect (AOP) est un paradigme de programmation axé sur l'organisation et la modularisation des fonctionnalités de bout en bout. Cas d'application - ACL, journalisation, gestion des erreurs, mise en cache.
Les hypothèses intégrées (internes) de PHP (lorsque vous définissez une fonction / constante / classe, elle reste définie pour toujours) rendent le paradigme AOP difficile à implémenter.
Li3 a été le premier à résoudre le problème de la fonctionnalité de bout en bout en utilisant un mécanisme de filtrage qui permet de filtrer la logique d'une méthode par le biais de fermetures. Pour rendre la méthode filtrable, l'implémentation de Li3 nécessite l'ajout manuel de code de modèle. Avec de telles limitations, les techniques AOP sont limitées aux techniques de filtrage.
Autres implémentations AOP bien connues en PHP:
L'extension PECL AOP est une approche intéressante mais en même temps risquée, car la prise en charge des extensions PECL n'est pas courante. Une autre option est Go! Libraries, qui est une implémentation AOP qui corrige le code PHP à la volée, ce qui permet d'utiliser des méthodes AOP.
Il existe d'autres implémentations, mais la plupart d'entre elles sont construites sur la base de procurations (pour autant que je sache), et cette approche a de nombreuses limites.
Nouveau mec dans la région
La génération automatique de code existe depuis longtemps en PHP et est utilisée dans de nombreuses bibliothèques, par exemple
ProxyManager. Et grâce à l'adoption de Composer,
Go! montre que l'édition de code à la volée est possible.
Si la génération de code peut toujours être considérée comme simple, la correction du code est un peu plus compliquée. Premièrement, en PHP, il n'y a pas d'analyseur de code intégré, et deuxièmement, il y a très peu de bibliothèques qui résolvent les problèmes d'analyse du code PHP. La plus connue est la bibliothèque
PHP-Parser . PHP-Parser est un excellent outil, mais même il ignore la mise en forme des espaces dans les arbres de syntaxe abstraite générés. Ce qui rend difficile la correction du code. En effet, le code à corriger est du vrai code exécutable. Par conséquent, si vous souhaitez que le retour arrière soit précis avec des erreurs, vous devez prendre en compte les numéros de ligne dans le fichier corrigé.
Pour cette tâche, nous utilisons le
correcteur de code Kahlan JIT. Kahlan est le nouveau framework de test Unit & BDD, grâce aux techniques d'édition JIT, permettant le code de patch stub et singe directement dans Ruby ou JavaScript. Sous le capot, nous constatons que cette bibliothèque est basée sur l'analyseur PHP rudimentaire. Mais, néanmoins, il est suffisamment rapide et stable pour nous convenir.
La bibliothèque de filtres est disponible sur
github.com/crysalead/filter et peut être utilisée comme suit.
Tout d'abord, le correcteur de code JIT doit être initialisé dès que possible (par exemple, immédiatement après avoir activé le composeur de chargement automatique):
include __DIR__ . '/../vendor/autoload.php'; use Lead\Filter\Filters; Filters::patch(true);
Notez que l'édition de code n'est possible que pour les classes chargées par le composeur autoload'er. Si une classe est ajoutée à l'aide des expressions require ou include, elle est déjà chargée avant d'appeler Filters :: patch (true) et ne sera donc pas corrigée.
Par défaut, tout le code corrigé sera stocké dans / tmp / jit, mais vous pouvez toujours le changer en votre propre:
Filters::patch(true, ['cachePath' => 'my/cache/path/jit']);
Les fichiers mis en cache seront restaurés automatiquement chaque fois que vous modifiez un fichier PHP.
Attention!
Filters::patch(true)
est le moyen le plus simple de configurer le patcher, gardez à l'esprit que tout votre code sera corrigé. Cela peut prendre du temps pour encapsuler toutes les méthodes de votre base de code dans une fermeture de filtre.
Heureusement, si la fonctionnalité de bout en bout joue un rôle crucial dans un code bien conçu, seules quelques méthodes sont nécessaires dans le projet. Par conséquent, l'approche préférée consiste à corriger uniquement les méthodes qui seront filtrées:
Filters::patch([ 'A\ClassName', 'An\Example\ClassName::foo', 'A\Second\Example\ClassName' => ['foo', 'bar'], ], [ 'cachePath' => 'my/cache/path/jit', ]);
Ainsi, vous pouvez choisir de corriger toutes les méthodes d'une certaine classe, une seule méthode ou plusieurs d'entre elles.
Filtre API
Maintenant que le patcher JIT est activé, créez un filtre de journal:
use Chaos\Filter\Filters; use Chaos\Database\Database; use Monolog\Logger; use Monolog\Handler\StreamHandler; $logger = new Logger('database'); $logger->pushHandler(new StreamHandler('my/log/path/db.log', Logger::WARNING)); Filters::apply(Database::class, 'query', function($next, $sql, $data, $options) use ($logger) { $logger->info('Ran SQL query: ' . $sql); return $next($sql, $data, $options); });
L'exemple ci-dessus crée un filtre de journal de requête SQL pour la bibliothèque de bases de données Chaos. Plus d'informations sur le filtre API peuvent être trouvées sur
github.com/crysalead/filter .
Conclusion
AOP, à mon avis, est la vraie réponse pour la fonctionnalité de bout en bout. Toutes les autres abstractions sont également redondantes et dans la plupart des cas limitées à un certain cadre. Je ne perds pas espoir qu'un jour PHP fournira une API intégrée pour une programmation orientée aspect. Mais maintenant, je pense que la correction de code JIT est la meilleure option, où les avantages l'emportent largement sur la surcharge du processeur, qui peut être pratiquement négligée lorsque la correction de code JIT n'est pas appliquée à l'échelle mondiale.
LA FIN
Comme toujours, nous attendons, le cas échéant, des questions, un souhait et vous invitons à
une leçon ouverte où vous pourrez écouter une conférence intéressante et mieux connaître le nouveau
professeur .