4

我正在尝试通过从我的 sencha touch 2 前端调用 put 方法来更新我的 mysql 数据库中的记录。我正在调用这个 url /api/users/id 但我不断收到 Symfony 错误:

No route found for "PUT /api/users/1

这就是我的 routing.yml 文件中的内容

users:
    resource: "Acme\MainBundle\Controller\UsersController"
    prefix:   /api
    type:     rest

另外,我的 User* s *Controller中有 putUsersAction 设置

public function putUsersAction($id, Request $request)
{
    $values['birthdate'] = $request->get('birthdate');
    $values['clubid'] = $request->get('clubid');

    $em = $this->getDoctrine()->getEntityManager();

    $user = $this->getDoctrine()
        ->getRepository('AcmeMainBundle:User')
        ->find($id);

    $club = $this->getDoctrine()
        ->getRepository('AcmeMainBundle:Club')
        ->find($values['clubid']);

    $user->setBirthdate($values['birthdate']);
    $user->addClub($club);

    $em->flush();

    $view = View::create()
        ->setStatusCode(200)
        ->setData($user);

    return $this->get('fos_rest.view_handler')->handle($view);
}

为什么 Symfony 告诉我没有 PUT /api/users/id 路由?

编辑 1:路由器:调试输出

[router] Current routes
Name                     Method Pattern
_wdt                     ANY    /_wdt/{token}
_profiler_search         ANY    /_profiler/search
_profiler_purge          ANY    /_profiler/purge
_profiler_info           ANY    /_profiler/info/{about}
_profiler_import         ANY    /_profiler/import
_profiler_export         ANY    /_profiler/export/{token}.txt
_profiler_phpinfo        ANY    /_profiler/phpinfo
_profiler_search_results ANY    /_profiler/{token}/search/results
_profiler                ANY    /_profiler/{token}
_profiler_redirect       ANY    /_profiler/
_configurator_home       ANY    /_configurator/
_configurator_step       ANY    /_configurator/step/{index}
_configurator_final      ANY    /_configurator/final
get_users                GET    /api/users.{_format}
post_users               POST   /api/users.{_format}
get_clubs                GET    /api/clubs.{_format}
post_clubs               POST   /api/clubs.{_format}
put_users                PUT    /api/users.{_format}
4

2 回答 2

7

首先,您应该调试路由并查看路由是否正确注册。您发布的路由被剪断缺乏正确的意图。它应该是:

user:
    resource: "Acme\MainBundle\Controller\UserController"
    prefix:   /api
    type:     rest

之后,您可以使用控制台命令调试路由:

php app/console router:debug

此外,您可以使用 grep (Unix) 或 findstr (Windows) 在输出中搜索您的路线:

php app/console router:debug | grep /api

或者

php app/console router:debug | findstr /api

接下来确保 FOSRestBundle 的自动路由按预期工作,将控制器命名为 User* s *Controller 和文件 User* s *Controller.php。

请参阅:FOSRestBundle 文档

请注意,您忘记在刷新之前调用persist($user),并且您不能在您的用户实体上调用flush,而是在您的EntityManager 上调用。请参阅下面的示例。

您可以通过使用 DependencyInjection 、 symfony2 ParamConverter隐式资源名称定义和FOSRestBundle提供的@View Annotation 来大大精简您的控制器。

然后,您的控制器将读取如下内容:

<?php

namespace Acme\MainBundle\Controller;

use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Request;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\ParamConverter;
use JMS\DiExtraBundle\Annotation as DI;
use Acme\MainBundle\Entity\User;
use FOS\RestBundle\Controller\Annotations\View;

/**
 * @DI\Service
 */
class UserController
{

    /** @DI\Inject("doctrine.orm.entity_manager") */
    private $em;

    // ...

    /**
     * @View()
     */
    public function putAction(User $user, Request $request)
    {

        $club = $this->em
            ->getRepository('AcmeMainBundle:Club')
            ->findOneById($request->get('clubid'));

        $user
            ->setBirthdate($request->get('birthdate')
            ->addClub($club);

        // you should add some validation here 

        $this->em->persist($user);
        $this->em->flush();

        return $user;
   }

   // ...
}

说明:

我使用了 JMSDiExtraBundle 的注解。您需要此捆绑包才能使它们工作。

否则,您应该将控制器声明为服务并在服务容器中手动注入 EntityManager(例如在您的包的 Resources/config/services.xml 中)。

使用 @DI\Service 注释将您的控制器声明为服务。

在此处注入您的 EntityManager,以便能够使用带有 @DI\Inject 注释的 $this->em 在整个类中访问它。

使用 FOSRest 的 @View 注释。如果您的应用程序中有 SensioFrameworkExtraBundle,请不要忘记在使用之前设置 sensio_framework_extra.view: { annotations: false }。

确保你有 return $this; 在您的用户实体的 setBirthdate(...) 和 addClub(...) 函数的末尾。

请注意我在示例中使用了 [JMSDiExtraBundle 的属性注入][3]。必须安装捆绑包才能使用。

您可以使用 NoxLogicMultiParamBundle 进一步精简控制器。

我不能发布超过 2 个链接,因为我是新来的……

  • 请在 google 上查找以下资源:
  • NoxLogicMultiParamBundle
  • FOSRestBundle 文档
  • JMSDiExtraBundle 文档
于 2012-11-17T23:36:32.370 回答
0
user:
    pattern:   /api/user/{id}
    defaults:  { _controller: AcmeMainBundle:User:putUsers, id: 1 }

或者您可以使用 FQCN:

defaults:  { _controller: Acme\MainBundle\Controller\UserController::putUsersAction, id: 1 }

并且只匹配 PUT 请求使用下面的代码,虽然有些浏览器不支持 PUT 和 DELETE 看到这个链接

user:
    pattern:   /api/user/{id}
    defaults:  { _controller: Acme\MainBundle\Controller\UserController::putUsers, id: 1 }
    requirements:
        _method:  PUT

...当然要查看您的所有路线,请从您的项目文件夹中运行它:

php app/console router:debug
于 2012-11-17T22:28:36.943 回答