通过服务访问方法——Symfony2


Accessing Method Through Service --- Symfony2

My Controller

<?php
namespace CJ'BusinessBundle'Controller;
use Symfony'Component'HttpFoundation'Request;
use Symfony'Bundle'FrameworkBundle'Controller'Controller;
use Sensio'Bundle'FrameworkExtraBundle'Configuration'Method;
use Sensio'Bundle'FrameworkExtraBundle'Configuration'Route;
use Sensio'Bundle'FrameworkExtraBundle'Configuration'Template;
use CJ'BusinessBundle'Entity'PurchaseOrder;
use CJ'BusinessBundle'Form'PurchaseOrderType;
/**
 * PurchaseOrder controller.
 *
 * @Route("/purchaseorder")
 */
class PurchaseOrderController extends Controller
{
/**
 * Lists all PurchaseOrder entities.
 *
 * @Route("/", name="purchaseorder")
 * @Method("GET")
 * @Template()
 */
public function indexAction()
{
    $em = $this->getDoctrine()->getManager();
    $entities = $em->getRepository('CJBusinessBundle:PurchaseOrder')->findAll();
    return array(
        'entities' => $entities,
    );
}
/**
 * Creates a new PurchaseOrder entity.
 *
 * @Route("/", name="purchaseorder_create")
 * @Method("POST")
 * @Template("CJBusinessBundle:PurchaseOrder:new.html.twig")
 */
public function createAction(Request $request)
{
    $entity  = new PurchaseOrder();
    $form = $this->createForm(new PurchaseOrderType(), $entity);
    $form->bind($request);
    if ($form->isValid()) {
        $em = $this->getDoctrine()->getManager();
        $em->persist($entity);
        $em->flush();
        return $this->redirect($this->generateUrl('purchaseorder_show', array('id' => $entity->getId())));
    }
    return array(
        'entity' => $entity,
        'form'   => $form->createView(),
    );
}
/**
 * Displays a form to create a new PurchaseOrder entity.
 *
 * @Route("/new", name="purchaseorder_new")
 * @Method("GET")
 * @Template()
 */
public function newAction()
{
    $entity = new PurchaseOrder();
    $form   = $this->createForm(new PurchaseOrderType(), $entity);
    $purchase = $this->get('cj.businessbundle.purchase');
    $purchase->newAction();
    return array(
        'entity' => $entity,
        'form'   => $form->createView(),
    );
}
/**
 * Finds and displays a PurchaseOrder entity.
 *
 * @Route("/{id}", name="purchaseorder_show")
 * @Method("GET")
 * @Template()
 */
public function showAction($id)
{
    $em = $this->getDoctrine()->getManager();
    $entity = $em->getRepository('CJBusinessBundle:PurchaseOrder')->find($id);
    if (!$entity) {
        throw $this->createNotFoundException('Unable to find PurchaseOrder entity.');
    }
    $deleteForm = $this->createDeleteForm($id);
    return array(
        'entity'      => $entity,
        'delete_form' => $deleteForm->createView(),
    );
}
/**
 * Displays a form to edit an existing PurchaseOrder entity.
 *
 * @Route("/{id}/edit", name="purchaseorder_edit")
 * @Method("GET")
 * @Template()
 */
public function editAction($id)
{
    $em = $this->getDoctrine()->getManager();
    $entity = $em->getRepository('CJBusinessBundle:PurchaseOrder')->find($id);
    if (!$entity) {
        throw $this->createNotFoundException('Unable to find PurchaseOrder entity.');
    }
    $editForm = $this->createForm(new PurchaseOrderType(), $entity);
    $deleteForm = $this->createDeleteForm($id);
    return array(
        'entity'      => $entity,
        'edit_form'   => $editForm->createView(),
        'delete_form' => $deleteForm->createView(),
    );
}
/**
 * Edits an existing PurchaseOrder entity.
 *
 * @Route("/{id}", name="purchaseorder_update")
 * @Method("PUT")
 * @Template("CJBusinessBundle:PurchaseOrder:edit.html.twig")
 */
public function updateAction(Request $request, $id)
{
    $em = $this->getDoctrine()->getManager();
    $entity = $em->getRepository('CJBusinessBundle:PurchaseOrder')->find($id);
    if (!$entity) {
        throw $this->createNotFoundException('Unable to find PurchaseOrder entity.');
    }
    $deleteForm = $this->createDeleteForm($id);
    $editForm = $this->createForm(new PurchaseOrderType(), $entity);
    $editForm->bind($request);
    if ($editForm->isValid()) {
        $em->persist($entity);
        $em->flush();
        return $this->redirect($this->generateUrl('purchaseorder_edit', array('id' => $id)));
    }
    return array(
        'entity'      => $entity,
        'edit_form'   => $editForm->createView(),
        'delete_form' => $deleteForm->createView(),
    );
}
/**
 * Deletes a PurchaseOrder entity.
 *
 * @Route("/{id}", name="purchaseorder_delete")
 * @Method("DELETE")
 */
public function deleteAction(Request $request, $id)
{
    $form = $this->createDeleteForm($id);
    $form->bind($request);
    if ($form->isValid()) {
        $em = $this->getDoctrine()->getManager();
        $entity = $em->getRepository('CJBusinessBundle:PurchaseOrder')->find($id);
        if (!$entity) {
            throw $this->createNotFoundException('Unable to find PurchaseOrder entity.');
        }
        $em->remove($entity);
        $em->flush();
    }
    return $this->redirect($this->generateUrl('purchaseorder'));
}
/**
 * Creates a form to delete a PurchaseOrder entity by id.
 *
 * @param mixed $id The entity id
 *
 * @return Symfony'Component'Form'Form The form
 */
private function createDeleteForm($id)
{
    return $this->createFormBuilder(array('id' => $id))
        ->add('id', 'hidden')
        ->getForm()
    ;
}
}

Serivces.yml

services:
   cj.businessbundle.purchase:
      class: CJ'BusinessBundle'Controller'PurchaseController

控制器内部访问方法[Not Purchase controller]

$purchase = $this->get('cj.businessbundle.purchase');
$purchase->newAction();
得到错误:

fatalerrorexcexception: Error:在/home/cj/public_html/Symfony/vendor/Symfony/Symfony/Symfony/src/Symfony/Bundle/FrameworkBundle/Controller/Controller.php第163行调用非对象的成员函数get()

新的Action不存在

我想我在定义服务时做错了什么

当你调用$this->get("your.service")时,你是在要求依赖注入容器加载该服务。你正在请求它加载你的一个控制器,它扩展了Symfony的控制器类,它扩展了ContainerAware。你得到的错误是因为加载的控制器很可能试图使用$this->container->get("request")访问像"请求"这样的服务,但$this->container没有设置。

ContainerAware有一个方法setContainer,当你的服务设置时,你可以通过使用services.yml中的calls:参数来运行它:

services:
   cj.businessbundle.purchase:
      class: CJ'BusinessBundle'Controller'PurchaseController
      calls:
        - [setContainer, [@service_container]]

Symfony2为加载的控制器(PurchaseOrderController)执行此操作,但如果您只是自己加载控制器类则不会。

从PurchaseController中提取newAction(或所需的逻辑)作为服务本身,而不是将整个控制器设置为服务,这将是更好的实践。这样,Purchase和PurchaseOrder控制器都可以调用该服务来创建一个新的Purchase(或newAction所做的任何事情),而不必每次都加载整个控制器。查看FOS用户包用户管理器以获得一个很好的服务示例或http://symfony.com/doc/2.1/book/service_container.html#what-is-a-service