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.

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

报告相同问题?

悬赏问题

  • ¥50 求解vmware的网络模式问题
  • ¥24 EFS加密后,在同一台电脑解密出错,证书界面找不到对应指纹的证书,未备份证书,求在原电脑解密的方法,可行即采纳
  • ¥15 springboot 3.0 实现Security 6.x版本集成
  • ¥15 PHP-8.1 镜像无法用dockerfile里的CMD命令启动 只能进入容器启动,如何解决?(操作系统-ubuntu)
  • ¥30 请帮我解决一下下面六个代码
  • ¥15 关于资源监视工具的e-care有知道的嘛
  • ¥35 MIMO天线稀疏阵列排布问题
  • ¥60 用visual studio编写程序,利用间接平差求解水准网
  • ¥15 Llama如何调用shell或者Python
  • ¥20 谁能帮我挨个解读这个php语言编的代码什么意思?