Closed samuelgfeller closed 1 month ago
Hi, @samuelgfeller!
It seems a little bit hard to enable DI container compilation using this template. Would you happen to have any suggestions on how to make it easy?
Here's what I mean. We want to enable compilation only when in production. Still, we know it only after settings were set, but settings were available only after the container was built (I don't think we wanna require
settings twice on each request) -> the built container can not be compiled.
So, in that case, the only obvious way I see to compile it is to use a separate command (CLI script) that should be used in the deployment process.
Hi @alexandrmazur96
I don't have a lot of experience with container compilation, but if I understand correctly, the issue is that settings.php
sets the APP_ENV
to prod
only after the container is built because settings.php
is required in the container definition.
A way to circumvent this would be to set the APP_ENV
elsewhere, e.g. the bootstrap.php
file, before building the container.
Currently, in this template, the APP_ENV
prod
is set in the production env.php
file and dev
is the default fallback value if nothing is set (docs).
This isn't ideal in your case if you want to be able to know if the environment is prod
before the settings are loaded. For this, you need a way to know that the application is in the production environment which is not related to settings and set the APP_ENV
to prod
accordingly.
There are certainly better other ways to do this, but you could, for example, create a file config/set-prod-env.php
which
only exists on the production server with the following content:
<?php
$_ENV['APP_ENV'] = 'prod';
Then in the bootstrap.php
file, you can check if this file exists and if it does, require it.
<?php
use DI\ContainerBuilder;
use Slim\App;
require __DIR__ . '/../vendor/autoload.php';
// Set the APP_ENV to prod if the file exists
if (file_exists(__DIR__ . '/set-prod-env.php')) {
require __DIR__ . '/set-prod-env.php';
} elseif (!isset($_ENV['APP_ENV'])) {
// Set the APP_ENV to dev if it is not already set
$_ENV['APP_ENV'] = 'dev';
}
// Instantiate DI ContainerBuilder
$containerBuilder = new ContainerBuilder();
// Add container definitions
$containerBuilder->addDefinitions(__DIR__ . '/container.php');
// Compile or use the cache if prod env
if ($_ENV['APP_ENV'] === 'prod') {
$containerBuilder->enableCompilation(__DIR__ . '/var/cache');
}
$container = $containerBuilder->build();
// Create app instance
return $container->get(App::class);
Or if you don't want to create an additional file, you could extract the APP_ENV
value from the secret prod env.php
with file_get_contents
and use this value, but this doesn't seem like a very clean solution to me.
Let me know if that helps and how you end up doing it.
If you have questions or suggestions, please don't hesitate to let me know here.