Search code examples
phpslimslim-3

Slim 2.x to 3.x upgrade - configureMode and getInstance replacement


I am working on upgrading Slim 2.x to 3.x to fix security findings. Currently in Slim 2 we are using configureMode to store environment specific database connections. The 3.0 upgrade guide only says that configureMode has been removed but doesn't tell you what to use instead. I've never worked in PHP as well as anyone else in my group (legacy product).

In my .htaccess file we are setting the environment

SetEnv SLIM_MODE development

in my index.php currently we use configureMode to set db properties

$app->configureMode('development', function () use ($app) {
    $app->config(array(
        'masterDB' => array(
            'dbhost' => 'DEVDB',
            'dbuser' => 'USER',
            'dbpass' => 'PASS',
            'dbname' => 'MASTER'
        ),
        'userDB' => array(
            'dbuser' => 'USER',
            'dbpass' => 'PASS'
        ),
        'debug' => false
    ));
});

/**
 * QA configuration
 */ 
$app->configureMode('qa', function () use ($app) {
    $app->config(array(
        'masterDB' => array(
            'dbhost' => 'DEVDB',
            'dbuser' => 'USER',
            'dbpass' => 'PASS',
            'dbname' => 'MASTER'
        ),
        'userDB' => array(
            'dbuser' => 'USER',
            'dbpass' => 'PASS'
        ),
        'debug' => false
    ));
});

In order to access these values we are using getInstance which has also been removed.

$app = \Slim\Slim::getInstance();

The tutorial just says these have been removed and I'm not sure how to replace. Can Slim 3.x support environmental configuration like we currently use or does this now need to be set during the install into that environment?

What is the correct way to set and access these values now?


Solution

  • I'm working with Slim 3 some years and I'm sure there is no "official" way of how to configure environment specific settings. But I would like to tell you how I do it.

    First create directory config/ in your project root directory.

    Then place all your configurations files into this config/ directory.

    1. Create a file: config/defaults.php

    The file contains all default settings, for all environments.

    <?php
    //
    // Configure defaults for the whole application.
    //
    // Error reporting
    error_reporting(0);
    ini_set('display_errors', '0');
    
    // Timezone
    date_default_timezone_set('Europe/Berlin');
    
    // Slim settings
    $settings = [
        'httpVersion' => '1.1',
        'responseChunkSize' => 4096,
        'outputBuffering' => 'append',
        'determineRouteBeforeAppMiddleware' => true,
        'displayErrorDetails' => false,
        'addContentLengthHeader' => true,
        'routerCacheFile' => false,
    ];
    

    Full example

    1. Then create a configuration file for the development environment: config/development.php
    <?php
    
    //
    // Development environment
    //
    $settings['env'] = 'development';
    
    // Error reporting
    error_reporting(E_ALL);
    ini_set('display_errors', '1');
    
    // Display all errors
    $settings['displayErrorDetails'] = true;
    
    $settings['db']['host'] = '{{db_host}}';
    $settings['db']['database'] = '{{db_database}}';
    

    Repeat this step for integration.php, staging.php and production.php.

    1. Then create a file env.php to define the effective environment.

    Note: Please don't commit this file to git.

    <?php
    /**
     * Environment specific application configuration.
     *
     * You should store all secret information (username, password, token) here.
     *
     * Make sure the env.php file is added to your .gitignore
     * so it is not checked-in the code
     *
     * Place the env.php _outside_ the project root directory, to protect against
     * overwriting at deployment.
     *
     * This usage ensures that no sensitive passwords or API keys will
     * ever be in the version control history so there is less risk of
     * a security breach, and production values will never have to be
     * shared with all project collaborators.
     */
    require __DIR__ . '/development.php';
    
    // Database
    $settings['db']['username'] = '{{db_username}}';
    $settings['db']['password'] = '{{db_password}}';
    
    // SMTP
    $settings['smtp']['username'] = '[email protected]';
    $settings['smtp']['password'] = '';
    
    1. Then create a file config/settings.php that merges all other configuration files:
    <?php
    
    // Defaults
    require __DIR__ . '/defaults.php';
    
    // Load environment configuration
    if (file_exists(__DIR__ . '/../../env.php')) {
        require __DIR__ . '/../../env.php';
    } elseif (file_exists(__DIR__ . '/env.php')) {
        require __DIR__ . '/env.php';
    }
    
    if (defined('APP_ENV')) {
        require __DIR__ . '/' . APP_ENV . '.php';
    }
    
    return $settings;
    

    Usage

    In your config/bootstrap.php you can load all settings and pass that configuration to the Slim App instance:

    // Instantiate the app
    $app = new \Slim\App(['settings' => require __DIR__ . '/../config/settings.php']);
    
    // Set up dependencies
    
    // Register middleware
    
    // Register routes
    
    $app->run();