Error: Call to a member function get() on a non-object 500 Internal Server Error - FatalErrorException (Symfony)

Error: Call to a member function get() on a non-object 500 Internal Server Error - FatalErrorException (Symfony)

我是 Mac 和 Symfony 的新手,如果我缺少任何基本知识,我深表歉意

基本上是尝试使用 php class 创建表单,下面是

<?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;
}
}

?>

然后我有我的class

 <?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

再次感谢您的提前帮助!

如何使用控制器作为服务?文档始终是一个很好的起点: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->setContainer。如果我们以正常方式使用控制器(即不作为服务),那么 setContainer 会在 Symfony\Component\HttpKernel\HttpKernel::handleRaw() 方法中被调用。但是由于我们将控制器定义为服务,因此我们需要注入容器:

# services.yml
homepage__controller:
    class: Whatever\Homepage
    calls:
         - [setContainer, ['@service_container']]

因此,将 setContainer 调用添加到您的服务定义应该会为您提供工作代码。尽管将 createView 直接添加到您的响应中可能不会为您提供所需的结果。肯定不会给你html。但那是另一回事了。

真正的问题当然是为什么要费心将控制器定义为服务。在几乎所有情况下,答案都是不应该。它曾经被推荐用于第三方捆绑包,但现在不再那么多了。如果您查看 FOSUserBundle 控制器,您会看到相当多的重复代码,只是因为它们盲目地遵循控制器作为服务规则。

有时候它是有道理的。我尽量让控制器保持苗条,只注入实际需要的服务。在这个问题中,控制器唯一需要的服务是表单工厂,因此它应该是唯一注入的服务。而且你不应该再扩展基本控制器 class.

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,那么只需按照文档中的示例进行操作即可。有很多东西可以学习,而无需陷入这些兔子洞。