How to create a php service for symfony 2 & 3 with entity manager and service container

How to create a php service for symfony 2 & 3 with entity manager and service container

For a non-framework php developer the things are so easy as use require_once to the php file that we want to include in our code file,however we will need to write this line in every file that we need our php file. In symfony 2 & 3 when we need to inject a file like this, we need to create a symfony service, this will be accesible in all the controllers in our project. 

A service is any PHP object that performs some sort of "global" task. It's a purposefully-generic name to describe an object that's created for a specific purpose (e.g. delivering emails). Each service is used throughout your application whenever you need the specific functionality it provides. You don't have to do anything special to make a service: simply write a PHP class with some code that accomplishes a specific task.

1. Create the Extensions folder

To create a special service, we need to create a folder that will contain our class inside our container bundle, for example: given the /app/src/ourcodeworld folder, this folder contains more bundle inside, therefore as an organization thing, we are going to create the Extensions folder inside of it.

2. Create the service class

Now we will create a class that will contain our service (it will receive as parameters in the contructor, the entity manager and the service container and then i'll explain how this will be injected) and we will call the class (and the file) OCWServices.php for example (change the name if you want and change the class name too):

Note: the functions inside of the OCWServices class aren't meant to work at the first time, they're just an example as they use the injected dependencies. Remove them when you implement it.

<?php
// /app/src/ourcodeworld/Extensions/OCWServices.php
// Don't forget to change the namespace acording to the path and the parent bundle.
namespace ourcodeworld\Extensions;

// don't forget the namespaces too !
use Doctrine\ORM\EntityManager;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
use Symfony\Component\Config\Definition\Exception\Exception;
use Symfony\Component\DependencyInjection\Container;

// This will be the name of the class and the file
class OCWServices{
    protected $em;
    private $container;
    
    // We need to inject this variables later.
    public function __construct(EntityManager $entityManager, Container $container)
    {
        $this->em = $entityManager;
        $this->container = $container;
    }
    
    /**
     * Find an user by role
     *
     * @PLEASE DELETE; THIS IS JUST AN EXAMPLE
     * @note We use the entity manager (Doctrine injected in our constructor)
     * @param string $role
     * @return entities
     */
    public function findUsersByRole($role) {
        $qb = $this->em->createQueryBuilder();
        
         $qb->select('u')
            ->from('mybundleBundle:User', 'u')
            ->where('u.roles LIKE :roles')
            ->setParameter('roles', '%"' . $role . '"%');
        
        return $qb->getQuery()->getResult();
    }
    
    
    /**
     * Example of how to retrieve another service within a service.
     * we request a pdf service that we can retrieve thanks to the container injected in the constructor
     * 
     * @PLEASE DELETE; THIS IS JUST AN EXAMPLE
     * @param type $html
     */
    public function createPDF($html = ""){
        $pdf = $this->container->get("myimaginary.pdfclass");

        $pdf->create('vertical', PDF_UNIT, PDF_PAGE_FORMAT, true, 'UTF-8', false);
        $pdf->generate();
    }
    
}

This class contains 2 functions that explain how to use the service container and the entity manager injected with the constructor. Now, if you were aware, we've just sent 2 variables in the constructor of the class (entity manager and the service container). We need to send this 2 variables of someway or our app will crash.

3. Register the service

Go to the services.yml file (located in /app/config/services.yml), and we are going to register our service like this :

# Learn more about services, parameters and containers at
# http://symfony.com/doc/current/book/service_container.html
parameters:
#    parameter_name: value

services:
#    service_name:
#        class: AppBundle\Directory\ClassName
#        arguments: ["@another_service_name", "plain_value", "%parameter_name%"]

#register our custom service with a name in this case OCWServices
    OCWServices:
# The namespace with the name of the class that contain our service
        class: ourcodeworld\Extensions\OCWServices
#The services that we will inject (see the constructor)
        arguments: [ "@doctrine.orm.entity_manager" , "@service_container" ] 

Now, from our controllers we will be able to retrieve our service like this (do not forget to clear the cache)

<?php

public function indexAction(){
    $myservice = $this->get('OCWServices'); // the name given in the settings.yml

    //Call any of the methods in it
    //$myservice->createPDF();
    $myservice->myMethod();
}

Have fun !

Become a more social person