duanbo5230 2015-02-24 11:19
浏览 54
已采纳

错误:在非对象上调用成员函数get()500内部服务器错误 - FatalErrorException(Symfony)

im fairly new to Mac and Symfony in general so sorry if im missing any basic knowledge

basically trying to create a form using a php class, here its below

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

?>

i then have my 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';
 }
 }

 ?>

and then on the main controller

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


}
?>

And the error i keep getting is

 Attempted to call method "createForm" on class "TeamRock\ApplicationBundle\Controllers\Calvin\Homepage".
500 Internal Server Error - UndefinedMethodException 

Any help is appreciated guys, as i said im pretty new to php and symfony and its a big learning curve so any helps or pointers are appreciated

ive been watching this guys videos just for reference Andrew Perkins Symfony Tutorials

thanks again for any help in advance!

  • 写回答

1条回答 默认 最新

  • dongming4994 2015-02-24 16:42
    关注

    How to use a controller as a service? The documentation is always a good place to start:http://symfony.com/doc/current/cookbook/controller/service.html

    In the case of this question, the controller use a createForm method which happens to be defined in:

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

    As you can see, the createForm method relies on the container object to access the form.factory object. How does the container get injected?

    namespace Symfony\Component\DependencyInjection;
    
    abstract class ContainerAware implements ContainerAwareInterface
    {
    protected $container;
    public function setContainer(ContainerInterface $container = null)
    {
        $this->container = $container;
    }
    

    So somewhere along the line we need to call $controller->setContainer. If we were using controllers in the normal fashion (i.e. not as services) then setContainer gets called in the Symfony\Component\HttpKernel\HttpKernel::handleRaw() method. But since we are defining the controller as a service then it is up to us to inject the container:

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

    So adding the setContainer call to your service definition should give you working code. Though adding createView directly to your response might not give you the desired results. It certainly won't give you html. But that is a different issue.

    The real question of course is why bother defining the controller as a service. In almost all cases, the answer is that you should not. It used to be recommended for third party bundles but not so much any more. If you look at the FOSUserBundle controllers you see quite a bit of duplicate code just because they blindly followed the controller as a service rule.

    There are times when it makes sense. I try to keep controllers as slim as possible and only inject the services that are actually needed. In this question, the only service the controller needs is the form factory so it should be the only one injected. And you should no longer extend the base controller 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']]
    

    I like to use setter injection instead of construct inject for these sorts of standard services. I save the construct for my own custom services. But you could certainly use arguments: ['@form.factory'] if you wanted.

    Finally though, if you are just learning the framework as well as PHP OOP then just follow the examples in the documentation. There is plenty to learn without going down these sorts of rabbit holes.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 HFSS 中的 H 场图与 MATLAB 中绘制的 B1 场 部分对应不上
  • ¥15 如何在scanpy上做差异基因和通路富集?
  • ¥20 关于#硬件工程#的问题,请各位专家解答!
  • ¥15 关于#matlab#的问题:期望的系统闭环传递函数为G(s)=wn^2/s^2+2¢wn+wn^2阻尼系数¢=0.707,使系统具有较小的超调量
  • ¥15 FLUENT如何实现在堆积颗粒的上表面加载高斯热源
  • ¥30 截图中的mathematics程序转换成matlab
  • ¥15 动力学代码报错,维度不匹配
  • ¥15 Power query添加列问题
  • ¥50 Kubernetes&Fission&Eleasticsearch
  • ¥15 報錯:Person is not mapped,如何解決?