2012-11-06 59 views
6

有一個小問題,我一直在努力一段時間。由於我不知道這裏有什麼問題,所以我考慮將它列入此列表。也許你們有些人知道更多...php/pdo/msql - 拒絕訪問

我有一個網站的登錄,檢查一個用戶和密碼對MySQL驅動的數據庫。當pdo連接在同一個文件中都可以正常工作時,可以登錄,沒有任何問題。正如它應該工作...

但是,數據庫連接部分移動到一個單獨的功能,這是我從另一個文件包含的時候,PDO失敗於我,並給我:

SQLSTATE[28000] [1045] Access denied for user '...'@'...' (using password: NO) Fatal error: Call to a member function prepare() on a non-object in /.../.../... on line 41

爲了清楚起見,這裏是代碼:

版本1:

這工作:

<?php 
    require "./vars_and_functions.php"; 

    /* open database connection */ 
    try { 
    $pdo = new PDO("mysql:host=$db_host;dbname=$db_name", $db_user, $db_pass); 

    /* query */ 
    $query = "SELECT uname, passw FROM members WHERE uname = ? AND passw = ?"; 
    $q = $pdo->prepare($query); 
    $q->execute(array($u_name, $p_word_md5)); 
    $result = $q->rowCount(); 

    if($result == 1) { /* we have a match */      
    /* close the database connection */ 
       $pdo = null; 

       /* and redirect */ 
       header("..."); 

    } /* if */ 
    else { /* wrong credentials */ 
     /* close the database connection */     
       $pdo = null; 

       /* and go back to the login page */ 
     header("..."); 
    } /* else */ 
     } /* try */ 
    catch(PDOException $e) { 
     echo $e->getMessage(); 
    } /* catch */ 
?> 

這裏是第2版

這不起作用:

<?php 
     require "./vars_and_functions.php"; 

     /* open database connection */ 
     $pdo = database_connection(); 



    /* query */ 
      $query = "SELECT uname, passw FROM members WHERE uname = ? AND passw = ?"; 
      $q = $pdo->prepare($query); 
      $q->execute(array($u_name, $p_word_md5)); 
      $result = $q->rowCount(); 

     if($result == 1) { /* we have a match */      
       /* close the database connection */ 
        $pdo = null; 

        /* and redirect */ 
        header("..."); 

     } /* if */ 
     else { /* wrong credentials */ 
      /* close the database connection */     
        $pdo = null; 

        /* and go back to the login page */ 
      header("..."); 
     } /* else */ 
      } /* try */ 
    catch(PDOException $e) { 
     echo $e->getMessage(); 
    } /* catch */ 
?> 

我includefile vars_and_functions.php看起來是這樣的:

$db_host = "...";  
$db_name = "...";   
$db_user = "...";  
$db_pass = "...";  

function database_connection() { 
    try { 
    $pdo = new PDO("mysql:host=$db_host;dbname=$db_name", $db_user, $db_pass); 
} 
catch(PDOException $e) { 
    echo $e->getMessage(); 
} 

return $pdo; 
} 

我心中唯一的真正的區別在於在這裏,pdo連接是通過函數調用完成的,而函數位於include文件vars_and_functions.php中。

這裏有什麼問題?

+0

啓用'error_reporting',它會告訴你變量在函數局部變量作用域中不可用。 – mario

+0

好吧,我意識到代碼的顯示在這裏看起來有點雜亂。我正在努力解決這個問題... – user1803765

回答

3

您的功能database_connection()未在正確的範圍內收到連接變量,因此在嘗試連接時它們未設置,因此在NULL中傳遞,並且PDO將連接主機默認爲localhost

將它們作爲參數功能:使用連接函數內部的變量

// Defined at global scope... 
$db_host = "...";  
$db_name = "...";   
$db_user = "...";  
$db_pass = "...";  

// Pass the 4 variables as parameters to the function, since they were defined at global 
// scope. 
function database_connection($db_host, $db_name, $db_user, $db_pass) { 
    try { 
    $pdo = new PDO("mysql:host=$db_host;dbname=$db_name", $db_user, $db_pass); 
} 

// Called as: 
$pdo = database_connection($db_host, $db_name, $db_user, $db_pass); 

如果你是,並不需要他們在其他地方,考慮在功能範圍定義它們,這保存您將它們作爲參數傳遞。

function database_connection() { 
    // Only needed here, so define in function scope 
    $db_host = "...";  
    $db_name = "...";   
    $db_user = "...";  
    $db_pass = "...";  

    try { 
    $pdo = new PDO("mysql:host=$db_host;dbname=$db_name", $db_user, $db_pass); 
} 

最後,往往最不理想的選擇是定義在爲你做了全球範圍內的變量,而是通過$GLOBALS[]在函數訪問它們(或global關鍵字):

function database_connection() { 
    try { 
    $pdo = new PDO("mysql:host={$GLOBALS['db_host']};dbname={$GLOBALS['db_name']}", $GLOBALS['db_user'], $GLOBALS['db_pass']); 
} 

注如果您正在開發error_reporting,並且您應該如此開發display_errors,則會看到有關未定義變量的通知。

error_reporting(E_ALL); 
ini_set('display_errors', 1); 
+0

聽起來很合理,但我不認爲這是真正的問題。如果是這樣,那麼pdo就不可能建立一個連接。我的函數有一個try和catch塊,它會在那裏失敗。但是,失敗的一點是腳本執行查詢的時間。 – user1803765

+0

@ user1803765 PDO仍會嘗試連接,而不使用這些變量 - 它會使用localhost,默認用戶和一個空密碼,並且不會像亞當所說的那樣選擇db –

+0

@ user1803765,PDO將默認爲localhost。我不記得是否可以在php.ini中以這種方式配置PDO,但MySQL和MySQLi擴展都在php.ini中都有一個默認的用戶/主機/密碼 –