6

有一个小 pdo 问题,我已经研究了一段时间。由于我不知道这里出了什么问题,所以我想把它放到这个列表中。也许你们中的一些人知道更多...

我有一个带有登录名的网站,可以根据 mysql 驱动的数据库检查用户和密码。当在同一个文件中建立 pdo 连接时,一切正常,可以登录,没有任何问题。就像它应该工作一样......

但是,当将数据库连接部分移动到我从另一个文件中包含的单独函数时,pdo 对我失败,并给了我:

SQLSTATE [28000] [1045] 用户'...'@'...'的访问被拒绝(使用密码:否)致命错误:在/.../中的非对象上调用成员函数prepare() .../...在第 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 */
?>

我的包含文件 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 连接是通过函数调用建立的,而函数位于包含文件 vars_and_functions.php 中。

这里有什么问题?

4

2 回答 2

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);
于 2012-11-06T17:36:38.657 回答
0

除了 Michael Berkowski 的回答之外,您还可以像这样传递 global 关键字:

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

有关 PHP 中变量作用域的更多信息,请参见http://php.net/manual/en/language.variables.scope.php

于 2012-11-06T17:41:20.830 回答