2016-08-25 3 views
0

Defaultcontrollerの中にshowUsersAction()メソッドがあります。これは、リストからユーザーを選択できるようにする必要があります。submitユーザの項目が表示されているルート/showItems/{userId}にリダイレクトされます。エラー:SymfonyコンポーネントフォームのChoiceTypeを使用して非オブジェクトのメンバー関数を呼び出す

私はリンクして簡単ですが、私はChoiceTypeを利用したいことをやることが可能であろうことを知っている:

まず、私は最小限の変更でSymfony documentationからChoiceTypeの例をコピーします

/** 
* @Route("/showUsers", name="showUsers") 
*/ 
public function showUsersAction(){ 
    $users = $this->getDoctrine()->getManager()->getRepository('AppBundle:User')->findAll(); 

    $form = $this->createFormBuilder() 
     ->setMethod('POST') 
     ->add('user', ChoiceType::class, [ 
      'choices' => $users, 
      'choice_label' => function($user) { 
       /** @var User $user */ 
       return strtoupper($user->getUsername());//here is the problem 
      }, 
      'choice_attr' => function($user) { 
       return ['class' => 'user_'.strtolower($user->getUsername())]; 
      }, 
     ]) 
     ->getForm(); 

    return $this->render('default/showUsers.html.twig', 
     array('users' => $users, 'form' => $form->createView())); 
} 

$usersは、クラスUserのオブジェクトを持つ配列を返します。私はブラウザにルートを実行すると、私は次のようなエラーメッセージが出ます:?

Error: Call to a member function getUsername() on a non-object 
in src\AppBundle\Controller\DefaultController.php at line 50 

ライン50を問題であり、どのように私は解決することができますどのようなコメント行return strtoupper($user->getUsername());

  1. ですか
  2. また、送信ボタンをクリックして同じルートに送信した後、選択したユーザーを取得するにはどうすればよいですか?

EDIT:$user symfonyのドキュメントに関連するべきではない非オブジェクトであるためもちろん (ための可能な重複のは)私は、この方法getUsername()を呼び出すことはできませんことを知っています。だから私の質問は、エラーが同じである他の100の問題とはまったく関係のないSymfonyの特別な解決策に関するものです。

+0

[参考 - PHPでこのエラーは何を意味しますか?](http:// stackove rflow.com/questions/12769982/reference-what-does-this-error-mean-in-php) –

+0

あなたの$コールバック関数の中に$ userが含まれているかどうか調べてみましたか? $ usersが実際にオブジェクトの配列だった場合、あなたのコードはドキュメントに従って動作するはずです – georaldc

+0

コールバック関数の中で定義されていなければ '$ user'と思います。 if文を追加すると、 'if($ user){...}'というエラーが2.コールバック関数に現れます。しかし、なぜ?それは、私が「選択肢」をどのように追加するかで、何かをするのか? – goulashsoup

答えて

0

私もentityタイプフィールドを設定するとのトラブルがあったので、私は、全体のaction機能のために私の解決策を投稿することを決定し、ここでtwigファイル:

action方法:

/** 
* @Route("/showUsers", name="showUsers") 
*/ 
public function showUsersAction(Request $request){ 
    // gets array of all users in the database 
    $users = $this->getDoctrine()->getManager()->getRepository('AppBundle:User')->findAll(); 

    $form = $this->createFormBuilder() 
    ->setMethod('POST') 
    ->add('users', EntityType::class, array(
     'class' => 'AppBundle:User', 
     'choices' => $users, 

     // This combination of 'expanded' and 'multiple' implements radio buttons 
     'expanded' => true, 
     'multiple' => false,  
     'choice_label' => function ($user) { 
       return $user->__toString(); 
     } 
    )) 

    // Adds a submit button to the form. 
    // The 'attr' option adds a class to the html rendered form 
    ->add('selected', SubmitType::class, array('label' => 'Show User Items', 'attr' => array('class' => 'button'))) 
    ->getForm(); 

    $form->handleRequest($request); 

    if ($form->isSubmitted() && $form->isValid()) { 
     // gets the selected user 
     $selectedUser = $form["users"]->getData(); 

     // redirects to route 'showItems' with the id of the selected user 
     return $this->redirectToRoute('showItems', array('userId' => $selectedUser->getId())); 
    } 

    // renders 'default/showUsers.html.twig' with the form as an argument 
    return $this->render('default/showUsers.html.twig', array('form' => $form->createView())); 
} 

twigファイル:

{# 
    // app/Resources/views/default/showUsers.html.twig 

    Description: 
    twig file that implements a form in which one of all users can get 
    selected via radio button to show the items of the user after a click 
    on the submit button. 

    @author goulashsoup 

#} 
{% extends 'base.html.twig' %} 
{% block title %}Users{% endblock %} 
{% block body %} 
    <div class="users"> 
     {{ form_start(form) }} 
      {% for user in form.users %} 
       {{ form_widget(user) }} 
       {{ form_label(user) }} 
       <br> 
      {% endfor %} 
      <br> 
     {{ form_end(form) }} 
    </div> 
{% endblock %} 
2

代わりにentityタイプを使用してください。ここにdocumentationへのリンクがあります。これは全く同じ機能を持つchoiceタイプの子タイプであり、すべてのオプションもエンティティオブジェクトを返します。

関連する問題