8000 [HttpKernel] Deprecate auto-discovery in Kernel::getName() by ro0NL · Pull Request #24292 · symfony/symfony · GitHub
[go: up one dir, main page]

Skip to content

[HttpKernel] Deprecate auto-discovery in Kernel::getName() #24292

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 1 commit into from
Closed

[HttpKernel] Deprecate auto-discovery in Kernel::getName() #24292

wants to merge 1 commit into from

Conversation

ro0NL
Copy link
Contributor
@ro0NL ro0NL commented Sep 22, 2017
Q A
Branch? 3.4
Bug fix? no
New feature? yes
BC breaks? no
Deprecations? yes
Tests pass? almost
Fixed tickets symfony/recipes#186
License MIT
Doc PR symfony/symfony-docs#...

The auto-discovery of kernel name doesnt work well with new structure. You probably want to override it.

@fabpot suggested to get rid of getName(), however; this is an important feature actually. It enables multi-kernel approach. See https://github.com/yceruto/symfony-skeleton-vkernel for example, but also things like ApiKernel, AppKernel live today.

In core it's crucial for Kernel::getContainerClass() and %kernel.name% might being used a lot today. So the concept of a kernel name should not be deprecated to me.

This PR suggests the default kernel name will be "app" in 4.0, but any other can be specified as constructor arg. I.e. set it from APP_NAME env.

cc @yceruto

@@ -297,6 +305,10 @@ public function getName()
if (ctype_digit($this->name[0])) {
$this->name = '_'.$this->name;
}

if ('app' !== $this->name) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why app here? Why does that indicate that it's been auto-discovered?

And what would this look like in 4.0? Would this method exist... but throw an exception? (so that the user either needs to override this method or pass in as an arg?)

Copy link
Member
@yceruto yceruto Sep 27, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And what would this look like in 4.0? Would this method exist... but throw an exception? (so that the user either needs to override this method or pass in as an arg?)

For 4.0 auto-discovery is removed and it should look like a simple getter.

Copy link
Member
@stof stof Sep 27, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@weaverryan AFAIK, in 4.0, this method would be getName() { return 'app';}. So anyone getting a different name through auto-discovery will need to override the method instead, to see the name explicitly (and so this code would not run anymore).
If the auto-discovered name is app (which is the case for all standard-edition projects), migrating to 4.0 would not break things as the hardcoded app would do the same.

We have 2 solutions in 4.0:

  • make the method return an hardcoded name and tell multi-kernel projects that they should override the method to avoid bugs. Existing multi-kernel projects will be warned for this by the deprecation. And new multi-kernels project should be warned about it with a big warning in the 4.0 documentation about multi-kernel setup. This is the approach indicated by the current deprecation.
  • make the method abstract. This is a bigger BC break as all SE projects would have to implement the method, but it would make the explanation simpler for multi-kernel projects as they would work the same (everyone has to overwrite the method). For flex projects, this is not an issue as the recipe is doing the override already (to have it named app and not src in 3.x projects), so it would just mean keeping the override in the 4.0 recipe.

If we go for the second option, the deprecation should instead be moved at the very beginning of getName and say Not overriding Kernel::getName is deprecated since Symfony 3.4. The method will be astract in 4.0.`

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@stof for 4.0 it should look like getName() { return $this->name; }

@fabpot
Copy link
Member
fabpot commented Sep 27, 2017

I would suggest to use the FQCN instead of app. That way, everything is automatic and no collision is ever possible.

@@ -297,6 +305,10 @@ public function getName()
if (ctype_digit($this->name[0])) {
$this->name = '_'.$this->name;
}

if ('app' !== $this->name) {
@trigger_error(sprintf('Auto-discovery of the kernel name is deprecated since Symfony 3.4 and won\'t be supported in 4.0.'), E_USER_DEPRECATED);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The message should tell users to override Kernel::getName()

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The idea is to pass the Kernel name as constructor argument, with app default for 4.0

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

then it should tell them to pass it in the constructor

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

actually, the deprecation should happen in the constructor itself (when passing null)

@stof
Copy link
Member
stof commented Sep 27, 2017

@fabpot FQCN is incompatible with the current regex. And allowing more chars is a BC break (as it makes the name unsuitable for some of its current usage, especially if we allow \)

@stof
Copy link
Member
stof commented Sep 27, 2017

Passing the name in the constructor makes things harder to use actually. The kernel is instantiated in several different places in the kernel (in the front controller, in the console, in each KernelTestCase test, in your Behat testsuite if you use it with the Symfony2Extension, etc...), and so it forces to duplicate the name everywhere (they must use the same name to reuse the cache).

I prefer the approach I thought about: keep overriding getName as today (so that name selection happens when defining the class, not when using it)

@fabpot
Copy link
Member
fabpot commented Sep 27, 2017

@stof I know, but computing a hash out of the class name would work well.

@yceruto
Copy link
Member
yceruto commented Sep 27, 2017

Passing the name in the constructor makes things harder to use actually. The kernel is instantiated in several different places in the kernel (in the front controller, in the console, in each KernelTestCase test, in your Behat testsuite if you use it with the Symfony2Extension, etc...), and so it forces to duplicate the name everywhere (they must use the same name to reuse the cache).

For single Kernel approach having a default Kernel name app for 4.0 it is not a problem, right? all Kernel instances using the same name and then the same container class.

Now for multiple kernels approach, we need anyway update the kernel to instantiate everywhere, right? either with the documented https://symfony.com/doc/current/configuration/multiple_kernels.html multi-class approach or name-based virtual kernel we are forced to update all entry points to set the class name or the kernel name respectively (just once for v-kernel by using env var for kernel name).

I prefer the approach I thought about: keep overriding getName as today

You could still, even configuring it protected $name = 'foo' should be enough or directly in the constructor if some logic is needed.

so that name selection happens when defining the class, not when using it

Why is it wrong to define the kernel name when it is instantiated? Indeed it made possible to optimize the multi-kernel class approach with just one Kernel.

@ro0NL
Copy link
Contributor Author
ro0NL commented Sep 27, 2017

Passing the name in the constructor makes things harder to use actually.

Im not sure. We are really flexible this way, and explicit. I tend to agree with @yceruto, IMHO the current approach is too opinionated in design.

For "we need to init kernel everywhere" i suggest a APP_NAME env or some config/kernel.php thingy to boot, but i guess sensible defaults fits 8/10 cases :)

computing a hash out of the class name would work well

Yes, interesting. Ill look into that.

@stof
Copy link
Member
stof commented Sep 27, 2017

@ro0NL an env variable won't work for a multi-kernel approach. You may need to use both kernels in the same process (and even in other cases, it might be hard to change the env variable depending on the kernel being used in this process).

Creating a kernel/config.php to configure this would just make things more complex than defining thi in your src/Kernel.php file where the kernel class is defined.

For projects, you should never need to pass different names for the same kernel (the name is here to make sure that multi-kernel setups don't reuse the same class names for the DIC and router generated classes, so changing the name in your project would mean your breaking the usage of your cache)

@fabpot
Copy link
Member
fabpot commented Sep 27, 2017

I still think that getting rid of the name altogether is the best option.

@ro0NL
Copy link
Contributor Author
ro0NL commented Sep 28, 2017

@fabpot that practically means virtual kernel support needs to happen on user's side. Might be a path, but out-of-the-box support with getName is really nice.

For this PR; i really like kernels having a name by design. For technical reasons, but also easy identification i guess. Basically not sure if getting rid of it is really worth it. It's just the auto-discovery thingy which seems a bit opinionated; not really practical/helping today.

What about a new form of (default) auto-discovery, i.e. $name ?? get_class($this)? As mentioned in #24292 (comment)

For the constructor arg; that be a new feature. Could be left out i guess.

cc @yceruto

*/
public function __construct($environment, $debug)
public function __construct($environment, $debug, $name = null)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's a BC break.

@nicolas-grekas
Copy link
Member

Moving to 4.1. Rebase on master might be needed, where PHP 7.1 features can be used btw.

@nicolas-grekas
Copy link
Member

I'd suggest to do nothing here and close this one. Not really worth it, isn't it?

@ro0NL
Copy link
Contributor Author
ro0NL commented Dec 29, 2017
Symfony 4.0.2 (kernel: src, env: dev, debug: true)

not sure you want to settle with kernel: src by default?

@nicolas-grekas
Copy link
Member

We already did to me :)

@ro0NL
Copy link
Contributor Author
ro0NL commented Dec 29, 2017

well.. hm.. ok. You can override anyway. Closing as there no open issues currently.

@ro0NL ro0NL closed this Dec 29, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants
0