【问题标题】:PHP Select with PDO Call to a member function prepare() on a non-object errorPHP Select with PDO 在非对象错误上调用成员函数prepare()
【发布时间】:2013-08-21 16:54:38
【问题描述】:

使用 PDO 选择通过 AJAX 调用发送的数据时,我的 PHP 中出现 Call to a member function prepare() on a non-object 错误。

在 StackOverflow 上四处搜索,我找到了很多关于这个错误的答案,但没有一个可以解决我的问题。

奇怪的是,其他 PHP 文件使用相同的 PDO 调用并成功运行,但这个只给了我非对象错误。

请注意,PDO 连接与其工作的其他页面相同,所以我知道这不会导致问题。

另外,我已经测试了发送的 AJAX 数据正在被接收,并且也可以正常工作。

PHP 代码

$mysql_user = "NotTelling";
$mysql_password = "DefinatelyNotThis";
try
{
    $dbh = new PDO("mysql:host=somehost;dbname=somename", $mysql_user, $mysql_password);
    $dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

    $username = $_POST['username'];
    $inPword = $_POST['password'];
    $lat =  $_POST['lat'];
    $lon =  $_POST['lon'];

    $loggedin = "";
    $password_hash = "";
    $loggedinstatus = "";
    $pts = "";

    function getLoginInfo()
    {
        $sth = $dbh -> prepare('SELECT pword, loggedin, points FROM login WHERE uname = :uname');
        $sth->bindParam(':uname', $username, PDO::PARAM_STR);
        while($row = $sth->fetch(PDO::FETCH_ASSOC))
        {
            echo $row['pword'];
            echo $row['loggedin'];
            echo $row['points'];
        }
        $password_hash = $fetch['pword'];
        $loggedinstatus = $fetch['loggedin'];
        $pts = $fetch["points"];

        if($password_hash === null || $loggedinstatus === null || $pts === null)
        {
            die(json_encode(array("message" => "none")));
        }
        else
        {           
            return "more";
        }
    }

    function checkLoginCreds()
    {
        if(crypt($inPword, $password_hash) === $password_hash)
        {
            switch($loggedinstatus)
            {
                case  "no":         
                    $sel = $dbh->prepare("UPDATE login SET loggedin='yes' WHERE uname = ?");
                    $sel->execute(array($username));
                    return "AllGood";
                    break;

                defaut:
                    return "alreadyin";
                    break;
            }
        }
        else
        {
            return "BadLogin";
        }
    }

    if(getLoginInfo() === "more")
    {
        echo json_encode(array("message" => checkLoginCreds()));
    }

    getLoginInfo();
}
catch(PDOException $e)
{
    echo $e->getMessage();
    file_put_contents('PDOErrors.txt', $e->getMessage(), FILE_APPEND);
}

最后,这是我var_dump() PDO 连接时的输出。

object(PDO)#1 (0) {}

【问题讨论】:

  • $dbh 未在您的函数中定义。
  • 修正了@andrewsi 的格式
  • 你应该在一个类中定义整个东西,或者在每个需要数据库连接的函数中连接到数据库..
  • @copilot0910 - 仍然不能解决问题。 $dbh 超出范围 - 要么将其作为参数传递给函数,要么将其声明为全局。
  • @blo 我已经看到了类方法,但不知道该怎么做。另外,为什么它在这个文件中不起作用,而在所有其他文件中都起作用?

标签: php mysql database pdo prepared-statement


【解决方案1】:

为此,您需要使用全局变量范围,此处解释:http://php.net/manual/en/language.variables.scope.php

$mysql_user = "NotTelling";
$mysql_password = "DefinatelyNotThis";
try
{
    $dbh = new PDO("mysql:host=somehost;dbname=somename", $mysql_user, $mysql_password);
    $dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

    $username = $_POST['username'];
    $inPword = $_POST['password'];
    $lat =  $_POST['lat'];
    $lon =  $_POST['lon'];

    $loggedin = "";
    $password_hash = "";
    $loggedinstatus = "";
    $pts = "";

    function getLoginInfo()
    {
        global $dbh, $username, $password_hash, $loggedinstatus, $pts;

        $sth = $dbh -> prepare('SELECT pword, loggedin, points FROM login WHERE uname = :uname');
        $sth->bindParam(':uname', $username, PDO::PARAM_STR);
        while($row = $sth->fetch(PDO::FETCH_ASSOC))
        {
            echo $row['pword'];
            echo $row['loggedin'];
            echo $row['points'];
        }
        $password_hash = $fetch['pword'];
        $loggedinstatus = $fetch['loggedin'];
        $pts = $fetch["points"];

        if($password_hash === null || $loggedinstatus === null || $pts === null)
        {
            die(json_encode(array("message" => "none")));
        }
        else
        {           
            return "more";
        }
    }

    function checkLoginCreds()
    {
        global $dbh, $inPword, $password_hash, $loggedinstatus, $username;

        if(crypt($inPword, $password_hash) === $password_hash)
        {
            switch($loggedinstatus)
            {
                case  "no":         
                    $sel = $dbh->prepare("UPDATE login SET loggedin='yes' WHERE uname = ?");
                    $sel->execute(array($username));
                    return "AllGood";
                    break;

                defaut:
                    return "alreadyin";
                    break;
            }
        }
        else
        {
            return "BadLogin";
        }
    }

    if(getLoginInfo() === "more")
    {
        echo json_encode(array("message" => checkLoginCreds()));
    }

    getLoginInfo();
}
catch(PDOException $e)
{
    echo $e->getMessage();
    file_put_contents('PDOErrors.txt', $e->getMessage(), FILE_APPEND);
}

但这很快就会变得一团糟。

我建议您将变量放在数组中或使用 OOP 以获得更强大的解决方案:http://php.net/manual/en/language.oop5.php

【讨论】:

    【解决方案2】:

    这是你可以在一个类中定义它的方式..

    class someClass {
    
      private $db;
    
      public function __construct(){
    
    
                $this->dbconnect();
    
        }
    
        private function dbconnect() {
    
          try { //try connection
    
            $dbh = new PDO('mysql:host=localhost;dbname=somenane', 'usernane', 'pass');
    
            $dbh->setAttribute(PDO::ATTR_EMULATE_PREPARES, false); 
            $dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
    
            $this->dbh = $dbh;
    
          } catch (Exception $e) { //connection failed
    
            die("Oh no! It seems we took too long to respond");
    
          }
    
        }
    
        public function getLoginInfo() { 
    
          $sth = $this->dbh->prepare('SELECT pword, loggedin, points FROM login WHERE uname = :uname'); 
          $sth->bindParam(':uname', $username, PDO::PARAM_STR); 
    
          //cont the code
    
        }
    
    }
    

    不确定它是否足够好..但它会起作用..

    【讨论】:

    • 每个类中的连接都和每个函数中的一样糟糕。
    • @YourCommonSense 如果您有“正确”的解决方案,为什么不直接分享呢?等等,你不要,因为有很多方法可以解决这个问题。
    • 他的所有功能都需要连接,有什么害处?
    • 以及所有课程。它们必须共享一个连接,而不是创建自己的连接。这将导致与它们拥有的对象一样多的连接。
    • 只需使其成为function __construct($db){ $this->db = $db;},然后实例化这个类,传递已经创建的 $db 像这样$obj = new someClass($db); 这将使所有对象使用单个连接,而不是创建新的对象(这会杀死你的数据库服务器很快)。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-12-30
    • 1970-01-01
    • 1970-01-01
    • 2017-07-31
    相关资源
    最近更新 更多