对于Mac和Symfony来说,我是相当新的,如果我缺少任何基本知识,那就很抱歉
基本上尝试使用php类创建表单,这里是
<?php
namespace TeamRock\ApplicationBundle\entity;
class Person{
protected $email;
protected $fullname;
public function getEmail(){
return $this->$email;
}
public function setEmail($email){
return $this->$email;
}
public function getFullname(){
return $this ->$fullname;
}
public function setFullname($fullname){
return $this -> $fullname;
}
}
?>
然后我有我的班级
<?php
namespace TeamRock\ApplicationBundle\form;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
class personType extends AbstractType{
public function buildForm(FormBuilderInterface $builder, array $options){
$builder->add ('email','email')->add ('name','text')->add('submit','submit');
}
public function getName(){
return 'person';
}
}
?>
然后在主控制器上
<?php
namespace TeamRock\ApplicationBundle\Controllers\Calvin;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use TeamRock\ApplicationBundle\entity\Person;
use TeamRock\ApplicationBundle\form\PersonType;
class Homepage
{
public function __invoke(Request $request)
{
$person = new person();
$form = $this->createForm(new PersonType(), $person);
return new Response("Hello, world!", Response::HTTP_OK, array('form'=>$form->createView()));
}
}
?>
我不断得到的错误是
Attempted to call method "createForm" on class "TeamRock\ApplicationBundle\Controllers\Calvin\Homepage".
500 Internal Server Error - UndefinedMethodException
任何帮助都是值得赞赏的人,正如我所说,我对PHP和symfony很新,它的学习曲线很大,所以任何帮助或指针都值得赞赏
我一直在关注这些家伙的视频,仅供参考Andrew Perkins Symfony Tutorials
再次感谢您的任何帮助!
答案 0 :(得分:2)
如何将控制器用作服务?文档始终是一个好的开始:http://symfony.com/doc/current/cookbook/controller/service.html
对于这个问题,控制器使用createForm方法,该方法恰好在:
中定义namespace Symfony\Bundle\FrameworkBundle\Controller;
use Symfony\Component\DependencyInjection\ContainerAware;
class Controller extends ContainerAware
{
public function createForm($type, $data = null, array $options = array())
{
return $this->container->get('form.factory')->create($type, $data, $options);
}
如您所见,createForm方法依赖于容器对象来访问form.factory对象。容器是如何注入的?
namespace Symfony\Component\DependencyInjection;
abstract class ContainerAware implements ContainerAwareInterface
{
protected $container;
public function setContainer(ContainerInterface $container = null)
{
$this->container = $container;
}
因此,我们需要调用$ controller-&gt; setContainer。如果我们以正常方式使用控制器(即不作为服务),则在Symfony \ Component \ HttpKernel \ HttpKernel :: handleRaw()方法中调用setContainer。但由于我们将控制器定义为服务,因此我们需要注入容器:
# services.yml
homepage__controller:
class: Whatever\Homepage
calls:
- [setContainer, ['@service_container']]
因此,将setContainer调用添加到服务定义应该可以为您提供工作代码。虽然直接在您的响应中添加createView可能无法获得所需的结果。它肯定不会给你HTML。但这是一个不同的问题。
当然,真正的问题是为什么要将控制器定义为服务。几乎在所有情况下,答案都是你不应该。它曾经被推荐用于第三方捆绑包,但不再那么多了。如果您查看FOSUserBundle控制器,您会看到相当多的重复代码,因为它们盲目地将控制器作为服务规则。
有时候它是有道理的。我尽量让控制器保持苗条,只注入实际需要的服务。在这个问题中,控制器需要的唯一服务是表单工厂,因此它应该是唯一注入的服务。而且你不应该扩展基本控制器类。
class HomepageController
{
private $formFactory;
public function setFormFactory($formFactory)
{
$this->formFactory = $formFactory;
}
public function __invoke(Request $request)
{
$person = new Person();
$form = $this->formFactory->create(new PersonType(), $person);
return new Response("Hello, world!", Response::HTTP_OK, array('form'=>$form->createView()));
}
}
services.yml
my__controller:
class: Whatever\HomepageController
calls:
- [setFormFactory, ['@form.factory']]
我喜欢使用setter注入而不是构造注入这些类型的标准服务。我为自己的自定义服务保存了构造。但是如果你愿意,你当然可以使用参数:['@ form.factory']。
最后,如果您只是学习框架以及PHP OOP,那么只需按照文档中的示例进行操作即可。如果没有这种类型的兔子洞,就有很多值得学习的东西。