这个PDO代码有什么问题?

时间:2011-03-07 10:12:56

标签: php pdo

我创建了一个文件名database.php,这是它的内容

<?php
#Start Session
session_start();
#Start Output Buffering
ob_start();
#Set Default TimeZone
date_default_timezone_set('Asia/Kolkata');

#Define Connection Constant
define('HOST','localhost');
define('USERNAME','user');
define('PASSWORD','pass');
define('DATABASE','database');
//Define Configuration Constant
define('DATE', date("d-F-Y/H:ia"));

#Connect to the database
try
{
    #Define Connection String Using PDO.
    $DBH = new PDO('mysql:host='.HOST.';dbname='.DATABASE,USERNAME,PASSWORD);

    #Set Error Mode to ERRMODE_EXCEPTION.
    $DBH->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
}
catch(PDOException $e)
{
    echo $e->getMessage();
    //Log Errors into a file
    file_put_contents("resources/logs/Connection-log.txt", DATE.PHP_EOL.$e->getMessage().PHP_EOL.PHP_EOL, FILE_APPEND);
}
?>

现在我已经定义了一个PHP的类,我已经声明了一个方法,我希望根据上面的连接获取一些值。我已经包含了database.php文件。

这是我的代码。

include('../../config/database.php');
class Property
{
    public function getAllCountries()
    {
        #Query Using Prepared Statement
        $STH = $DBH->query('SELECT * FROM countries');

        #Set the Fetch Mode
        $STH->setFetchMode(PDO::FETCH_ASSOC);

        $countries = array();
        while($row = $STH->fetch())
        {
            $countries[] = $row['name'];
            return $countries;
        }
    }
}
$property = new Property;
echo $property->getAllCountries();

当我初始化课程时它没有任何问题,但是当我尝试调用$ property-&gt; getAllCountries();它给了我以下错误。

Notice: Undefined variable: DBH in /Applications/MAMP/htdocs/kokaris/administrator/resources/library/models/class.property.php on line 8

Fatal error: Call to a member function query() on a non-object in /Applications/MAMP/htdocs/kokaris/administrator/resources/library/models/class.property.php on line 8

我的代码出了什么问题?

2 个答案:

答案 0 :(得分:3)

问题是$DBH在通话$DBH->query()时不在范围内。 $DBH位于全局范围内,而调用位于函数范围内(getAllCountries)。与其他一些语言不同,全局变量在函数中是不可访问的,除非您明确声明它们。

这方面的一行解决方法是在函数中使用$DBH的全局值:

public function getAllCountries()
{
    global $DBH;

    #Query Using Prepared Statement
    $STH = $DBH->query('SELECT * FROM countries');

然而,这可能是一个坏主意,因为您现在已经锁定了处理数据库连接的特定方式。最好将数据库对象作为参数传递给构造函数,将其存储在对象变量中,并在需要使用它时检索它。

class Property
{
    protected $dbh;

    public function __construct($dbh) {
        $this->dbh = $dbh;
    }

    public function getAllCountries() {
        $STH = $this->dbh->query('SELECT * FROM countries');

        [snip]
    }    
}

然后,您需要使用作为参数传递的DB对象初始化您的类:

$property = new Property($DBH);
echo $property->getAllCountries();

答案 1 :(得分:2)

尝试将句柄传递给类的构造函数中的dbh,并仅为全局变量和常量保留大写变量名称...避免在类中使用全局变量...

第二期:退出循环之外的国家/地区!

class Property
{

    protected $dbh;

    public function __construct($dbhandle) {
      $this->dbh = $dbhandle;
    }


    public function getAllCountries()
    {
        #Query Using Prepared Statement
        $sth = $this->dbh->query('SELECT * FROM countries');

        #Set the Fetch Mode
        $sth->setFetchMode(PDO::FETCH_ASSOC);

        $countries = array();
        while($row = $sth->fetch())
        {
            $countries[] = $row['name'];
        }

        // !! return goes here!
        return $countries;
    }
}

$property = new Property($DBH);
echo $property->getAllCountries();