Отделение конфигурации базы данных от подключения

Я пытаюсь установить соединение с базой данных, при этом информация о конфигурации базы данных отделена от соединения.

Это код, который я написал

Информация о конфигурации БД:

$config = array(
"database" => array(
   "host" => "host",
   "username" => "username",
   "password" => "password",
   "name" => "name",
)
);

define("databse_config", $config["database"]);

$config обычно также содержит другую информацию, не относящуюся к вопросу, поэтому я определил «database_config».

подключение к базе данных:


require_once "config.php";
define("DB_HOST", databse_config['host']);
define("DB_USERNAME", databse_config['username']);
define("DB_PASSWORD", databse_config['password']);
define("DB_NAME", databse_config['name']);

function connect()
{
    $dbhost = DB_HOST;
    $dbuser = DB_USERNAME;
    $dbpass = DB_PASSWORD;
    $dbname = DB_NAME;

    try {
        $conn = new PDO("mysql:host=$dbhost;dbname=$dbname", $dbuser, $dbpass);
        $conn->exec("set names utf8");
        $conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
        return $conn;
    } catch (PDOException $e) {
        echo 'Connection failed: ' . $e->getMessage();
    }
}

connect();

Проблема, с которой я продолжаю сталкиваться, заключается в том, что при попытке выполнить функцию страница продолжает загружаться и в конечном итоге выводит следующую ошибку:

Ошибка подключения: SQLSTATE [HY000] [2002] Время ожидания подключения истекло.

Я новичок в PDO, поэтому я пробовал то же самое при использовании mysqli, что дало тот же результат.

Любая помощь будет оценена по достоинству.


person Kjvhout    schedule 19.03.2020    source источник
comment
У меня такое чувство, что вы зашли слишком далеко со своей разлукой. не слишком ли много двух блоков определения констант и трех блоков определений переменных для задачи? Разве вы не можете просто использовать databse_config внутри connect()?   -  person Your Common Sense    schedule 19.03.2020
comment
Привет, я уже пробовал это делать. Я также пытался запустить код без функции, и он все равно не работает.   -  person Kjvhout    schedule 19.03.2020
comment
В яблочко. Так что ваш вопрос не в том, как отделить, а в том, как исправить ошибку?   -  person Your Common Sense    schedule 19.03.2020
comment
Да, точно. Я должен был быть более конкретным с заголовком.   -  person Kjvhout    schedule 19.03.2020


Ответы (1)


Ошибка подключения: SQLSTATE [HY000] [2002] Время ожидания подключения истекло.

Это означает, что php пытался установить TCP/IP-соединение с вашим сервером базы данных и НЕ ПРОШЕЛ. Вы указали имя хоста DB_HOST, которое недоступно по сети из местоположения вашей программы php.

Значение имени хоста может отсутствовать или быть неправильным. Если вы указали его по имени (mysql-server.example.com), это сообщение об ошибке говорит о том, что поиск DNS-имени выполнен успешно.

Итак, ваш php отправляет запрос на сервер для соединения TCP/IP. Этот запрос никогда не получает ответа. Это означает, что где-то есть брандмауэр, блокирующий соединение, или что нет сетевого маршрута от вашей программы php к сети.

Все это означает, что значение $dbhost неверно в вашей операции new PDO().

Ваш код можно было бы сильно упростить без потери модульности. sprintf() помогает. Чем проще, тем лучше для устранения неполадок.

require_once "config.php";
function connect()
{
    try {
        $connectionString = sprintf ("mysql:host=%s;dbname=%s", 
                                      database_config['host'],
                                      database_config['name']);
        $conn = new PDO($connectionString, 
                        database_config['username'],
                        database_config['password']);
        $conn->exec("set names utf8");
        $conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
        return $conn;
    } catch (PDOException $e) {
        echo 'Connection failed: ' . $e->getMessage();
    }
}    
connect();

И вы можете echo $connectionString; посмотреть, что внутри, и убедиться, что это не что-то странное.

person O. Jones    schedule 19.03.2020
comment
Привет, спасибо за вашу реакцию. Все детали, которые я дал для соединения, должны быть хорошими. Раньше я подключался к базе данных, но тогда я не разделял конфигурацию базы данных. Единственная разница теперь в том, что все детали предоставляются в виде массива и из файла конфигурации. - person Kjvhout; 19.03.2020
comment
Верно. Тем не менее, я предлагаю вам устранять неполадки в обратном направлении от точки отказа. Я хочу сказать, что ваша подсказка - неправильное имя хоста сервера. - person O. Jones; 19.03.2020
comment
Извините, вы были совершенно правы. Я вернулся к тому, что я изменил, так как это сработало, и обнаружил, что где-то по ходу я меняю имя хоста. Большое спасибо!! - person Kjvhout; 19.03.2020