【问题标题】:Manipulating POST data to work with Symfony2 forms when used in a REST API在 REST API 中使用 POST 数据以使用 Symfony2 表单
【发布时间】:2012-02-16 01:24:00
【问题描述】:

背景:

我正在 symfony 上编写一个 RESTful API。我希望客户端能够使用内容类型 application/json 发布到 url,并发布控制器操作正在寻找的 json 表单对象。

我为此使用了一个非常基本的控制器设置。出于演示目的,我们假设我尝试验证一个简单的用户名密码组合。

public function loginAction( Request $request )
{
    $user = new ApiUser();
    $form = $this->createForm(new ApiUserType(), $user);
    if ( "POST" == $request->getMethod() ) {
        $form->bindRequest($request);
        if ( $form->isValid() ) {
            $em = $this->getDoctrine()->getEntityManager();
            $repo = $this->getDoctrine()->getRepository('ApiBundle:ApiUser');
            $userData = $repo->findOneByUsername($user->getUsername());
            if ( is_object($userData) ) {
                /** do stuff for authenticating **/
            }
            else{
                return new Response(json_encode(array('error'=>'no user by that username found')));
            }
        else{
            return new Response(json_encode(array('error'=>'invalid form')));
        }
    }
}

现在我遇到的问题是,我是否尝试过 var_dumping 这个直到奶牛回家,无论出于何种原因,symfony 都不想获取应用程序/json 内容体并使用该数据来填充表单数据。

表单名称:api_apiuser

字段:用户名、密码

处理此类任务的最佳方式是什么。只要我能得到这个工作,我愿意接受建议。感谢您抽出宝贵时间。

【问题讨论】:

    标签: php symfony


    【解决方案1】:

    您需要访问 RAW 请求正文,然后使用 json_decode。您可能需要将您的 bindRequest 方法更改为类似以下内容:

    public function bindRequest(Request $request) 
    {
           if($request->getFormat() == 'json') {
               $data = json_decode($request->getContent());
               return $this->bind($data);
            } else {
               // your standard logic for pulling data form a Request object
               return parent::bind($request);
            }
    }
    

    我还没有真正搞砸过 SF2,所以这更多是基于 API 的猜测,exp。使用 sf1.x 和我从框架上的演示中获得的东西。像bindJsonRequest 这样创建一个完全不同的方法可能会更好,这样事情会更整洁一些。

    【讨论】:

      【解决方案2】:

      我实际上找到了一种类似的方法来解决这个问题,在检查方法是否为 post 之后,在将请求绑定到表单之前,我这样做:

      if ( "POST" === $request->getMethod() ) {
          if (0 === strpos($request->headers->get('Content-Type'), 'application/json')){
              $data = json_decode($request->getContent(), true);
              $request->request->replace(is_array($data) ? $data : array());
          }
          $form->bindRequest($request);
          /** Rest of logic **/
      }
      

      【讨论】:

        【解决方案3】:

        是的,表单在绑定期间等待的是一个数组,其中包含与您的 ApiUser 属性相对应的键。

        所以如果你发送一个带有字符串的 POST 请求:

        { username: 'user', password: 'pass' }
        

        您必须使用 json_decode 将其转换为数组,例如:

        $data = json_decode($request->getContent()); // $request->request->get('json_param_name');
        

        然后你将这个数组绑定到使用$form->bind($data);的表单

        表单将根据数组的键(用户名、密码)更新您的 ApiUser 属性。

        如果您正在构建 RESTful json api,我建议您使用序列化器/转换器自动执行此过程,例如 https://github.com/schmittjoh/JMSSerializerBundle/blob/master/Resources/doc/index.rst

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2016-03-19
          • 2019-05-31
          • 2020-05-10
          • 1970-01-01
          • 1970-01-01
          • 2017-03-29
          • 1970-01-01
          相关资源
          最近更新 更多