Macbernie Macbernie - 3 months ago 10
PHP Question

Call to a member function addPaiementType() on null

I have 3 files:

The first one:

public function register(\Pimple\Container $app)
{
$app['manager.form'] = function() use ($app) {
return new Form($app);
};
}


Second:

class Form
{
private $form;

public function __construct(Application $app)
{
$this->form = $app['form.factory']->createBuilder(FormType::class);
}

public function addDuree()
{
$this->form->add('duree', ChoiceType::class, [
'choices' => [
'1' => '1',
'3' => '3',
'6' => '6',
'12' => '12'
],
'multiple' => false,
'expanded' => true,
'data' => 1
]);
}

public function addPaiementType()
{
$this->form->add('paiementType', ChoiceType::class, [
'choices' => [
'virement' => 'virement',
'cheque' => 'cheque',
'paypal' => 'paypal',
'paypal-cb' => 'paypal-cb'
],
'multiple' => false,
'expanded' => true,
'data' => 'virement'
]);
}

public function addTermsAccepted()
{
$this->form->add('termsAccepted', CheckboxType::class, [
'mapped' => false,
'constraints' => new Assert\IsTrue(),
]);
}

public function getForm()
{
return $this->form->getForm();
}
}


And the controller:

$form = $app['manager.form']->addDuree()->addPaiementType()->addTermsAccepted();


But Silex give me the error:

Call to a member function addPaiementType() on null


I do not understand why. For me this code structure is equivalent to:

$form = $app['form.factory']->createBuilder(FormType::class)
->add('duree', ChoiceType::class, [
'choices' => [
'1' => '1',
'3' => '3',
'6' => '6',
'12' => '12'
],
'multiple' => false,
'expanded' => true,
'data' => 1
])
->add('paiementType', ChoiceType::class, [
'choices' => [
'virement' => 'virement',
'cheque' => 'cheque',
'paypal' => 'paypal',
'paypal-cb' => 'paypal-cb'
],
'multiple' => false,
'expanded' => true,
'data' => 'virement'
])
->add('termsAccepted', CheckboxType::class, [
'mapped' => false,
'constraints' => new Assert\IsTrue(),
])
->getForm();


But it seems not... Don't know why.

Thanks for help

Answer

To use object call chaining, the methods have to return $this. You're not doing that. Your addDuree() has NO return at all, so it implicitly has a return null, which means that this line:

$form = $app['manager.form']->addDuree()->addPaiementType()->addTermsAccepted();

executes as if it was written

 $form = $app['manager.form']->null->addPaiementType()
                               ^^^^

Your should have

function addPaimentType() {
    ... stuff ...
    return $this;
}
Comments