我希望能够创建扩展MySQLi类的类来执行所有SQL查询。

$mysql = new mysqli('localhost', 'root', 'password', 'database') or die('error connecting to the database');

我不知道如何在没有全局化$ mysql对象的情况下执行此操作,以便在我的其他方法或类中使用。

class Blog {

public function comment() {
    global $mysql;

    //rest here
}

}

任何帮助都将不胜感激。

感谢。

有帮助吗?

解决方案

My suggestion is to create a Singleton DataAccess class, instantiate that class in a global config file and call it in your Blog class like $query = DataAccess::query("SELECT * FROM blog WHERE id = ".$id).

Look into the Singleton pattern, it's a pretty easy to understand designpattern. Perfect for this situation.

Your DataAccess class can have several methods like query, fetchAssoc, numRows, checkUniqueValue, transactionStart, transactionCommit, transactionRollback etc etc. Those function could also be setup as an Interface which gets implemented by the DataAccess class. That way you can easily extend your DataAccess class for multiple database management systems.

The above pretty much describes my DataAccess model.

其他提示

I was working on something similar. I'm happy about this singleton class that encapsulates the database login.

<?php
class db extends mysqli
{
    protected static $instance;
    protected static $options = array();

    private function __construct() {
        $o = self::$options;

        // turn of error reporting
        mysqli_report(MYSQLI_REPORT_OFF);

        // connect to database
        @parent::__construct(isset($o['host'])   ? $o['host']   : 'localhost',
                             isset($o['user'])   ? $o['user']   : 'root',
                             isset($o['pass'])   ? $o['pass']   : '',
                             isset($o['dbname']) ? $o['dbname'] : 'world',
                             isset($o['port'])   ? $o['port']   : 3306,
                             isset($o['sock'])   ? $o['sock']   : false );

        // check if a connection established
        if( mysqli_connect_errno() ) {
            throw new exception(mysqli_connect_error(), mysqli_connect_errno()); 
        }
    }

    public static function getInstance() {
        if( !self::$instance ) {
            self::$instance = new self(); 
        }
        return self::$instance;
    }

    public static function setOptions( array $opt ) {
        self::$options = array_merge(self::$options, $opt);
    }

    public function query($query) {
        if( !$this->real_query($query) ) {
            throw new exception( $this->error, $this->errno );
        }

        $result = new mysqli_result($this);
        return $result;
    }

    public function prepare($query) {
        $stmt = new mysqli_stmt($this, $query);
        return $stmt;
    }    
}

To use you can have something like this:

<?php
require "db.class.php";

$sql = db::getInstance();

$result = $sql->query("select * from city");

/* Fetch the results of the query */ 
while( $row = $result->fetch_assoc() ){ 
    printf("%s (%s)\n", $row['Name'], $row['Population']); 
} 
?>

You can use PHP's extends keyword just for any other class:

class MyCustomSql extends mysqli {

    public function __construct($host, $user, $password, $database) {
        parent::__construct($host, $user, $password, $database);
    }

    public function someOtherMethod() {
    }
}

$sql = new MyCustomSql('localhost', 'root', 'password', 'database') or die('Cannot connect!');

or better use object aggregation instead of inheritance:

class MySqlManipulator {

    private $db;

    public function __construct($host, $user, $password, $database) {
        $this->db   = new mysqli($host, $user, $password, $database);
    }

    public function someOtherMethod() {
        return $this->db->query("SELECT * FROM blah_blah");
    }
}

$mysqlmanipulator = new MySqlManipulator('localhost', 'root', 'password', 'database') or die('Cannot connect!');

My standard method is to make a singleton class that acts as the database accessor, and a base class that everything requiring such access inherits from.

So:

class Base {

  protected $db;

  function __construct(){
    $this->db= MyDBSingleton::get_link();
    //any other "global" vars you might want 
  }

}


class myClass extends Base {

  function __construct($var) {
     parent::__construct();// runs Base constructor
     $this->init($var);
  }

  function init($id) {
    $id=(int) $id;
    $this->db->query("SELECT * FROM mytable WHERE id=$id");
    //etc.
  }
}

Have a look at PDO, which throw exceptions for you to catch if a query fails. It's widely used and tested so you shouldn't have a problem finding existing solutions whilst using it.

To inject it into your blog class:

class Blog {

    private $_db;

    public function __construct(PDO $db) {
        $this->_db = $db
    }

    public function comment() {
        return $this->_db->query(/*something*/);
    }

}
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top