C3rd
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.
- I used the Symfony\Dotenv class to read the .env file and get DATABASE_URL value
- Then I created a class to parse the DATABASE_URL value to Driver/Connection class required array structure (see screenshot below, $db_options variable)
- 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.