When trying to set up a route for my rest api, when I visit my "/places" route I get a FatalThrowableError: "Call to a member function has() on null" in vendor\symfony\symfony\src\Symfony\Bundle\FrameworkBundle\Controller\ControllerTrait.php (line 356)
The problem only happens when I switch my routes from annotation to rest.
This doesn't work:
places:
type: rest
resource: AppBundle\Controller\PlaceController
This works:
places:
type: annotation
resource: AppBundle\Controller\PlaceController
The method is almost empty, only a call to getDoctrine:
/**
* @Get("/places")
*/
public function getPlacesAction(Request $request)
{
dump($this->container);
$this->getDoctrine();
return new JsonResponse($formatted);
}
And the container is null. I checked and the setContainer method is never called on my Controller and I can't find why.
The same thing works with identical configuration with Symfony 3.2.9, but not with Symfony 3.3.
Are you able to set up a small example project that makes it possible to reproduce your issue?
I have the same problem with Symfony 3.3.2. $this->container is null. So I get:
"Error: Call to a member function has() on null" when I invoke $this->getDoctrine() in controller.
Maybe related to symfony/symfony#23200?
Do you make use of the new feature that makes it possible to easily register controllers as services?
Yes it might be related.
I've tried this solution for my controller(service.yml) as was mentioned in symfony/symfony#23200 thread:
calls:
- [setContainer, ["@service_container"]]
and it works. But it's obvious that something wrong with auto injecting container in controller.
Do you use JMSDiExtraBundle?
I don't. Here is my composer.json deps:
{
"name": "root/api",
"license": "proprietary",
"type": "project",
"autoload": {
"psr-4": {
"": "src/"
},
"classmap": [
"app/AppKernel.php",
"app/AppCache.php"
]
},
"autoload-dev": {
"psr-4": {
"Tests\\": "tests/"
},
"files": [
"vendor/symfony/symfony/src/Symfony/Component/VarDumper/Resources/functions/dump.php"
]
},
"require": {
"php": ">=5.5.9",
"doctrine/doctrine-bundle": "^1.6",
"doctrine/doctrine-migrations-bundle": "^1.2",
"doctrine/orm": "^2.5",
"friendsofsymfony/user-bundle": "~2.0",
"incenteev/composer-parameter-handler": "^2.0",
"lexik/jwt-authentication-bundle": "^2.4",
"sensio/distribution-bundle": "^5.0.19",
"sensio/framework-extra-bundle": "^3.0.2",
"symfony/monolog-bundle": "^3.1.0",
"symfony/polyfill-apcu": "^1.0",
"symfony/swiftmailer-bundle": "^2.3.10",
"symfony/symfony": "3.3.*",
"twig/twig": "^1.0||^2.0",
"nelmio/cors-bundle": "^1.4",
"nelmio/api-doc-bundle": "^2.11",
"friendsofsymfony/rest-bundle": "^2.1",
"jms/serializer-bundle": "^1.1"
},
"require-dev": {
"sensio/generator-bundle": "^3.0",
"symfony/phpunit-bridge": "^3.0"
},
"scripts": {
"symfony-scripts": [
"Incenteev\\ParameterHandler\\ScriptHandler::buildParameters",
"Sensio\\Bundle\\DistributionBundle\\Composer\\ScriptHandler::buildBootstrap",
"Sensio\\Bundle\\DistributionBundle\\Composer\\ScriptHandler::clearCache",
"Sensio\\Bundle\\DistributionBundle\\Composer\\ScriptHandler::installAssets",
"Sensio\\Bundle\\DistributionBundle\\Composer\\ScriptHandler::installRequirementsFile",
"Sensio\\Bundle\\DistributionBundle\\Composer\\ScriptHandler::prepareDeploymentTarget"
],
"post-install-cmd": [
"@symfony-scripts"
],
"post-update-cmd": [
"@symfony-scripts"
]
},
"config": {
"sort-packages": true
},
"extra": {
"symfony-app-dir": "app",
"symfony-bin-dir": "bin",
"symfony-var-dir": "var",
"symfony-web-dir": "web",
"symfony-tests-dir": "tests",
"symfony-assets-install": "relative",
"incenteev-parameters": {
"file": "app/config/parameters.yml"
},
"branch-alias": null
}
}
Do you register your controllers as services? If yes, what does your config look like? Can you also show the code of your controller?
This is the controller I stuck with:
namespace AppBundle\Controller;
use FOS\RestBundle\Controller\Annotations\RouteResource;
use FOS\RestBundle\Controller\FOSRestController;
use FOS\RestBundle\Routing\ClassResourceInterface;
/**
* Class UserController
* @package AppBundle\Controller
*
* @RouteResource("user")
*/
class UserController extends FOSRestController implements ClassResourceInterface
{
public function getAction($id) {
var_dump($this->container); // display null
exit;
// next code gives error because container is null:
// return $this->getDoctrine()
// ->getRepository('AppBundle:User')
// ->find($id);
} // "get_user" [GET] /users/{slug}
}
My services.yml:
# Learn more about services, parameters and containers at
# http://symfony.com/doc/current/service_container.html
parameters:
#parameter_name: value
services:
# default configuration for services in *this* file
_defaults:
# automatically injects dependencies in your services
autowire: true
# automatically registers your services as commands, event subscribers, etc.
autoconfigure: true
# this means you cannot fetch services directly from the container via $container->get()
# if you need to do this, you can override this setting on individual services
public: false
# makes classes in src/AppBundle available to be used as services
# this creates a service per class whose id is the fully-qualified class name
AppBundle\:
resource: '../../src/AppBundle/*'
# you can exclude directories or files
# but if a service is unused, it's removed anyway
exclude: '../../src/AppBundle/{Entity,Repository}'
# controllers are imported separately to make sure they're public
# and have a tag that allows actions to type-hint services
AppBundle\Controller\:
resource: '../../src/AppBundle/Controller'
public: true
tags: ['controller.service_arguments']
# add more services, or override services that need manual wiring
# AppBundle\Service\ExampleService:
# arguments:
# $someArgument: 'some_value'
# ----------------------------------------------------------------
# !!!!!!! Next code inject container and the code is start working
# AppBundle\Controller\UserController:
# calls:
# - [setContainer, ["@service_container"]]
I got the same issue, it is a pain in the ass
Can someone of you create a small example project that makes it easily possible to reproduce your issue?
@xabbuh Here is a test project with the problem:
https://github.com/maxixcom/symfony-container
But it use db. You need configure and create some db. And run migrations:
./bin/console doctrine:migration:migrate
Actually it creates FOSUserBundle User table.
Look at UserController::getAction - (GET request - /users/1). There is a problem.
But if you try DefaultController::indexAction (GET request - /) you'll see that container exist
Thank you for providing this useful example. I think I was able to reproduce the issue. Can you please check if symfony/symfony#23239 fixes it for you?
@xabbuh Yes, it fixes the issue. Container is in controller now.
Hi,
I have the same issue. How to fix the problem? Manually?
Thanks.
to fix it you have to update Framework Bundle... or just edit it and add the new content
https://github.com/symfony/symfony/pull/23239/files
vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Controller/ControllerResolver.php
Will it be fixed somehow in the bundle or should we wait for the next symfony release and until then apply some custom fixes?
Symfony 3.3.3 containing this fix was released.
Symfony 3.3.9 has this issue when using JMSDiExtraBundle. The "solution" (I bracket it as I have NO idea whats going on) was to add the setContainer call to my controllers in the "generic" autowiring section:
# controllers are imported separately to make sure they're public
# and have a tag that allows actions to type-hint services
AppBundle\Controller\:
resource: '../../src/AppBundle/Controller'
public: true
tags: ['controller.service_arguments']
**calls:
- [setContainer, ["@service_container"]]**
Also Symfony 3.3.13 is still affected. The solution is the same above... but didn't have it been fixed already?
Are you using JMSDiExtraBundle?
Yes, version 1.9.0
Then it's probably related to their code. I don't know if they ever fixed the issue on their side.
@ventuc you need to downgrade JMSDiExtraBundle to 1.7.0 version.
It solves the issue.
Most helpful comment
Symfony 3.3.3 containing this fix was released.