Ulepszamy nasz Config o możliwość podania portu bazy danych. Do dzieła!

Pierwsza rzecz – config.ini:

; This is a sample configuration file
; Comments start with ';', as in php.ini

[DB_CREDENTIALS]
driver = mysql
host = localhost
db_name = mydb123
db_user = usr
db_password = pass
port = 3306

Teraz nasza klasa config:

class ConfigINI {

    public static $iniPath = __DIR__ . "/config.ini";

    public static function getPDOCredentials(){
        $ini_array = parse_ini_file(static::$iniPath, true);
        return $ini_array['DB_CREDENTIALS'];
    }
}

class PDOConnection {

    protected $connection;
    protected $credentials;

    public static $requiredKeys = [
        'driver',
        'host',
        'db_name',
        'db_user',
        'db_password',
        'port'
    ];
   //(...)

Bez zmian, ale musieliśmy dopisać klucz w PDOConnection. Teraz metoda connect:

class PDOConnection {

    //(...)

    public function connect(): PDOConnection{
        try {
            $this->credentials = ConfigINI::getPDOCredentials();

            if(!array_key_exists('port', $this->credentials))
                $this->credentials['port'] = 3306;

            if(!static::hasRequiredKeys($this->credentials))
                throw new Error("Credentials dont have valid keys");

            $parsed = static::parseCredentials($this->credentials);
            $this->connection = new PDO(...$parsed);

        } catch (Exception $e) {
            echo $e->getMessage();
        }
        
        return $this;
    }

    //(...)

}

Obsługujemy możliwość, w której portu nie ma – wtedy używamy domyślnego 3306. Pora na parseCredentials:

class PDOConnection {

    //(...)

    public static function parseCredentials($credentials){
        $driver = $credentials['driver'];
        $config = http_build_query(arg_separator:';', data:
            [
                'host' => $credentials['host'],
                'port' => $credentials['port'],
                'dbname' => $credentials['db_name']
            ]
            );

        $dsn = "{$driver}:{$config}";

        return [$dsn, $credentials['db_user'], $credentials['db_password']];
    }

   //(...)

}

//dsn - mysql:host=localhost;port=3306;dbname=mydb123

Używamy http_build_query z separatorem „;” do utworzenia dsn-a. Nie są to argumenty w odpowiedniej kolejności, więc używamy named arguments.

Reszta jest jak poprzednio, ale dodaliśmy możliwość przekazywania portu i uprościliśmy tamtego dość brzydkiego sprintf-a.