How do I get a service from the container directly, if I didn't/couldn't inject the service using DI?
You need to add your dependencies so the service locator can find them.
Add a method getSubscribedServices()
to your controller class:
public static function getSubscribedServices()
{
return array_merge(
parent::getSubscribedServices(),
[
'checker' => Checker::class,
]
);
}
If your controller class extends AbstractController
you can simply do:
$this->get('checker');
If you want to do it in another type of class (e.g. a service that doesn't extend AbstractController
), then you need to declare that your service implements the ServiceSubscriberInterface
.
use Symfony\Contracts\Service\ServiceSubscriberInterface;
use Psr\Container\ContainerInterface;
class FooService implements ServiceSubscriberInterface {
public function __construct(ContainerInterface $locator)
{
$this->locator = $locator;
}
public static function getSubscribedServices() { /* same as before */ }
public function get($service)
{
return $this->locator->get($service);
}
}
... and you would be able to do the same than you in the controller earlier.
Selecting one of many services as the service to use
Actually, I believe you were on the right track with the third bullet point in the "What I've tried so far" section, except that the service container does register itself as a service, but it's called service_container
, not container
.
How to prevent entities from being listed as services in the container?
it is expected.
have a look at config/services.yaml where the magic happens (at least this happens in my services.yaml):
# removed lines for readability before, after and in-between the following
services:
App\:
resource: '../src/*'
exclude: '../src/{Entity,Migrations,Tests}'
this essentially should turn everything except for entities, migrations and tests in the src
directory into services. you can adapt this to your needs obviously.
So essentially ... if you remove that App\
entry, you would be bound to explicitly add whitelist all classes that are supposed to be services.
Blacklisting on the other hand is shown in the example, although the example is quite general. Maybe there are more sophisticated ways to do this ...
Service not found: even though it exists in the app's container
A lot of things changed in symfony4 vs previous versions. You are using everything as if in a previous version. The quick solution is not the "preferred" way, but to start can change the public
key from the default false
to true
in your services.yaml file.
A better way is to leave it private and use dependency injection instead. The naming of the service has changed as well (now just the path of the service). See the docs here. For your code, try these:
// services.yaml
services:
_defaults:
autowire: true
autoconfigure: true
public: false
App\Foo\Bar:
tags: { ** }
And the controller with dependence injection:
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
class MyController extends AbstractController
{
public function baz(Request $request, Bar $bar)
{
$bar->doSomething();
}
}
There's a nice tutorial about these things (and more) here.
Related Topics
Curl_Exec Printing Results When I Don't Want To
Array Merge on Multidimensional Array
PHP Sessions to Authenticate User on Login Form
Generating a Waveform Using Ffmpeg
PHP SQL Select Where Like Search Item with Multiple Words
Storing and Retrieving an Array in a PHP Cookie
Folder Structure of a PHP MVC Framework... am I Doing This Right
Symfony How to Return All Logged in Active Users
How to Post Multiple <Input Type="Checkbox" /> as Array in PHP
PHP Loop: Add a Div Around Every Three Items Syntax
PHP Merge Array(S) and Delete Double Values
In Laravel How to Add Values to a Request Array
Efficient PHP Auto-Loading and Naming Strategies
Symfony2 - How to Switch from "Dev" to "Prod"
Best Way to Do a Weighted Search Over Multiple Fields in MySQL