Symfonyでサービスをコントローラに注入する方法を解説!初心者でもわかるDIの使い方
生徒
「Symfonyでサービスというものを使うって聞いたんですが、それって何ですか?」
先生
「サービスは、特定の処理をまとめて再利用できる便利な仕組みです。コントローラに注入して使うことで、コードをきれいに保てますよ。」
生徒
「注入ってどういう意味ですか?難しそう…」
先生
「大丈夫。注入というのは、必要な道具を渡してあげることだと思えばOKです。基本からゆっくり見ていきましょう!」
1. Symfonyの「サービス」とは?
Symfony(シンフォニー)におけるサービスとは、特定の処理をまとめた「部品」のようなものです。たとえば、「メッセージを作る処理」や「計算をする処理」などをサービスにしておくと、アプリケーションのいろいろな場所で何度も使い回すことができます。
このようにサービスを使うことで、重複するコードをなくして整理されたプログラムを作ることができるのです。
2. コントローラにサービスを「注入」するとは?
Symfonyでは、サービスをコントローラで使いたい場合、コンストラクタインジェクションと呼ばれる方法で受け取ります。これは、「このクラスを使うならこのサービスも一緒に渡してね」という書き方です。
「注入(インジェクション)」とは、必要なもの(サービス)をクラスの外から渡すことを意味します。DI(Dependency Injection/依存性注入)とも呼ばれますが、難しく考えずに「使いたいものを事前に用意して渡してもらう方法」と覚えておけばOKです。
3. サービスクラスを作ってみよう
まずは、簡単なメッセージを返すサービスを作ってみましょう。サービスクラスは通常、src/Serviceというフォルダに作ります。
namespace App\Service;
class MessageService
{
public function getMessage(): string
{
return 'こんにちは、サービスからのメッセージです!';
}
}
このMessageServiceクラスには、getMessage()というメソッドがあり、メッセージの文字列を返します。
4. サービスをコントローラで使う方法
次に、このサービスをコントローラに注入して使ってみます。
Symfonyでは、特別な設定をしなくても、src/Serviceの中のクラスは自動的にサービスとして認識されます。つまり、自分で設定ファイルを書かなくても使えるのです。
namespace App\Controller;
use App\Service\MessageService;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
class HelloController extends AbstractController
{
private MessageService $messageService;
public function __construct(MessageService $messageService)
{
$this->messageService = $messageService;
}
#[Route('/service-test', name: 'service_test')]
public function index(): Response
{
$msg = $this->messageService->getMessage();
return new Response($msg);
}
}
ポイント解説:
__construct()(コンストラクタ)は、コントローラが使われるときに自動で呼び出される特別な関数です。- ここでサービスを受け取り、クラスの中で保存しています。
$this->messageServiceを使って、サービスの中のメソッドgetMessage()を呼び出します。
5. サービスを使うメリットとは?
サービスを使うと、Symfonyのアプリケーションが部品化されて整理された構造になります。
- 共通の処理をまとめて再利用できる
- テストしやすくなる
- コントローラがすっきりして見やすくなる
たとえば、「あいさつメッセージを作る処理」や「メールを送る処理」など、いろいろな場所で同じことをしたいときに、サービスとして作っておけば、どのコントローラからでも簡単に使えるようになります。
6. サービスの場所とファイル名に注意しよう
Symfonyでサービスを使うためには、src/Serviceの中にPHPファイルを作成し、クラス名とファイル名が一致している必要があります。
例えば、MessageServiceというクラスであれば、MessageService.phpという名前のファイルにして、namespace App\Service;のように正しい名前空間を設定しましょう。
7. 実行結果を確認しよう
ブラウザで /service-test にアクセスしてみましょう。すると、以下のように表示されるはずです。
こんにちは、サービスからのメッセージです!
これで、Symfonyのコントローラにサービスを注入して使う方法がわかりました。
まとめ
Symfonyでサービスをコントローラに注入するしくみを学ぶことで、アプリケーション全体の構造をより整理されたものにでき、複雑な処理もわかりやすく分離できるようになります。特にサービスは「共通の処理をまとめるための部品」という位置づけであり、コードを繰り返し書かずに機能を再利用できるところが大きな魅力です。また、Symfonyはサービスを自動的に認識する仕組みを備えているため、初学者でもファイルを正しい場所に作成するだけで自然とDIが機能し、コントローラがすっきりした読みやすい構成になります。
さらに、コンストラクタインジェクションを使うことで依存関係が明確になり、コントローラ内部の処理がより役割分担された形で整理できます。これは大規模開発だけでなく、小さなアプリケーションでも役に立つ考え方で、ひとつ一つの処理を独立させて考えられるため、後からコードを変更したりテストしたりするときにも大きな効果を発揮します。サービスにまとめた処理はテストしやすく、アプリケーションの品質向上につながります。
サービス注入の簡単な復習サンプル
以下は、サービスを作成し、それをコントローラで呼び出す基本構造をもう一度整理したものです。繰り返し見ておくことで、DIの働きが自然に身につきます。
// サービスクラス
namespace App\Service;
class GreetingService
{
public function greet(string $name): string
{
return $name . 'さん、ようこそサービスの世界へ!';
}
}
// コントローラ側
namespace App\Controller;
use App\Service\GreetingService;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
class GreetingController extends AbstractController
{
private GreetingService $greetingService;
public function __construct(GreetingService $greetingService)
{
$this->greetingService = $greetingService;
}
#[Route('/greet/{name}', name: 'greet_user')]
public function greetUser(string $name): Response
{
$msg = $this->greetingService->greet($name);
return new Response($msg);
}
}
このサンプルのように、サービスにまとめておけば処理を複数の場所で簡単に取り出して利用でき、コントローラ本体には本来の役割であるリクエスト処理だけを集中させることができます。アプリケーションの規模が大きくなるほど、この役割分割は効果的に働き、保守性も大幅に向上します。SymfonyのDIはシンプルで扱いやすいため、初心者でも自然とよい構造のプログラムを書きやすくなるのが特徴です。
生徒
「サービスを使うと、同じ処理を何度も書かなくてよくなるっていうのがすごく便利ですね。コードがすっきりする理由がわかりました!」
先生
「そうなんです。サービスにまとめておくことで、コントローラは“受け取りと返却”に集中できるようになり、全体の見通しも良くなりますね。」
生徒
「コンストラクタで受け取るっていうのも最初は難しそうに感じたけど、意味がわかったら自然な流れに思えてきました。」
先生
「依存性注入は慣れるほど力を発揮しますよ。サービスを増やしたり、処理を細かく分けていくと、もっと便利さを実感できるはずです。」
生徒
「これから作るアプリでも、どんどんサービスを使って整理しながら書いてみます!」
先生
「その調子です。学んだ内容を実際に書いてみることで理解は必ず深まりますよ。」