php - 尝试构建一个静态数据库类,我可以从类外的任何函数访问它

标签 php mysql oop pdo

更新: 使用 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;
    }
}

这是迄今为止该类(class)的进展情况,看起来效果很好。特别感谢 Phil 的所有支持。

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

再次感谢。


原始问题

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

$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;
    }
}

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

我现在得到的错误如下。

Fatal error: Access to undeclared static property: db::$connection

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

这只是类(class)的开始,它基于我已经在使用的一组函数。

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

最佳答案

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

首先,将连接设为静态,eg

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;
}

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

public static function dbDataArray($query, $params = array()) {
    $stmt = self::getConnection()->prepare($query);
    $stmt->execute($params);
    return $stmt->fetchAll();
}

关于php - 尝试构建一个静态数据库类,我可以从类外的任何函数访问它,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18885421/

相关文章:

php - 光标是执行此操作的唯一方法吗?

php - 为虚拟数据创建批量 MySQL 插入脚本

mysql - 将数据从 HDFS 导出到 MySQL,但在进入 MySQL 之前应更新数据

objective-c - 如何在具有相同根类的两个类之间共享代码?

android - Android 中代码的可重用性

php - 使用计数还是有一个可以计数的字段?

php - 如何在www目录中创建符号链接(symbolic link)?

mysql - 通用池与 node-mysql 池

Mysql 在 600 万行表上的性能

c++ - 使用相互依赖的类是不好的做法吗?