2012-11-06 15 views
6

Istnieje mały problem pdo, nad którym pracuję od dłuższego czasu. Ponieważ nie wiem, co tu jest nie tak, pomyślałem o zabraniu go na tę listę. Może niektórzy z was wiedzą więcej ...php/pdo/msql - odmowa dostępu

Mam stronę internetową z loginem, który sprawdza użytkownika i hasło do bazy danych obsługiwanej przez mysql. Gdy połączenie pdo jest wykonane w tym samym pliku, wszystko działa poprawnie, można się zalogować, bez żadnych problemów. Podobnie jak to ma działać ...

Jednak podczas przesuwania części połączenia bazy danych do funkcji indywidualne, które obejmują od innego pliku, pdo nie działa na mnie i daje mi:

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

dla jasności, oto kod:

Wersja 1:

to działa:

<?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 */ 
?> 

Oto wersja 2

To nie działa:

<?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 */ 
?> 

Moja includefile vars_and_functions.php wygląda następująco:

$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; 
} 

Jedyną różnicą jest moim zdaniem tutaj połączenie pdo jest wykonywane przez wywołanie funkcji, podczas gdy funkcja znajduje się w pliku włączającym vars_and_functions.php.

Co jest nie tak?

+0

Włącz 'error_reporting', który powie ci, że zmienne nie są dostępne w zasięgu funkcji zmiennej lokalnej. – mario

+0

W porządku, zdaję sobie sprawę, że prezentacja kodu wygląda tu trochę niechlujnie. Pracuję nad poprawieniem ... – user1803765

Odpowiedz

3

Twoja funkcja nie otrzymuje zmiennych połączenia w poprawnym zakresie, więc nie są one ustawiane podczas próby połączenia i dlatego są przekazywane jako NULL, a PDO domyślnie przyjmuje host połączenia do localhost.

przekazać je jako parametry do funkcji:

// 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); 

Jeśli jesteś tylko użyciem tych zmiennych wewnątrz funkcji zasilania i nie trzeba ich gdzie indziej, należy rozważyć zdefiniowanie ich w zakres funkcji, które zapisuje je jako parametry.

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); 
} 

opcja ostateczna i często najmniej pożądane jest określenie zmiennych w zasięgu globalnym, jak masz zrobić, ale dostęp do nich poprzez $GLOBALS[] (lub słowo kluczowe global) w funkcji:

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

Note że jeśli pracujesz z włączonym error_reporting i display_errors, powinieneś zobaczyć powiadomienia o niezdefiniowanych zmiennych.

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

Brzmi rozsądnie, ale nie sądzę, że to jest prawdziwy problem. Jeśli tak, to nie byłoby możliwe, aby pdo ustanowiło połączenie w pierwszej kolejności. Moja funkcja ma blok wypróbowania i catch, a to się nie powiedzie. Jednak punktem, w którym nie działa, jest wykonanie skryptu. – user1803765

+0

@ user1803765 ​​CHNP nadal próbowałby połączyć się bez tych vars - użyłoby 'localhost', domyślnego użytkownika i pustego hasła i nie wybrałoby db –

+0

@ user1803765 ​​jak powiedział adam, PDO będzie domyślnie localhost. Nie pamiętam, czy PDO jest konfigurowalny w ten sposób również w php.ini, ale rozszerzenia MySQL i MySQLi mają domyślny użytkownik/host/pass w php.ini –