Symfony 5.2 Command / Console connecting to DBAL
Posted: 8 Feb 2021, 6:51am - Monday

I have been searching how my Symfony Command/Console can connect to the database using DBAL. Somehow there's no working solution that its not either deprecated or the solution was lower version of what I am looking for.

So I made my own solution, takes a while but it works.

  1. I used the Symfony\Dotenv class to read the .env file and get DATABASE_URL value
  2. Then I created a class to parse the DATABASE_URL value to Driver/Connection class required array structure (see screenshot below, $db_options variable)
  3. then I instantiate Driver class and feed the parsed array and Driver to Connection (see sample code below)

Filename: DatabaseUrlEnvUtil

/**
 *  // mysql://root:secret@127.0.0.1:3306/dbname?serverVersion=5.7
 *
 * Class DatabaseUrlEnvUtil
 * @package App\Utils
 */
class DatabaseUrlEnvUtil
{
    /**
     * @param string $str
     * @return array
     */
    public static function convertToArray(string $str) {
        $breakers = [
            /*'driver' => [
                'delimeter' => '://',
                'position' => 0
            ],*/
            'user' => [
                'delimeter' => [':', '//'],
                'position' => [1, 1]
            ],
            'password' => [
                'delimeter' => [':', '@'],
                'position' => [2, 0]
            ],
            'host' => [
                'delimeter' => ['@', ':'],
                'position' => [1, 0]
            ],
            'dbname' => [
                'delimeter' => ['/', '?'],
                'position' => [3, 0]
            ],
            'port' => [
                'delimeter' => [':', '/'],
                'position' => [3, 0]
            ]
        ];

        $data = [];
        foreach($breakers as $key => $breaker) {
            $delimeter = isset($breaker['delimeter']) ? $breaker['delimeter'] : null;
            $position = isset($breaker['position']) ? $breaker['position'] : 0;

            if (is_null($delimeter)) {
                continue;
            }

            if (is_array($delimeter)) {
                $tmp_data = $str;
                foreach($delimeter as $i => $item) {
                    $tmp = explode($item, $tmp_data);
                    $tmp_data = $tmp[$position[$i]];
                }
                $data[$key] = $tmp_data;
            } else {
                $tmp = explode($delimeter, $str);
                $data[$key] = isset($tmp[$position]) ? $tmp[$position] : null;
            }
        }

        return $data;
    }
}

Console/Command Output:

That's it, problem solved.