I started work on extracting Bundle from HttpKernel into a Bundle
Component<https://github.com/symfony/symfony/pull/4819>with the goal of
promoting reusability of Bundles as a
packaging mechanism outside the scope of HttpKernel applications. My main
reason for extracting Bundle was because I didn’t want to depend on an
“HTTP Kernel” in my non-HTTP application.
I’m still very new to Symfony so I had not really paid much attention to
HttpKernel or Kernel until very recently. I started to look at it more
closely last night because I wondered if I could use *Kernel* itself and
leverage a much larger chunk of Symfony code for my project since I was
needing to do many (all?) of the same things that *Kernel* was. I was
encouraged by the following:
*The Kernel is the heart of the Symfony system. It manages an environment
made of bundles.*
This sounded like exactly what I was hoping for so I started digging in to
see what I'd need to do to support it. It implements KernelInterface…
awesome. Wait, why does KernelInterface extend HttpKernelInterface? D'oh. I
asked around on #symfony-dev why KernelInterface extends
HttpKernelInterface instead of being independent and got some fun
responses. Main takeaway: Kernel is in HttpKernel, so it makes sense for
Kernel to be HTTP-aware. Yes, this makes sense, but it is *not* the answer
I was hoping for. What it did was get me thinking that maybe Kernel
shouldn't be in the HttpKernel component then...
So I spent some time this morning looking at whether or not it would be
feasible to detach Kernel from HttpKernel for the purpose of making it a
standalone component. I think it might be possible but I’m not 100% up on
all of the internals so I wanted some feedback on this before I actually
try to make it work and waste what will undoubtably be a lot of time if
there is little or no chance of this being accepted. :)
One direction:
- Provide a Bundle component that encapsulates the core bits of the
internals of a Bundle. (BundleInterface, abstract Bundle, etc.)
- Provide a Kernel component that is capable of creating a HTTP-unaware
application that leverages all of the Container + Bundles.
(KernelInterface, abstract Kernel, DI Extension support classes, etc.)
Alternative:
- Provide a Kernel component that has Kernel + Bundle stuff in it.
The former results in two extra components versus just one which might be
considered a negative. It is more flexible though and would open up the
door for more people to use the core structure of bundles. The latter would
be less flexible but would result in code that is organized in a way that
is more simple.
In all cases, the existing *HttpKernelInterface* and *HttpKernel* would
stay the same. *KernelInterface* would extend *
Symfony\Component\Kernel\KernelInterface* and *HttpKernelInterface* but
would be otherwise backwards compatible. This would hopefully ensure no BC
breaks and should fit nicely since the HttpKernel kernels would essentially
be implementations of the Kernel component.
The majority of the code for *Kernel* (minus implementations for *
TerminableInterface* and *HttpKernelInterface*) and *KernelInterface* would
move to the new components:
namespace Symfony\Component\Kernel;
interface KernelInterface *extends* \Serializable
{
// ... code from Symfony\ComponentHttpKernel minus extending
// HttpKernel
}
abstract class Kernel implements KernelInterface {
// ... code from Symfony\Component\HttpKernel minus the HttpKernelInterface
+
// TerminableInterface implementations.
}
The existing *Kernel* class would need to be updated to extend the new *
Kernel* and add implementations for *TerminableInterface* and *
HttpKernelInterface* from the original implementation:
namespace Symfony\Component\HttpKernel;
use Symfony\Component\Kernel\Kernel as BaseKernel;
abstract class Kernel extends BaseKernel implements KernelInterface,
HttpKernelInterface, TerminableInterface
{
/**
* {@inheritdoc}
*
* @api
*/
public function handle(Request $request, $type =
HttpKernelInterface::MASTER_REQUEST, $catch = true)
{
if (false === $this->booted) {
$this->boot();
}
return $this->getHttpKernel()->handle($request, $type, $catch);
}
/**
* Gets a http kernel from the container
*
* @return HttpKernel
*/
protected function getHttpKernel()
{
return $this->container->get('http_kernel');
}
/**
* {@inheritdoc}
*
* @api
*/
public function terminate(Request $request, Response $response)
{
if (false === $this->booted) {
return;
}
if ($this->getHttpKernel() instanceof TerminableInterface) {
$this->getHttpKernel()->terminate($request, $response);
}
}
}
use Symfony\Component\Kernel\KernelInterface as BaseKernelInterface;
interface KernelInterface extends BaseKernelInterface, HttpKernelInterface,
\Serializable
{
}
There are of course a lot of other bits to worry about in here. I'm not
sure which things should be moved to the Kernel bundle vs staying in
HttpKernel. I'm sure there are some big BC things I have not considered in
moving other things around.
The end result would be something like the following:
use Symfony\Component\Kernel\Kernel;
use Symfony\Component\Config\Loader\LoaderInterface;
use SomeApp\Bundle\CoreBundle\SomeApp;
class AppKernel extends Kernel
{
public function registerBundles()
{
$bundles = array(
new SomeApp\Bundle\CoreBundle\CoreBundle,
new ThirdParty\SomeAppExtensionBundle\SomeAppExtensionBundle,
);
if (in_array($this->getEnvironment(), array('dev', 'test'))) {
$bundles[] = new SomeApp\Bundle\DebugBundle\DebugBundle(),
}
return $bundles;
}
public function registerContainerConfiguration(LoaderInterface $loader)
{
$loader->load(__DIR__.'/config/config_'.$this->getEnvironment().'.yml');
}
}
$kernel = new AppKernel('prod', false);
$kernel->loadClassCache();
$someApp = new SomeApp($kernel);
$someApp->something();
In the end I could probably just use the existing HttpKernel component and
ignore the handle method. :) It would definitely save a lot of time... but the
Kernel is cool and I think that there might be other people out there that
might be more apt to use it if it was its own standalone thing and not
connected in any way to HttpFoundation, HttpKernel, or implying serving
anything over HTTP in any way.
Is this something that is worthwhile for me to continue thinking about,
discussing, and pursuing?
--
If you want to report a vulnerability issue on symfony, please send it to
security at symfony-project.com
You received this message because you are subscribed to the Google
Groups "symfony developers" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to
[email protected]
For more options, visit this group at
http://groups.google.com/group/symfony-devs?hl=en