Cómo crear un servicio de PHP en Symfony 2 ó 3 con entity manager y service container

Cómo crear un servicio de PHP en Symfony 2 ó 3 con entity manager y service container

Para un desarrollador de PHP que no usa un framework, las cosas son tan fáciles para incluir una clase en PHP al usar require_once en la clase en la que se requiere, sin embargo necesitarás escribir esta linea en cada clase de PHP en la que la necesites además de saber el directorio de esta. En symfony 2 y 3, cuando necesitas inyectar un archivo de esta manera, crearemos en su lugar un servicio de Symfony, este servicio será accesible en todos los controladores de nuestro proyecto y lugares en el que se tenga acceso al container de symfony.

En PHP un servicio es cualquier objeto que ejecuta algun tipo de tarea "global". Su nombre, puramente generico describe un objeto con un proposito especifico (p. ej enviar correos electronicos). Cada servicio es usado a través de tu aplicación cuando sea que necesites una funcionalidad especifica que este provee. No necesitas hacer nada en especial para hacer un servicio, simplemente escribe una clase en PHP con algo de código que cumpla con una actividad que puede ser aislada.

1. Crea la carpeta Extensions

Para crear un servicio, necesitas crear una carpeta que contendrá la clase dentro de tu bundle, por ejemplo: dada la carpeta /app/src/ourcodeworld , esta contendrá más bundles en ella, por lo tanto en cuestión de organización, vamos a crear la carpeta Extensions dentro de ella.

2. Crea la clase del servicio

Ahora, crearemos una clase que contendrá nuestro servicio (esta recibirá como parametros en el constructor, el entity manager y el service container y luego te explicare como esta será inyectada luego) y ejecutaramos la clase (y el archivo) OCWServices.php por ejemplo (cambia el nombre si deseas y cambia el nombre de la clase tambien):

Nota: las funciones dentro de la clase OCWServices no servirán en tu proyecto como primera medida a menos que las modifiques, ellas son solo un ejemplo para mostrar como las dependencias pueden ser usadas. Eliminalas cuando implementes el servicio en tu proyecto.

<?php
// /app/src/ourcodeworld/Extensions/OCWServices.php
// No olvides cambiar el namespace de acuerdo al directorio del bundle contenedor
namespace ourcodeworld\Extensions;

// No olvides incluir los namespaces necesarios
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;

// Este será el nombre de la clase y del archivo
class OCWServices{
    protected $em;
    private $container;
    
    // Inyectaremos las dependencias en el constructor luego
    public function __construct(EntityManager $entityManager, Container $container)
    {
        $this->em = $entityManager;
        $this->container = $container;
    }
    
    /**
     * Encuentra a un usuario por ROL
     *
     * @ELIMINAR; SOLO UN EJEMPLO
     * @note Usamos el Entity Manager (Doctrine inyectado en el 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();
    }
    
    
    /**
     * Ejemplo de como obtener otro servicio dentro de otro servicio.
     * Solicitamos el servicio PDF que podemos obtener atraves del container
     * 
     * @ELIMINAR; Esto es solo un ejemplo
     * @param type $html
     */
    public function createPDF($html = ""){
        $pdf = $this->container->get("myclaseimaginaria.pdfclass");

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

Esta clase contiene 2 funciones que explican cómo usar el service container y el entity manager inyectado en el constructor. Ahora, si estuviste atento, habrás notado que el constructor espera 2 objetos (entity manager y service container). Necesitamos enviar estas 2 variables de alguna manera o nuestra aplicación no funcionará.

3. Registra el servicio

Ve al archivo services.yml (localizado en /app/config/services.yml), alli registraremos nuestro servicio usando:

# Aprnede más sobre los servicios, parametro y containers en
# 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%"]

# Registra nuestro servicio personalizado con un nombre, en este caso OCWServices
    OCWServices:
# El namespace con el nombre de la clase que contiene nuestro servicio
        class: ourcodeworld\Extensions\OCWServices
# Que servicios recibirá nuestro servicio como parametros, verifica el constructor !
        arguments: [ "@doctrine.orm.entity_manager" , "@service_container" ] 

Ahora, desde cualquier controlador o clase que tenga acceso al service container, podrás acceder al servicio creado, en este caso OCWServices (no olvides limpiar la cache):

<?php

public function indexAction(){
    $myservice = $this->get('OCWServices'); // El nombre dad en services.yml

    // Ejecuta alguno de los métodos de la clase
    //$myservice->createPDF();
    $myservice->myMethod();
}

Que te diviertas !

Esto podría ser de tu interes

Conviertete en un programador más sociable