PDO和php - 在非对象上调用成员函数prepare()

时间:2023-01-21 19:22:40

I started learning PDO and im still a bit of a PHP novice. Im doing a project to increase my knowledge but im stuck at the first hurdle.

我开始学习PDO,我仍然是一个PHP新手。我做了一个项目来增加我的知识,但我陷入了第一个障碍。

Im getting this error: Call to a member function prepare() on a non-object on line 37 of this code. This is from database.class.php

我收到此错误:在此代码的第37行上的非对象上调用成员函数prepare()。这是来自database.class.php

<?php// Include database classinclude 'config.php';class Database{private $host      = DB_HOST;private $user      = DB_USER;private $pass      = DB_PASS;private $dbname    = DB_NAME;private $dbh;private $error;public function __construct(){    // Set DSN    $dsn = 'mysql:host=' . $this->host . ';dbname=' . $this->dbname;    // Set options    $options = array(        PDO::ATTR_PERSISTENT    => true,        PDO::ATTR_ERRMODE       => PDO::ERRMODE_EXCEPTION    );    // Create a new PDO instanace    try{        $this->dbh = new PDO($dsn, $this->user, $this->pass, $options);    }    // Catch any errors    catch(PDOException $e){        $this->error = $e->getMessage();    }}// this variable holds the temporary statementprivate $stmt;// prepare our values to avoid SQL injectionpublic function query($query){    $this->stmt = $this->dbh->prepare($query);}// use switch to select the appropiate type for the value been passed// $param = placeholder name e.g username, $value = myusernamepublic function bind($param, $value, $type = null){    if (is_null($type)) {        switch (true) {            case is_int($value):                $type = PDO::PARAM_INT;                break;            case is_bool($value):                $type = PDO::PARAM_BOOL;                break;            case is_null($value):                $type = PDO::PARAM_NULL;                break;            default:                $type = PDO::PARAM_STR;        }    }// run the binding process$this->stmt->bindValue($param, $value, $type);}// execute the prepared statementpublic function execute(){    return $this->stmt->execute();}// returns an array of the results, first we execute and then fetch the resultspublic function resultset(){    $this->execute();    return $this->stmt->fetchAll(PDO::FETCH_ASSOC);}// same as resultset() except this returns a single resultpublic function result_single(){    $this->execute();    return $this->stmt->fetch(PDO::FETCH_ASSOC);}// count the number of rows from the previous delete, update or insert statementpublic function rowCount(){    return $this->stmt->rowCount();}// last insert id return the last id of the insert made, useful if you need to run a further// query on the row you just inserted and need the id as the referencepublic function lastInsertId(){    return $this->dbh->lastInsertId();}// transactions allow you to rollback if a set of queries fail but it also allows ensures// we avoid errors due to users interaction while half of the queries are still being written// the following code begins a transactionpublic function beginTransaction(){    return $this->dbh->beginTransaction();}// end a transactionpublic function endTransaction(){    return $this->dbh->commit();}// rollback a transactionpublic function cancelTransaction(){    return $this->dbh->rollBack();}// this dumps the PDO information from the prepared statement for debug purposespublic function debugDumpParams(){    return $this->stmt->debugDumpParams();}}?>

Now the initial page im running this code in index.php

现在初始页面我在index.php中运行此代码

<?php// Include database connection classinclude 'includes/database.class.php';include 'includes/bug.class.php';$database = new Database;$bugs = new Bugs;$bugs->find_all_rows();echo "<pre>";print_r($rows);echo "</pre>";echo "Number of rows: " . $bugs->rowCount() . "<br />";?>

And this is the page it would be running the find_all_rows function on which is the bugs.class.php file

这是运行find_all_rows函数的页面,其中是bugs.class.php文件

<?phpclass Bugs {    public function find_all_rows() {      return self::find_by_sql('SELECT * FROM tbl_priority');       }    public function find_by_sql($sql="") {      global $database;      $database->query($sql);      $rows = $database->resultset();      return $rows;    }}?>

Is there a debug tool that will help me trace these type of errors better or is it just a case im not familiar enough with PDO to spot an obvious mistake?

是否有一个调试工具可以帮助我更好地跟踪这些类型的错误,还是只是一个我不熟悉PDO的案例来发现一个明显的错误?

2 个解决方案

#1


2  

@papaja hit the nail right on the head. Your PDO connection failed, thus you do not have a PDO object to run the prepare method on.

@papaja正好击中了头部。您的PDO连接失败,因此您没有PDO对象来运行prepare方法。

Off the top of my head, I think you are missing the end quote on the $dsn string. You probably want to add the following after $this->dbname and before the semi-colon:

在我的脑海中,我认为你错过了$ dsn字符串的最终引用。你可能想在$ this-> dbname之后和分号之前添加以下内容:

. "'"

That's a single quote wrapped in double quotes. I use the following syntax to create the DSN string:

这是用双引号括起来的单引号。我使用以下语法来创建DSN字符串:

"mysql:host=$this->HOST;dbname=$this->DATABASE"

Anyway, create a test file so that you know exactly what the problem is. The test file should look like this:

无论如何,创建一个测试文件,以便您确切地知道问题是什么。测试文件应如下所示:

class TestDatabase{    private $host      = DB_HOST;    private $user      = DB_USER;    private $pass      = DB_PASS;    private $dbname    = DB_NAME;    private $dbh;    public function __construct(){        $dsn = 'mysql:host=' . $this->host . ';dbname=' . $this->dbname;        $options = array(            PDO::ATTR_PERSISTENT    => true,            PDO::ATTR_ERRMODE       => PDO::ERRMODE_EXCEPTION        );        $this->dbh = new PDO($dsn, $this->user, $this->pass, $options);    }}

Note that we are not running the instantiation of the PDO object within a try catch block. While you would never ever do that in production, it will be useful for your test because it will throw a fatal exception containing all of the details of your connection.

请注意,我们没有在try catch块中运行PDO对象的实例化。虽然你永远不会在生产中这样做,但它对你的测试很有用,因为它会抛出包含连接所有细节的致命异常。

Now instantiate the test class and proceed by debugging the errors you receive. Again, they will be more detailed than the previous error because it will be an uncaught PDO exception.

现在实例化测试类并继续调试您收到的错误。同样,它们将比之前的错误更详细,因为它将是未被捕获的PDO异常。

#2


0  

Get same error and couldn't fix with code written above.

得到相同的错误,无法修复上面写的代码。

Here is easy fix as in your code this is the problem why PDO Sending Error :

这里很容易修复,因为在你的代码中这是PDO发送错误的原因:

public function __construct(){    // Set DSN    $dsn = 'mysql:host=' . $this->host . ';dbname=' . $this->dbname;    // Set options    $options = array(        PDO::ATTR_PERSISTENT    => true,        PDO::ATTR_ERRMODE       => PDO::ERRMODE_EXCEPTION    );    // Create a new PDO instanace    try{        $this->dbh = new PDO($dsn, $this->user, $this->pass, $options);    }    // Catch any errors    catch(PDOException $e){        $this->error = $e->getMessage();    }}

I am using PHP 5.5 and if someone have same error then he will need this

我使用PHP 5.5,如果有人有相同的错误,那么他将需要这个

After $dns you need to add this where $this->dbname . ";";

在$ dns之后你需要在$ this-> dbname中添加它。 “;”;

Only this is how it will work for PHP 5.5 and Will not work with $this->dbname . "'";

只有这样它才能用于PHP 5.5,并且无法使用$ this-> dbname。 “'”;

public function __construct(){    // Set DSN    $dsn = 'mysql:host=' . $this->host . ';dbname=' . $this->dbname . ";";    // Set options    $options = array(        PDO::ATTR_PERSISTENT    => true,        PDO::ATTR_ERRMODE       => PDO::ERRMODE_EXCEPTION    );    // Create a new PDO instanace    try{        $this->dbh = new PDO($dsn, $this->user, $this->pass, $options);    }    // Catch any errors    catch(PDOException $e){        $this->error = $e->getMessage();    }}

#1


2  

@papaja hit the nail right on the head. Your PDO connection failed, thus you do not have a PDO object to run the prepare method on.

@papaja正好击中了头部。您的PDO连接失败,因此您没有PDO对象来运行prepare方法。

Off the top of my head, I think you are missing the end quote on the $dsn string. You probably want to add the following after $this->dbname and before the semi-colon:

在我的脑海中,我认为你错过了$ dsn字符串的最终引用。你可能想在$ this-> dbname之后和分号之前添加以下内容:

. "'"

That's a single quote wrapped in double quotes. I use the following syntax to create the DSN string:

这是用双引号括起来的单引号。我使用以下语法来创建DSN字符串:

"mysql:host=$this->HOST;dbname=$this->DATABASE"

Anyway, create a test file so that you know exactly what the problem is. The test file should look like this:

无论如何,创建一个测试文件,以便您确切地知道问题是什么。测试文件应如下所示:

class TestDatabase{    private $host      = DB_HOST;    private $user      = DB_USER;    private $pass      = DB_PASS;    private $dbname    = DB_NAME;    private $dbh;    public function __construct(){        $dsn = 'mysql:host=' . $this->host . ';dbname=' . $this->dbname;        $options = array(            PDO::ATTR_PERSISTENT    => true,            PDO::ATTR_ERRMODE       => PDO::ERRMODE_EXCEPTION        );        $this->dbh = new PDO($dsn, $this->user, $this->pass, $options);    }}

Note that we are not running the instantiation of the PDO object within a try catch block. While you would never ever do that in production, it will be useful for your test because it will throw a fatal exception containing all of the details of your connection.

请注意,我们没有在try catch块中运行PDO对象的实例化。虽然你永远不会在生产中这样做,但它对你的测试很有用,因为它会抛出包含连接所有细节的致命异常。

Now instantiate the test class and proceed by debugging the errors you receive. Again, they will be more detailed than the previous error because it will be an uncaught PDO exception.

现在实例化测试类并继续调试您收到的错误。同样,它们将比之前的错误更详细,因为它将是未被捕获的PDO异常。

#2


0  

Get same error and couldn't fix with code written above.

得到相同的错误,无法修复上面写的代码。

Here is easy fix as in your code this is the problem why PDO Sending Error :

这里很容易修复,因为在你的代码中这是PDO发送错误的原因:

public function __construct(){    // Set DSN    $dsn = 'mysql:host=' . $this->host . ';dbname=' . $this->dbname;    // Set options    $options = array(        PDO::ATTR_PERSISTENT    => true,        PDO::ATTR_ERRMODE       => PDO::ERRMODE_EXCEPTION    );    // Create a new PDO instanace    try{        $this->dbh = new PDO($dsn, $this->user, $this->pass, $options);    }    // Catch any errors    catch(PDOException $e){        $this->error = $e->getMessage();    }}

I am using PHP 5.5 and if someone have same error then he will need this

我使用PHP 5.5,如果有人有相同的错误,那么他将需要这个

After $dns you need to add this where $this->dbname . ";";

在$ dns之后你需要在$ this-> dbname中添加它。 “;”;

Only this is how it will work for PHP 5.5 and Will not work with $this->dbname . "'";

只有这样它才能用于PHP 5.5,并且无法使用$ this-> dbname。 “'”;

public function __construct(){    // Set DSN    $dsn = 'mysql:host=' . $this->host . ';dbname=' . $this->dbname . ";";    // Set options    $options = array(        PDO::ATTR_PERSISTENT    => true,        PDO::ATTR_ERRMODE       => PDO::ERRMODE_EXCEPTION    );    // Create a new PDO instanace    try{        $this->dbh = new PDO($dsn, $this->user, $this->pass, $options);    }    // Catch any errors    catch(PDOException $e){        $this->error = $e->getMessage();    }}