PHP で作る軽量なコンソールアプリケーション

電脳世界

近年はコンソールアプリケーションの開発を行う際に Go を採用する機会が増えたのではないでしょうか。弊社でもコンソールアプリケーションの開発に Go を採用する事例が増えています。省メモリで高速に動作し、バイナリ化できるなどのメリットは PHP で抱えていた多くの問題を解決しうる大きな強みです。

とはいえ PHP でコンソールアプリケーションを開発する機会が無くなったかというと、そうではありません。PHP エンジニアが多いことや、すでに開発してある豊富な資源を利用できること、時には納期との兼ね合いや保守フェイズでの運用の行いやすさなどを考慮して PHP を採用する機会もあります。弊社で PHP を利用したコンソールアプリケーションを新しく開発する際には、Symfony Console Component と Zend ServiceManager を組み合わせる事例が増えてきました。本記事では、この組み合わせでの開発に関してご紹介します。

Symfony Console Component

Symfony Console Component は、Symfony が提供するコマンドラインのコマンドを作成するためのコンポーネントです。コンソールコマンドは、cron ジョブやインポートジョブ、その他の定期的なバッチジョブなど、定期的なタスクに使用することができます。

インストールは Composer を利用して行うことができます。

composer require symfony/console

具体的な利用方法は公式のドキュメントをご参照ください。

Zend ServiceManager

Zend ServiceManager は、Zend が提供するファクトリドリブンな DI コンテナです。DI コンテナから取得したいサービスを生成するファクトリクラスを定義し設定することで、サービスのインスタンスをファクトリクラス経由で取得することができるようになります。

インストールは Composer を利用して行うことができます。

composer require zendframework/zend-servicemanager

具体的な利用方法は公式のドキュメントをご参照ください。

コンソールアプリケーションの実装例

Symfony Console Component と Zend ServiceManager を組み合わせたアプリケーションのサンプルコードを Github にて公開しています。実装例については Github のリポジトリをご参照ください。

フレームワークを使わない理由

PHP でコンソールアプリケーションを作成する場合には、Laravel や Phalcon などのフレームワークを利用することもできます。フレームワークを利用した場合には、それらが提供する強力な機能によって、様々な処理を簡単に実装することができます。これは非常に大きなメリットです。しかし、フレームワークのルールに縛られることによって、アプリケーション層とビジネスロジックの境目が曖昧になってしまったり、フレームワークに依存しすぎることによって、フレームワークのバージョンアップが困難になってしまったりといった弊害が発生します。

アイスタイルでは、持続的に成長可能なアプリケーションの作成を目指しています。その目標を達成するために挑戦しているのがドメイン駆動設計やクリーンアーキテクチャです。

これらを実施しようとした場合、ドメイン層にフレームワークの知識を持ち込むべきではないため、必然的にフレームワークに求める機能が減っていきます。アプリケーション層がどんどんと薄くなっていくため、必要な機能をライブラリを使って実装することで、必要最低限なスッキリとした構成にすることができ、ライブラリのバージョンアップや変更などの変化に強い状態にすることができます。そこで一つの回答として採用されているのが、Symfony Console Component と Zend ServiceManager の組み合わせでした。

この組み合わせで実装したアプリケーションは、アプリケーションの実行に必要なコードのみが存在することになるため、非常に軽量で見通しが良くなるというメリットがありました。もちろんフレームワークを利用することによって、統一された規則に沿って実装されるコードも見通しが良くなりますが、すべてのコードがアプリケーションに関して意味があるというのは非常に大きな強みであると感じました。

なお、データベースや API への通信を担うインフラストラクチャ層では、最適なライブラリを選択して取り入れるようにしています。以下が最近よく使うライブラリの例です。

おわりに

今回は Symfony Console Component と Zend ServiceManager を組み合わせたコンソールアプリケーションを例にご紹介しましたが、重要なのは何を重視するかです。もしアプリケーションを高速に開発することを重視するのであれば、フレームワークを採用することは有力な選択肢に挙がると思います。サービスと共に成長していくアプリケーションを開発したいのであれば、フレームワークを採用しないことも選択肢に挙がるかと思います。

私たちが関わっていくサービスが何を重視するのかを、エンジニアだけでなく一緒にサービスをつくっていくチーム全体で話し合い、理解して、それらをコードに落とし込んでいくことが、私たちの重要な仕事であると考えています。

参考

PHP Engineer who developed web sites with Phalcon