2017-01-25 7 views
0

私はSymfonyを新しく導入しましたが、一般的にはPHP Web開発ではありません。それは、私が「動的な」フォームをうまく提出するのが非常に難しいと言いました。symfony 3 spl_object_hashは、パラメータ1がオブジェクトであることを期待しています。フォームを提出するときに整数を指定します。

詳細については、 http://symfony.com/doc/current/form/dynamic_form_modification.html#form-events-submitted-dataに従っています。

Profileエンティティは、CountryおよびAreaエンティティとManyToOne関係にあります。 AreaのManyToOneの関係はCountryです。

Countryの値に応じて、Areaエンティティの選択要素が動的に取り込まれます。これは問題なくOKです。私がフォームを提出すると、私は次のエラーを受け取ります:

Warning: spl_object_hash() expects parameter 1 to be object, integer given 500 Internal Server Error - ContextErrorException

スタックトレースを見ると、これは私のAreaエンティティ選択配列を平坦化する方法に起因するようです。

何かすべての助けがありがたいです - 私はこれまでこれを見て2日を過ごしました。

以下にいくつかのコードの詳細があります。それ以上の情報があれば、私に聞いてください!

おかげ

T2T


は私のProfileTypeクラスはAbstractTypeを拡張し、フォームを構築し、私のbuildFormルーチンが含まれています。

// Location Country & Area 
    // Start: Dynamic form stuff 
    // http://symfony.com/doc/current/form/dynamic_form_modification.html#form-events-submitted-data 
    $builder 
     ->add('locationCountry', EntityType::class, [ 
      'class'  => 'AppBundle:Country', 
      'placeholder' => '', 
     ]); 

    $formModifier = function (FormInterface $form, Country $country = null) { 

     $arChoices = array(); 
     if (!is_null($country)) { 
      $arChoices = $this->em->getRepository('AppBundle:Area')->findByCountry($country); 
     } 

     $areas = null === $country ? array() : $arChoices; 
     $form->add('locationArea', EntityType::class, [ 
      'class'  => 'AppBundle:Area', 
      'placeholder' => '', 
      'choices'  => $areas 
     ]); 
    }; 

    $builder->addEventListener(
     FormEvents::PRE_SET_DATA, 
     function (FormEvent $event) use ($formModifier) { 
      // this would be your entity, i.e. Profile 
      $data = $event->getData(); 
      $formModifier($event->getForm(), $data->getLocationCountry()); 
     } 
    ); 

    $builder->get('locationCountry')->addEventListener(
     FormEvents::POST_SUBMIT, 
     function (FormEvent $event) use ($formModifier) { 
      // It's important here to fetch $event->getForm()->getData(), as 
      // $event->getData() will get you the client data (that is, the ID) 
      $country = $event->getForm()->getData(); 

      // since we've added the listener to the child, we'll have to pass on 
      // the parent to the callback functions! 
      $formModifier($event->getForm()->getParent(), $country); 
     } 
    ); 
    // End: Dynamic form stuff 

Country次のように定義されます:私は、次のコードを持ってProfileTypebuildForm以内

namespace AppBundle\Entity; 

use Doctrine\ORM\Mapping as ORM; 

/** 
* Area 
* 
* @ORM\Table(name="Area") 
* @ORM\Entity(repositoryClass="AppBundle\Repository\AreaRepository") 
*/ 
class Area 
{ 
    /** 
    * @var int 
    * 
    * @ORM\Column(name="id", type="integer") 
    * @ORM\Id 
    * @ORM\GeneratedValue(strategy="AUTO") 
    */ 
    private $id; 

    /** 
    * @ORM\ManyToOne(targetEntity="AppBundle\Entity\Country") 
    */ 
    private $country; 

    /** 
    * @var string 
    * 
    * @ORM\Column(name="name", type="string", length=255) 
    */ 
    private $name; 

    /** 
    * Get id 
    * 
    * @return int 
    */ 
    public function getId() 
    { 
     return $this->id; 
    } 

    /** 
    * Set name 
    * 
    * @param string $name 
    * 
    * @return Area 
    */ 
    public function setName($name) 
    { 
     $this->name = $name; 

     return $this; 
    } 

    /** 
    * Get name 
    * 
    * @return string 
    */ 
    public function getName() 
    { 
     return $this->name; 
    } 

    public function __toString() { 
     return $this->name; 
    } 

    /** 
    * Set country 
    * 
    * @param \AppBundle\Entity\Country $country 
    * 
    * @return Area 
    */ 
    public function setCountry(\AppBundle\Entity\Country $country = null) 
    { 
     $this->country = $country; 

     return $this; 
    } 

    /** 
    * Get country 
    * 
    * @return \AppBundle\Entity\Country 
    */ 
    public function getCountry() 
    { 
     return $this->country; 
    } 

} 

そしてProfileの関連部分:

namespace AppBundle\Entity; 

use Doctrine\ORM\Mapping as ORM; 

/** 
* Country 
* 
* @ORM\Table(name="Country") 
* @ORM\Entity(repositoryClass="AppBundle\Repository\CountryRepository") 
*/ 
class Country 
{ 
    /** 
    * @var int 
    * 
    * @ORM\Column(name="id", type="integer") 
    * @ORM\Id 
    * @ORM\GeneratedValue(strategy="AUTO") 
    */ 
    private $id; 

    /** 
    * @var string 
    * 
    * @ORM\Column(name="name", type="string", length=100, unique=true) 
    */ 
    private $name; 

    /** 
    * @var bool 
    * 
    * @ORM\Column(name="visible", type="boolean") 
    */ 
    private $visible; 


    /** 
    * Get id 
    * 
    * @return int 
    */ 
    public function getId() 
    { 
     return $this->id; 
    } 

    /** 
    * Set name 
    * 
    * @param string $name 
    * 
    * @return Country 
    */ 
    public function setName($name) 
    { 
     $this->name = $name; 

     return $this; 
    } 

    /** 
    * Get name 
    * 
    * @return string 
    */ 
    public function getName() 
    { 
     return $this->name; 
    } 

    /** 
    * Set visible 
    * 
    * @param boolean $visible 
    * 
    * @return Country 
    */ 
    public function setVisible($visible) 
    { 
     $this->visible = $visible; 

     return $this; 
    } 

    /** 
    * Get visible 
    * 
    * @return bool 
    */ 
    public function getVisible() 
    { 
     return $this->visible; 
    } 

    public function __toString() { 
     return $this->getName(); 
    } 
} 

Areaは以下のように定義されます定義しているD:

/** 
* @ORM\ManyToOne(targetEntity="AppBundle\Entity\Country") 
*/ 
private $locationCountry; 

/** 
* @ORM\ManyToOne(targetEntity="AppBundle\Entity\Area") 
*/ 
private $locationArea; 

/** 
* Set locationArea 
* 
* @param \AppBundle\Entity\Area $locationArea 
* 
* @return Profile 
*/ 
public function setLocationArea(\AppBundle\Entity\Area $locationArea = null) 
{ 
    $this->locationArea = $locationArea; 

    return $this; 
} 

/** 
* Get locationArea 
* 
* @return \AppBundle\Entity\Area 
*/ 
public function getLocationArea() 
{ 
    return $this->locationArea; 
} 

/** 
* Set locationCountry 
* 
* @param \AppBundle\Entity\Country $locationCountry 
* 
* @return Profile 
*/ 
public function setLocationCountry(\AppBundle\Entity\Country $locationCountry = null) 
{ 
    $this->locationCountry = $locationCountry; 

    return $this; 
} 

/** 
* Get locationCountry 
* 
* @return \AppBundle\Entity\Country 
*/ 
public function getLocationCountry() 
{ 
    return $this->locationCountry; 
} 

は最後に、私のAreaRepositoryに私は、次があります。

namespace AppBundle\Repository; 

use AppBundle\Entity\Area; 

/** 
* AreaRepository 
* 
* This class was generated by the Doctrine ORM. Add your own custom 
* repository methods below. 
*/ 
class AreaRepository extends \Doctrine\ORM\EntityRepository 
{ 
    /** 
    * @param $oCountry 
    * @return array 
    */ 
    public function findByCountry($oCountry) { 

     if (is_null($oCountry)) { 
      return array(); 
     } 

     $oRepo = $this->getEntityManager()->getRepository('AppBundle:Area'); 
     $oQB = $oRepo->createQueryBuilder('a'); 
     $oQuery = $oQB->where('a.country = :countryId') 
      ->setParameter('countryId', $oCountry) 
      ->getQuery(); 

     $arResult = $oQuery->getArrayResult(); 

     return $arResult; 
    } 
} 

答えて

0

オブジェクトのIDが永続化のための代わりにオブジェクト自体渡されているため、このエラーを取得しています。ご自身のコメントで

ルック:

$event->getData() will get you the client data (that is, the ID)だから、あなたの$formModifier関数にオブジェクトのidを渡しています。

そして、あなたはあなたがfindByCountryに取得したIDを渡すようなものがこのラインで

$arChoices = $this->em->getRepository('AppBundle:Area')->findByCountry($country);

に失敗。

ボトムライン:あなたは国のオブジェクトを渡すことになっています、それはidだけではありません。

+0

Doh !!ありがとう、この問題を修正したようです!感謝の意をもって答えを受け入れましょう! t2t – tip2tail

+1

あなたは大歓迎です。 – Mawcel

関連する問題