仅在POST期间进行数组到字符串转换

时间:2015-07-26 16:14:46

标签: symfony

有相同标题的问题,但它们与POSTing无关。 如果我使用Symfony提交表单,我可以毫无问题地提交。问题是当我使用Angular使用我创建的POST方法提交表单时。它给了我一个例外“通知:数组到字符串转换”。

我知道它与我的ManyToMany Relation(所有者)有关。如果我不添加任何所有者它工作正常。问题是当我添加所有者时。

这是我的Stack Trace:

Stack Trace:

1. in vendor/symfony/symfony/src/Symfony/Bridge/Doctrine/Form/ChoiceList/ORMQueryBuilderLoader.php at line 106 


2. at ErrorHandler ->handleError ('8', 'Array to string conversion', '/Applications/MAMP/htdocs/uploader/vendor/symfony/symfony/src/Symfony/Bridge/Doctrine/Form/ChoiceList/ORMQueryBuilderLoader.php', '106', array('v' => array('id' => '2', 'firstName' => 'Albert', 'lastName' => 'Jankowski', 'username' => 'ajankowski', 'password' => '$2y$13$7lXTaq3w45j3P0HEln71T.ItLxxf8ZX28UkNFpYFPULyR2a7pLW1C', 'email' => 'ajankowski@myemail.com', 'enabled' => true, 'salt' => null, 'usernameCanonical' => 'ajankowski', 'availableRoles' => array('ROLE_USER', 'ROLE_ADMIN'), 'emailCanonical' => 'ajankowski@myemail.com', 'plainPassword' => null, 'lastLogin' => null, 'confirmationToken' => null, 'roles' => array('ROLE_USER'), 'accountNonExpired' => true, 'accountNonLocked' => true, 'credentialsNonExpired' => true, 'credentialsExpired' => false, 'expired' => false, 'locked' => false, 'superAdmin' => false, 'user' => false, 'passwordRequestedAt' => null, 'groups' => array(), 'groupNames' => array()))) 
in vendor/symfony/symfony/src/Symfony/Bridge/Doctrine/Form/ChoiceList/ORMQueryBuilderLoader.php at line 106


3. at ORMQueryBuilderLoader ->Symfony\Bridge\Doctrine\Form\ChoiceList\{closure} (array('id' => '2', 'firstName' => 'Albert', 'lastName' => 'Jankowski', 'username' => 'ajankowski', 'password' => '$2y$13$7lXTaq3w45j3P0HEln71T.ItLxxf8ZX28UkNFpYFPULyR2a7pLW1C', 'email' => 'ajankowski@myemail.com', 'enabled' => true, 'salt' => null, 'usernameCanonical' => 'ajankowski', 'availableRoles' => array('ROLE_USER', 'ROLE_ADMIN'), 'emailCanonical' => 'ajankowski@myemail.com', 'plainPassword' => null, 'lastLogin' => null, 'confirmationToken' => null, 'roles' => array('ROLE_USER'), 'accountNonExpired' => true, 'accountNonLocked' => true, 'credentialsNonExpired' => true, 'credentialsExpired' => false, 'expired' => false, 'locked' => false, 'superAdmin' => false, 'user' => false, 'passwordRequestedAt' => null, 'groups' => array(), 'groupNames' => array())) 

4. at array_filter (array(array('id' => '2', 'firstName' => 'Albert', 'lastName' => 'Jankowski', 'username' => 'ajankowski', 'password' => '$2y$13$7lXTaq3w45j3P0HEln71T.ItLxxf8ZX28UkNFpYFPULyR2a7pLW1C', 'email' => 'ajankowski@myemail.com', 'enabled' => true, 'salt' => null, 'usernameCanonical' => 'ajankowski', 'availableRoles' => array('ROLE_USER', 'ROLE_ADMIN'), 'emailCanonical' => 'ajankowski@myemail.com', 'plainPassword' => null, 'lastLogin' => null, 'confirmationToken' => null, 'roles' => array('ROLE_USER'), 'accountNonExpired' => true, 'accountNonLocked' => true, 'credentialsNonExpired' => true, 'credentialsExpired' => false, 'expired' => false, 'locked' => false, 'superAdmin' => false, 'user' => false, 'passwordRequestedAt' => null, 'groups' => array(), 'groupNames' => array())), object(Closure)) 
in vendor/symfony/symfony/src/Symfony/Bridge/Doctrine/Form/ChoiceList/ORMQueryBuilderLoader.php at line 107

我的实体:

/**
 * Company
 *
 * @ORM\Table()
 * @ORM\Entity(repositoryClass="AppBundle\Repository\CompanyRepository")
 */
class Company
{
  ......
  ......

  /**
   * @var User
   *
   * @ORM\ManyToMany(targetEntity="AppBundle\Entity\User")
   */
  private $owners;

  ......
  ......
}

我的控制器:

/**
 * @Route("", name="api_company_create")
 * @Method("POST")
 *
 * @param \Symfony\Component\HttpFoundation\Request $request
 *
 * @return Response $response
 */
public function createAction(Request $request)
{
  // Process the form.
  $company = new Company();
  $form = $this->createForm(new CompanyType(), $company);
  $this->processForm($request, $form, TRUE);

  if (!$form->isValid()) {
    $this->throwApiProblemValidationException($form);
  }

  $em = $this->getDoctrine()->getManager();
  $em->persist($company);
  $em->flush();

  $response = $this->createApiResponse($company, 201);

  $companyUrl = $this->generateUrl(
    'api_company_show',
    ['id' => $company->getId()] );

  $response->headers->set('Location', $companyUrl);

  return $response;
}

/**
 * Process the form.
 *
 * @param \Symfony\Component\HttpFoundation\Request $request
 * @param \Symfony\Component\Form\FormInterface $form
 * @param boolean $removeExtraFields
 * @param Company $currentCompany
 */
private function processForm(Request $request, FormInterface $form, $removeExtraFields = FALSE, $currentCompany = NULL)
{
  $data = json_decode($request->getContent(), true);

  $clearMissing = $request->getMethod() != 'PATCH';
  $form->submit($data, $clearMissing);
}



/**
 * Company
 *
 * @ORM\Table()
 * @ORM\Entity(repositoryClass="AppBundle\Repository\CompanyRepository")
 */
class Company
{
  ......
  ......

  /**
   * @var User
   *
   * @ORM\ManyToMany(targetEntity="AppBundle\Entity\User")
   */
  private $owners;

  ......
  ......
}

我尝试将__String()添加到我的公司实体,但这没有帮助。

  /**
   * Transform to string
   *
   * @return string
   */
  public function __toString()
  {
    return (string) $this->getOwners();
  }

1 个答案:

答案 0 :(得分:0)

我能够弄清楚这一点。这是因为Symfony(Doctrine)不希望整个对象回来。我在我的控制器中创建了一个函数来解决这个问题。

  /**
   * You may receive an entire object for a relation from your api but when
   * saving Doctrine only wants the ids.
   *
   * For Example your API returns:
   *   $data['owners'][0] = array('id' => 1, 'name' => 'Admin');
   *   $data['owners'][1] = array('id' => 2, 'name' => 'User');
   *
   * But it expects:
   *
   *   $data['owners'][0] = 1;
   *   $data['owners'][1] = 2;
   *
   *
   * @param array $data
   * @param string $name
   */
  private function convertRelationToDoctrineSafeArray(&$data, $name)
  {
    if (isset($data[$name]) && $data[$name]) {
      foreach ($data[$name] as $key => $field) {
        $fields[$key] = $field['id'];
      }
      unset($data[$name]);
      $data[$name] = $fields;
    }
  }