2012-11-06 10 views
6

Es gibt ein kleines PDO-Problem, an dem ich seit einiger Zeit arbeite. Da ich nicht weiß, was hier falsch ist, habe ich darüber nachgedacht, es auf diese Liste zu bringen. Vielleicht wissen einige von Ihnen mehr ...php/pdo/msql - Zugriff verweigert

Ich habe eine Website mit einem Login, der einen Benutzer und ein Passwort für eine MySQL-basierte Datenbank überprüft. Wenn die PDO-Verbindung in der gleichen Datei hergestellt wird, funktioniert alles einwandfrei, man kann sich ohne Probleme einloggen. So wie es funktionieren soll ...

Wenn jedoch den Datenbankverbindungsteil an eine separate Funktion zu bewegen, die ich aus einer anderen Datei enthalten, nicht gU auf mich und gibt mir:

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

aus Gründen der Klarheit, hier ist der Code:

Version 1:

Dies funktioniert:

Hier

ist Version 2

Dies funktioniert nicht:

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

Mein Include vars_and_functions.php wie folgt aussieht:

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

Der einzige wirkliche Unterschied meiner Meinung nach ist dass hier die PDO-Verbindung über einen Funktionsaufruf hergestellt wird, während sich die Funktion in der Include-Datei vars_and_functions.php befindet.

Was ist hier falsch?

+0

Aktivieren Sie 'error_reporting', das Ihnen mitteilt, dass die Variablen im Bereich der lokalen Variablen der Funktionen nicht verfügbar sind. – mario

+0

ok Leute, mir ist klar, dass die Darstellung des Codes hier etwas unordentlich aussieht. Ich arbeite daran, dies zu korrigieren ... – user1803765

Antwort

3

Ihre Funktion database_connection() nicht empfängt die Verbindungsvariablen im richtigen Umfang, so dass sie nicht gesetzt, wenn die Verbindung versucht wird und daher als NULL und PDO defaults die Verbindung Host localhost geben.

Geben sie als Parameter an die Funktion:

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

Wenn Sie nur diese Variablen innerhalb der Verbindungsfunktion und brauchen sie nicht an anderer Stelle, sollten Sie definieren, sie in ihrem Umfang der Funktion verwendet wird, sind die Sie können sie als Parameter übergeben.

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

Die letzte und oft am wenigsten wünschenswerte Option ist es, die Variablen im globalen Bereich zu definieren, wie Sie getan haben, aber sie über $GLOBALS[] (oder das global Schlüsselwort) in der Funktion zuzugreifen:

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

Hinweis Wenn Sie mit error_reporting aktiviert und display_errors wie Sie sollten entwickeln, würden Sie Benachrichtigungen über undefinierte Variablen sehen.

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

Klingt vernünftig, aber ich denke nicht, dass dies das eigentliche Problem ist. Wenn es so wäre, wäre es für pdo nicht möglich, überhaupt eine Verbindung herzustellen. Meine Funktion hat einen Versuchs- und Catch-Block und würde genau dort scheitern. Der Punkt, an dem es jedoch fehlschlägt, ist, wenn das Skript die Abfrage ausführt. – user1803765

+0

@ user1803765 ​​PDO würde immer noch versuchen, ohne diese vars eine Verbindung herzustellen - es würde "localhost", den Standardbenutzer und ein leeres Passwort verwenden und würde keine db auswählen –

+0

@ user1803765 ​​wie adam sagte, PDO wird standardmäßig localhost verwenden. Ich kann mich nicht erinnern, ob PDO auch auf diese Weise in php.ini konfigurierbar ist, aber die Erweiterungen MySQL und MySQLi haben beide einen Standardbenutzer/host/pass in php.ini –

0

Neben Michael Berkowski Antwort, können Sie auch das Schlüsselwort global wie so passieren:

function database_connection() { 
    global $db_host, $db_name, etc; 
    // your code here 
} 

Weitere Informationen finden Sie auf den Geltungsbereich von Variablen in PHP http://php.net/manual/en/language.variables.scope.php.