2016-01-22 2 views
4

Я читал много сообщений об этом, и, похоже, нет никакого консенсуса. Я пишу родовой установщик с открытым исходным кодом для веб-приложений, и мне нужно подтвердить успешное соединение PDO. Он должен проверить соединение с PDO, а затем записать фактический файл config/init. Часть записи файла работает нормально, но я не могу получить конкретную проверку того, что PDO действительно подключен. Он говорит, что он связан, если форма пуста, и она говорит, что она связана, если какая-то информация в форме верна. Как получить четкое указание на правильность учетных данных pdo? Я дам вам (урезанную) версию того, что я делаю.Мне нужно подтверждение успешного подключения к PDO

Форма:

<H2>Please fill in your database credentials</H2> 
<form class="form" action="" method="post"> 
    <label for="dbh">Database Host 
    <input class="form-control" type="text" name="dbh" value="<?php if (!empty($_POST['dbh'])){ print $_POST['dbh']; } ?>"></label><br><br> 

    <label for="dbu">Database User 
    <input class="form-control" type="text" name="dbu" value="<?php if (!empty($_POST['dbu'])){ print $_POST['dbu']; } ?>"></label><br><br> 

    <label for="dbp">Database Password 
    <input class="form-control" type="text" name="dbp" value="<?php if (!empty($_POST['dbp'])){ print $_POST['dbp']; } ?>"></label><br><br> 

    <label for="dbn">Database Name 
<input class="form-control" type="text" name="dbn" value="<?php if (!empty($_POST['dbn'])){ print $_POST['dbn']; } ?>"></label><br><br> 

РНР

<?php 
if (!empty($_POST)) { 
    $dbh=$_POST['dbh']; //db host 
    $dbu=$_POST['dbu']; //db username 
    $dbp=$_POST['dbp']; //db password 
    $dbn=$_POST['dbn']; //database name 

    //If Testing 
    if (!empty($_POST['test'])) { 
     $dsn = "mysql:host=$dbh;dbname=$dbn;charset=utf8"; 
     $opt = array(
      PDO::ATTR_ERRMODE   => PDO::ERRMODE_EXCEPTION, 
      PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC 
      ); 
     $pdo = new PDO($dsn, $dbu, $dbp, $opt); 
    } 

    //todo: If Submitted, a bunch more logic here 
} 
?> 
+0

'$ PDO = новый PDO ($ DSN, $ ДБУ, $ DBP, $ OPT) или умереть ('не удалось подключиться');' Он будет генерировать ошибку, если соединение не является установленное – mega6382

+0

Я ценю это ... это только выдает ошибку, если имя хоста неверно. Если имя пользователя, имя db или пароль неверны, это не вызывает ошибки. Я думаю, что я собираюсь попробовать mysqli. –

+0

Как я сказал в ответе ниже, ни один из этих ответов не включает проверку формы. Чтобы эти проверки работали, необходимо предоставить хост, базу данных и пользователя. Если один из них пуст, тест вернется с ложным положительным результатом. –

ответ

5

Если есть какие-либо ошибки, связь, PDOException объект будет брошен.

try { 
    $pdo = new PDO($dsn, $dbu, $dbp, $opt); 
} catch (PDOException $e) { 
    // bad connection 
} 

Чтобы убедиться, что данные, такие как имя хоста, имя базы данных и учетные данные являются правильными, вы должны заставить пользователя не оставить эти данные пустыми. Фактически, вполне возможно установить соединение только с хостом, потому что mysql позволяет создавать учетные записи с пустым именем пользователя (пустая строка), которое соответствует любому имени пользователя.

Кроме того, для того, чтобы избежать инъекций параметров (например, имя базы данных называется foo;port=123) в строке уведомления о доставке вы должны по крайней мере проверить наличие запятой или NULL байт в настройках подключения (в качестве имени хост электронной базы данных).

Пример

/** 
* Return a PDO object if the connection options are correct, and if the connection is established. False otherwhise. 
*/ 
function test_mysql_connection($host, $dbname, $username, $password = null) { 
    if (empty($host) || empty($dbname) || empty($username)) { 
     // those parameters MUST NOT be empty 
     throw new InvalidArgumentException('Host, database name and username are required.') 
    } 

    try { 
     $pdo = new PDO(build_mysql_dsn_safely($host, $dbname), $username, $password); 
     return $pdo; 
    } catch (PDOException $e) { 
     // bad connection 
     return false; 
    } 
} 

/** 
* See how is it parsed here: https://github.com/php/php-src/blob/71c19800258ee3a9548af9a5e64ab0a62d1b1d8e/ext/pdo/pdo.c#L207 
*/ 
function build_mysql_dsn_safely($host, $dbname = null, $charset = null, $port = null) 
{ 
    static $bad_chars = array(';', '=', "\0"); 

    $vars = array_filter(array(
     'host' => $host, 
     'dbname' => $dbname, 
     'charset' => $charset, 
     'port' => $port, 
    )); 

    foreach($vars as $param => $data) { 
     foreach ($bad_chars as $bad_char) { 
      if (strpos($data, $bad_char) !== false) { 
       throw new InvalidArgumentException(sprintf(
        'Connection options "%s" contains an invalid value.', $param 
       )); 
      } 
     } 
    } 

    return 'mysql:'.implode(';', array_map(function($optkey, $optval) { 
     return $optkey.'='.$optval; 
    }, array_keys($vars), $vars)); 
} 

if($pdo = test_mysql_connection($_POST['dbh'], $_POST['dbu'], $_POST['dbn'], $_POST['dbp'])) { 
    // connection established 
} 
+0

Я видел, как многие люди говорят, что не нужно делать попытку/уловку, и мне нужно больше, чем просто отсутствие ошибок .... Мне нужно сообщение об успешном успешном завершении. –

+0

люди, которые говорят, что не поймают исключение? Зачем? Я добавил пример. – Federkun

+0

@DanHoover Вы должны абсолютно использовать блоки try-catch. Если вы хотите получить сообщение об ошибке, вы можете получить его с помощью '$ e-> getMessage()' в блоке catch. –

Смежные вопросы