2016-01-22 38 views
4

我已閱讀了很多關於此的帖子,似乎沒有任何共識。我正在爲Web應用程序編寫一個開源通用安裝程序,我需要確認一個成功的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

<?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,$ DBU,$ DBP,$選擇)或死亡( '不能連接');'如果連接是不是會產生錯誤建立了 – mega6382

+0

我很欣賞它......如果主機名是錯誤的,這隻會引發錯誤。如果用戶名,數據庫名稱或密碼錯誤,則不會引發錯誤。我想我會嘗試使用mysqli。 –

+0

正如我在下面的答案中所述,這些答案都不包括表單驗證。爲了使這些檢查工作,必須提供主機,數據庫和用戶。如果其中一個是空白的,測試將返回一個誤報。 –

回答

5

如果有任何連接錯誤,一個PDOException對象將被拋出。

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

要驗證數據,如主機名,數據庫名稱和登錄憑據是正確的,你必須強迫用戶不離開這些數據爲空。事實上,完全有可能只與主機建立連接,這是因爲mysql允許創建與任何用戶名匹配的空白用戶名(空字符串)的帳戶。另外,爲避免dsn字符串中的參數注入(例如名爲foo;port=123的數據庫名稱),您至少應檢查連接選項中是否存在分號或NULL字節(作爲主機e數據庫名稱)。

/** 
* 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塊。如果你想要這個錯誤信息,你可以在catch塊中用'$ e-> getMessage()'得到它。 –