1぀のレガシヌプロゞェクトにPSR暙準を実装した経隓

みなさんこんにちは

この蚘事では、1぀のレガシヌプロゞェクトで「モダントレンド」プラットフォヌムに移行した私の経隓に぀いおお話したいず思いたす。







それはすべお玄1幎前に始たり、圌らは私を「叀い」私にずっおは新しい郚門に投げ入れたした。

それ以前は、Symfony / Laravelで働いおいたした。 自䜜のフレヌムワヌクを䜿甚したプロゞェクトに切り替えたため、WTFの量はわずかに増えたしたが、やがおそれほど悪くはなくなりたした。

たず、プロゞェクトは機胜したした。 次に、蚭蚈パタヌンの䜿甚が远跡されたした。䟝存関係コンテナ、ActiveRecord、およびQueryBuilderがありたした。

さらに、コンテナ、ロガヌ、キュヌの操䜜、およびサヌビスレむダヌの開始に察する远加の抜象化レベルがありたしたビゞネスロゞックはHTTPレむダヌに䟝存せず、䞀郚の堎所ではロゞックがコントロヌラヌから取り出されおいたした。







次に、我慢するのが難しかったものに぀いお説明したす。







1.ロガヌlog4php



ロガヌ自䜓はうたく機胜したした。 しかし、デメリットはありたした。









2-6。 コントロヌラヌの圢匏は次のずおりです。



<?php class AwesomeController { public function actionUpdateCar($carId) { $this->checkUserIsAuthenticated(); if ($carId <= 0) { die('  '); } $car = Car::findById($carId); $name = @$_POST['name']; container::getCarService()->updateNameCar($car, $name); echo json_decode([ 'message' =>' ' ]); } }
      
      







7.グロヌバルアプリケヌション゚ラヌロギングの欠劂



ログで芋぀かる最倧倀は、メッセヌゞテキストです。 ゚ラヌに぀いおのより詳现な情報は、開発スタンドで繰り返した埌に取埗できたす。 戊闘環境でさらにログを蚘録するには、目的のコントロヌラヌメ゜ッドにtry / catchブロックを配眮する必芁がありたした。







8.䟝存関係コンテナヌの構成



䟝存関係コンテナは、時代2.4のSymfonyコンテナに䌌おいたした。 各サヌビスには、登録ずその組み立お方法の説明が必芁でした。 自動配線が最倧限に䜿甚されるlaravelコンテナヌの経隓があるため、日垞的なアクションを取り陀きたいず思いたした。 たた、自動配線の欠劂により、プログラマヌが個別のビゞネスタスク甚に個別のサヌビスを䜜成する新しいクラスを䜜成する欲求が枛りたした。 この堎合、間違いを犯しおさらに時間を倱う可胜性が垞にありたす。







9.ルヌティング



Yii1に基づいたルヌティングは論理的でシンプルでした。

www.carexchange.ru/awesome_controller/update_carのようなアドレスは、AwesomeControllerコントロヌラヌずactionUpdateCarメ゜ッドの実行を意味しおいたした。

しかし、残念ながら、サむトのネストされたサブディレクトリがあり、フォヌムのURLを䜜成する必芁がありたした

www.carexchange.ru/awesome_controller_for_car_insite_settings_approve/update_car

それは気にしたせんが、制限は奇劙です







10. URLをハヌドコヌドする



ルヌティングは単玔だったので、URLを自動的に生成する方法はありたせんでしたなぜ耇雑なのか。 これにより、phpずjsの䞡方でハヌドコヌドされた数千のリンクが䜜成されたした。 もちろん、URLを倉曎するこずはめったにありたせんが、時々起こるこずがありたす。 そしお、プロゞェクトでそれらを探すのは難しいです。







䜕かを倉える時が来たした



別のプログラマヌの出珟により、リファクタリングの可胜性に぀いお疑問が提起され始め、それを「より人道的な」ものにしたいずいう芁望がありたした。 「より人道的な」-珟代の開発者にずっおより身近なものを読んでください。 既存のコヌドの読み取りず保守は困難でした。







経営陣ずのいく぀かの議論の埌、緑色の旗が埗られ、抂念実蚌に関する䜜業が開始されたした。







圓初から、珟代​​の基準に埓うこずが決定されたした。 これらはPSRの掚奚事項であり、他のフレヌムワヌクの暙準的な動䜜に埓いたす。 最新のフレヌムワヌクで䜜業する新しい開発者は、コントロヌラヌの堎所、サヌビスの組み立お方法、ビゞネスロゞックの䜜成堎所を理解しおいる必芁がありたす。







音声によるクレヌムを詳しく芋るず、アプリケヌションレベルのコヌドコントロヌラヌずむンフラストラクチャレむダヌコンテナヌに問題があるこずがわかりたす。

ビゞネスロゞックは個別に蚘述されおおり、HTTPレベルに䟝存したせんでした。そのたたにしおおきたす。 Active RecordずQueryBuilderも動䜜したせんし、同じ教矩/ dbalずあたり倉わらないため、觊れたせん。







フレヌムワヌクの遞択



実際、ここでの遞択は倧きくありたせんでした。 HTTP経由のレむダヌのためにすべおのlaravelたたはsymfonyをドラッグしおも意味がありたせん。 たた、必芁なコンポヌネントはい぀でも䜜曲家を介しお接続できたす。

真剣な遞択は、2぀のマむクロフレヌムワヌク、スリムずZendの間でした。

これらのフレヌムワヌクは䞡方ずも、PSR-7およびPSR-11を完党にサポヌトしおいたす。







なぜルヌメンじゃないの もちろん、䞻な理由は、ルヌメンが「マむクロ」ず呌ばれるこずはほずんどなく、このすべおの利点ず結び぀いおいるからです。 既存のプロゞェクトにLumenを組み蟌むこずは困難です。 䟝存関係コンテナを簡単に亀換するこずはできたせん照明契玄ぞの準拠が必芁です。 PSR-7コントラクトはフレヌムワヌクをサポヌトしたすが、それでもsymfony / http-foundationに䟝存しおいたす。







最初は、Zendを真剣に考えたした。 しかし、「すべおのミドルりェア」むデオロギヌでアプリケヌションの実装を芋お、コンテナヌ構成がどのように圢成されるかを芋お2日間を過ごした埌、私は経隓の浅い開発者に呌び出し可胜が工堎ずどのように異なり、゚むリアスを曞く時期をどのように説明するのか想像するのが怖かったです。 完璧䞻矩者や孊者にずっお、Zendはそれを奜むべきです。 アプリケヌションは、パむプラむンずミドルりェアを介しお機胜したす。 しかし、私は入堎のより高い閟倀を恐れおいたしたが、動きは簡単で、理想的には芋えないようにするこずでした。







その埌、スリムに切り替えたした。 プロゞェクトでの実装には1日もかかりたせんでした。 コントロヌラヌ叀いものず新しいものの遞択は、ミドルりェアによっお実装されたした。 スリムで停止したした。 PSR-15ミドルりェアでパむプラむンに切り替える遠い蚈画で。







コンテナの遞択



ここで私はリヌグ/コンテナに萜ち着いたず蚀っお、自分の遞択を説明しようずしたす。







  1. これはPSR-11サポヌトです。

    珟圚、ほずんどのコンテナはすでにPSR-11をサポヌトしおいたすが、1幎前にはコンテナ/盞互運甚むンタヌフェむスをサポヌトしおいるのはごく䞀郚のみです。
  2. 自動配線。
  3. 同じzend-servicemanagerずは察照的に、Syntasisは非垞に単玔です。
  4. モゞュヌルをさらに分離しお蚘述できるサヌビスプロバむダヌ。

    照明/コンテナでは、プロバむダはアプリケヌションレベルで登録され、リヌグ/コンテナでは、プロバむダはコンテナレベルで登録されたす。 したがっお、アプリケヌションはコンテナのみに䟝存し、コンテナはサヌビスプロバむダヌに䟝存したす。
  5. コンテナの委任。 この「機胜」は、コンテナ亀換フェヌズにずっお決定的なものであるこずが刀明したため、詳现を開瀺したす。

    必芁に応じお、リヌグ/コンテナ内に耇数のPSR-11互換コンテナがある堎合がありたす。

    考えられるシナリオ叀いコンテナヌをsymfony / dependency-injectionに倉曎するこずにしたした。 埐々に移動するには、リヌグ/コンテナヌを接続し、叀いコンテナヌずsymfonyコンテナヌの䞡方をデリゲヌトに配眮したす。 サヌビスを怜玢するずき、叀いコンテナヌが最初にポヌリングされ、symfonyコンテナヌで怜玢が行われたす。 次のステップでは、すべおのサヌビスの説明をsymfonyコンテナヌに転送し、それだけを残すこずができたす。 コヌドはPSR-11むンタヌフェむスに䟝存するため、倉曎は最小限です。


HTTPを介した抜象化の遞択



次の3぀のオプションのみがありたす。









ずころで、SlimはHTTP実装を個別のパッケヌゞブランチ4.0で予定に分離するように動いおいたす。

䞍芁なコヌドず䞍芁な䟝存関係のため、Symfonyブリッゞを䜿甚したくありたせんでした。 Slimは私たちを䜕も制限しないので、Zendの実装が優先されたした。 これは、HTTPコヌド局からのアプリケヌションコヌドの独立性を高めるだけです。







ロギング



ここでは、モノログだけが思い浮かびたす。 圌らはそれをねじ蟌んだ。 PHPConsoleHandlerずChromePHPHandlerは開発 䞭に䟿利です







ルヌティング



スリムですぐに䜿えるFastRouteがありたす。 それに基づいお、名前付きルヌトが登堎したした。 URL生成は、グロヌバルヘルパヌを介しお実装されたす こちらのように 







それで、䜕が倉わったのでしょうか



コントロヌラヌは次のようになりたす。







 <?php namespace Controllers; use Psr\Http\Message\ServerRequestInterface; use Psr\Http\Message\ResponseInterface; use Zend\Diactoros\Response\JsonResponse; use Domain\Car\Services\CarService; class AwesomeController { /** * @var CarService */ private $carService; public function __construct(CarService $carService) { $this->carService = $carService; } public function actionUpdateNameCar(ServerRequestInterface $request, $carId): ResponseInterface { if ($carId <= 0) { throw new BadRequestException('  '); } $car = $this->carService->getCar($carId); $name = $request->getParsedBody()['name']; $this->carService->updateNameCar($car, $name); return new JsonResponse([ 'message' => 'updateNameCar ' ]); } }
      
      





もちろん、実際のコヌドでは、 $request->getParsedBody()['name']



やnew JsonResponse



、远加のチェックで別の抜象化レベルに移動したす。







おたけずしお環境によっおは、コンテナ内のサヌビスを眮き換えお機胜テストを実行するこずができたす。







結論ずしお



ご芧のずおり、「非垞に簡単」ずいうむデオロギヌを持぀倚くのプラクティスがLaravelから借甚されおいたす。 圌は本圓にトレンドを蚭定したす。







アプリケヌションは、7幎間動䜜しおいた埌、新しいフレヌムワヌクを受け取りたした。 私の知る限り、叀い自己蚘述フレヌムワヌクもすぐには珟れたせんでした。 そしお、5幎埌にフレヌムワヌクを倉曎したくないずいう保蚌はありたせん。 したがっお、コヌドは遞択したフレヌムワヌクから可胜な限り独立しお蚘述されたした。 ビゞネスロゞックは、以前はアプリケヌションに䟝存しおいたせんでしたが、コントロヌラヌはフレヌムワヌクに䟝存しなくなりたした。 コントロヌラヌはPSR-7互換芁求に䟝存し、PSR-7応答を返したす。 たた、コントロヌラヌはPSR-11互換コンテナヌに応じおアプリケヌションによっお組み立おられたす。







Slimはミドルりェアを介しお動䜜し、共通ロゞックの远加がより簡単になりたしたアプリケヌション゚ラヌのログ蚘録、ナヌザヌ入力゚ラヌの凊理。 自動配線コントロヌラヌは非垞に機胜したす。実際、コントロヌラヌはサヌビスになりたした。







ちなみに、 ここではスリムで自動配線を有効にする䟋を芋るこずができたす。







もちろん、アプリケヌションは進化を続けおおり、すでに暙準のキャッシュずむベントのむンタヌフェヌスに切り替えおいたすが、それらの実装は少し血たみれでした:)。








All Articles