Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can i better understand service layer in symfony2 in php

Tags:

php

symfony

I am learning to use symfony2 but i am having hard time in learning what is service layer and where it can be used.

How can i better understand about service layer in symfony2

like image 598
Mirage Avatar asked Jan 17 '23 04:01

Mirage


1 Answers

I'll try my best to explain services, but the Symfony2 docs do a better job than I'll be able to.

At it's core, a service is simply a class. A class becomes a service when it is registered with Symfony2's Dependency Injection Container (or just Container for short.) At this point, the class is part of an application's Service Layer.

A service may have dependencies (and often times, it does), but it is not required to. A service is often used as a dependency for other services. Let me give you an example:

  • You have a class used to send email, called EmailSender
  • You have a class that contains the instructions on how to send email over SMTP, called SmtpTransport
  • EmailSender has a dependency in the form of SmtpTransport. In other words, for EmailSender to be able to do its job, it needs an instance of SmtpTransport to be injected into it. (Note that although EmailSender has a dependency, SmtpTransport does not.)

Say you need to use EmailSender in five different places in your app. In each spot, you may have code like this:

$emailSender = new EmailSender(new SmtpTransport());  
$emailSender->send($email)

That's not a lot of code (since EmailSender only has one dependency), but what happens when you decide that instead of using SMTP, EmailSender should use a transport class for sendmail? You'd have to edit each block of code in order to update it.

The alternative is to register EmailSender and its dependencies as services.
Registration looks like this:

// YourApp/YourBundle/Resources/config/services.yml
services:
  smtp_transport:
    class: YourApp\YourBundle\Email\SmtpTransport

  email_sender:
    class: YourApp\YourBundle\Email\EmailSender
    arguments:
      - @smtp_transport

Now, to use it (from a container aware context):

$container->get('email_sender')->send($email);

Notice how much simpler and cleaner it is to actually use the class to send emails? Sure, you have to do the work to register the service first, but that's trivial and only has to be done once.

Imagine that EmailSender has three dependencies, instead of one. By using services, you only need to modify the service registration without having to change your implementation code (the code used to send the email).

In short, the service layer acts as a central repository for classes that a) have one or more dependencies b) need to be used in a 'global' scope. By fetching these service classes from the Dependency Injection Container, you end up with less redundant code and an easier way to make wide reaching changes.

I may be wrong, but I think Symfony2 is the first PHP framework to implement a dependency injection container. As such, a lot of PHP devs may be unfamiliar with the concept of services. I definitely suggest making sure you understand it fully, as you'll see that it's a very powerful tool. Plus, the concept of services is in no way limited to Symfony2 or even PHP - you'll be able to take advantage of this concept in a wide variety of frameworks and languages.

like image 96
Steven Mercatante Avatar answered Jan 18 '23 23:01

Steven Mercatante