1

更新: 使用 PDO 而不是弃用的方法将代码更改为现在工作的类代码

原来的问题得到了回答,问题就解决了。Phil 从小就使用PDO而不是传统的 SQL,所以看到这个类还处于起步阶段,我决定开始迁移过程。

class db
{
    private static $connection;
    const __DB__HOST__      = __DB__HOST__;
    const __DB_USERNAME__   = __DB_USERNAME__;
    const __DB_PASSWORD__   = __DB_PASSWORD__;
    const __DB_NAME__       = __DB_NAME__;


    private static function getConnection() {
        if (self::$connection === null) {

            $dsn = sprintf("mysql:dbname=".__DB_NAME__.";host=".__DB_HOST__, __DB_USERNAME__, __DB_PASSWORD__,"charset=utf8" );

            self::$connection = new PDO($dsn, self::__DB_USERNAME__, self::__DB_PASSWORD__, array(
                PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
                PDO::ATTR_EMULATE_PREPARES => false,
                PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC
            ));
        }
        return self::$connection;
     }

    //Make the query
    private static function dbQuery($sql_string) {

        $conn = self::getConnection();

        $sth = $conn->prepare($sql_string);
        $sth->execute();

        return $sth;
    }

    //Return all results from sqlquery in array
    public static function dbDataArray($sql_string){

        $data = self::dbQuery($sql_string)->fetchAll();

        return $data;
    }

    public static function Value($sql_string){

        $data = self::dbQuery($sql_string)->fetchColumn();

        return $data;
    }
}

到目前为止,这是该课程的进展,并且似乎工作得很好。特别感谢菲尔的所有支持。

欢迎任何其他建议,我们将不胜感激。

再次感谢。


原始问题

基本上我正在尝试构建一个可以使用以下语法的数据库访问类

$test = db::dbDataArray("SELECT * FROM fw_settings");

如果连接不存在,该类将创建连接,因此我可以随时从该类调用方法,而无需创建新实例。

到目前为止,这是我对具有单一功能的结构所拥有的。一旦我可以让状态类处理单个查询项,我将添加所有其他功能。

class db
{
    public $connection;
    const __DB__HOST__      = __DB__HOST__;
    const __DB_USERNAME__   = __DB_USERNAME__;
    const __DB_PASSWORD__   = __DB_PASSWORD__;
    const __DB_NAME__       = __DB_NAME__;

    function __construct() {

        if (self::$connection == null){

             self::$connection = mysql_connect(__DB_HOST__,__DB_USERNAME__,__DB_PASSWORD__)
                or die('Unable to Connect to SQL Host'.__DB_HOST__);
             @mysql_select_db(__DB_NAME__)
                or die('Unable to Select DB: '.__DB_NAME__);
        }
    }

    //Regular SQL query such as delete, update, etc.
    public static function dbQuery($sql_string) {

        //Handle the rest of the SQL query here
        if (!$sqlResult = mysql_query($sql_string, self::$connection) ){
            //Let's output the MySQL error if we have one
            die('
                <div style="border:1px solid red;color:red;background:yellow;">
                    <p>'.$sql_string.'</p>
                    SQL Error:'. mysql_error(self::$connection).'
                </div>'
            );

        }
        else {
            //Return the sql result
            if (strpos($sql_string, "DELETE")){
                if (mysql_affected_rows($sqlResult) > 0){
                    return $sqlResult;
                }
                else{
                    return false;
                }
            }
            else{
                return $sqlResult;
            }
        }
    }

    //Return all results from sqlquery in array
    public static function dbDataArray($sql_string){

        $data = array();
        $dataQuery = self::dbQuery($sql_string);
        $i = 1;

        while(($row = mysql_fetch_assoc($dataQuery)) !== false){
            foreach($row AS $key=>$val){
                $data[$i][$key] = $val;
            }
            $i++;
        }
        return $data;
    }
}

常量在类之前加载的另一个文件中定义,因此它们将存在。

我现在得到的错误如下。

致命错误:访问未声明的静态属性:db::$connection

看起来它正在使连接正常。我只是无法使用 dbQuery 函数访问连接。dbQuery 函数用于所有其他函数。

这只是课程的开始,它基于我已经使用的一组函数。

一旦它工作,最终目标是能够将数据库名称传递给类并在该特定实例中访问该数据库,因此我可以在我计划使用它的项目中使用多个数据库。

4

1 回答 1

3

为了让你的类静态运行,你需要做一些事情。

首先,使连接静态,例如

private static $connection;

其次,为什么都是下划线?

define('DB_HOST', 'localhost');
define('DB_NAME', 'your_db_name');
define('DB_USER', 'username');
define('DB_PASS', 'password');

另外,为什么要使用类常量呢?只需使用您已经定义的常量。

第三,失去构造函数。您不能期望创建此类的实例静态使用它。我会为连接采用延迟加载方法

private static function getConnection() {
    if (self::$connection === null) {
        $dsn = sprintf('mysql:host=%s;dbname=%s;charset=utf8',
            DB_HOST, DB_NAME);

        self::$connection = new PDO($dsn, DB_USER, DB_PASS, array(
            PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
            PDO::ATTR_EMULATE_PREPARES => false,
            PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC
        ));
    }
    return self::$connection;
}

然后,您的公共方法将在内部调用此方法。我还将充实您的dbDataArray方法,向您展示如何返回关联数组

public static function dbDataArray($query, $params = array()) {
    $stmt = self::getConnection()->prepare($query);
    $stmt->execute($params);
    return $stmt->fetchAll();
}
于 2013-09-19T02:52:09.047 回答