La seule chose que je peux voir ici, c'est que vous dites à PDO de lancer des exceptions après vous avez essayé d'ouvrir la connexion. C'est probablement trop tard.
Ce que vous pourriez faire à la place, c'est envoyer cette option au constructeur directement en utilisant le 4ème paramètre :
try {
$opts = array(PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION);
$db = new PDO($dbms . ':host=' . $dbhost . ';port=' . $dbport . ';dbname=' . $dbname,
$dbuser, $dbpasswd, $opts);
} catch(PDOException $e) {
...
Cela résoudra probablement votre problème.
Modifier : Si le nom d'hôte est fourni par l'utilisateur, vous pouvez le valider avant de l'envoyer au constructeur du PDO.
Par exemple en utilisant :
if (filter_var(gethostbyname($user_provided_host_name), FILTER_VALIDATE_IP)) {
// valid hostname / ip address
}
Cela fonctionnera pour les noms de domaine, localhost
et adresses IP.