Error: Call to a member function on a non-object using ChoiceType of Symfony component form
Error: Call to a member function on a non-object using ChoiceType of Symfony component form
我在 Defaultcontroller
中有 showUsersAction()
-方法,它应该呈现一个表单,应该可以从列表中 select 用户,按 submit
-按钮,然后重定向到显示用户项目的路由 /showItems/{userId}
。
我知道使用 link 可以轻松做到这一点,但我想利用 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
给出了一个包含 class 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());
- 问题是什么,我该如何解决?
- 在我通过提交按钮提交到同一路径后,如何获得 selected 用户?
编辑:(因为可能重复)
我当然知道getUsername()
这个方法是不能调用的,因为$user
是一个非对象,应该和Symfony文档没有关系。所以我的问题与 Symfony 的特殊解决方案有关,它与 100 个错误相同的其他问题完全无关。
请改用 entity
类型。这里有一个link到documentation。它是 choice
类型的子类型,具有完全相同的功能,而且每个选项 returns 都是一个实体对象。
因为我在设置 entity
类型字段时也遇到了麻烦,所以我决定 post 我的整个 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 %}
我在 Defaultcontroller
中有 showUsersAction()
-方法,它应该呈现一个表单,应该可以从列表中 select 用户,按 submit
-按钮,然后重定向到显示用户项目的路由 /showItems/{userId}
。
我知道使用 link 可以轻松做到这一点,但我想利用 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
给出了一个包含 class 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());
- 问题是什么,我该如何解决?
- 在我通过提交按钮提交到同一路径后,如何获得 selected 用户?
编辑:(因为可能重复)
我当然知道getUsername()
这个方法是不能调用的,因为$user
是一个非对象,应该和Symfony文档没有关系。所以我的问题与 Symfony 的特殊解决方案有关,它与 100 个错误相同的其他问题完全无关。
请改用 entity
类型。这里有一个link到documentation。它是 choice
类型的子类型,具有完全相同的功能,而且每个选项 returns 都是一个实体对象。
因为我在设置 entity
类型字段时也遇到了麻烦,所以我决定 post 我的整个 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 %}