如何使用从一个 class 到另一个的连接

How to use connection from one class into another

class Database {

    public $isConn;
    private static $_instance = null;
    private $datab;

    // connect to db
    public function __construct($username = "root", $password = "", $host = "localhost", $dbname = "market", $options = []) {
        $this->isConn = TRUE;
        try {
            $this->datab = new PDO("mysql:host={$host};dbname={$dbname};charset=utf8", $username, $password, $options);
            $this->datab->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
            $this->datab->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC);
        } catch (PDOException $e) {
            throw new Exception($e->getMessage());
        }
    }

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

现在每个 class 需要数据库连接

class test {

    private $_db = null;

    public function __construct() {
        $this->_db = Database::getInstance();
    }

    public function test(){
       return $this->_db->getRow("SELECT * FROM users", PDO::FETCH_ASSOC, []);
    }

   public static function testStatic(){
        return $this->_db->getRow("SELECT * FROM users", PDO::FETCH_ASSOC, []);
        }

现在它给我一个错误说不能使用 $this,那么我如何使用 self:: 来使用它? }

现在如何在静态函数和非静态函数中一起使用它

我在我的应用程序中已经这样做了很长时间。虽然是的,对所选数据库驱动程序的调用确实也是简单的函数 - 它们是具有大量所需参数(登录/数据库信息/等)的函数,这些参数非常重复...

我正在使用 sqlsrv - 但可以根据您的需要修改相同的技术

db.class.php:

class db{
    private static $_server='my.database.server';
    private static $_config=[ 
                  'UID'                  => 'username',
                  'PWD'                  => 'password',
                  'Database'             => 'myDatabase',
                  'CharacterSet'         => 'UTF-8',
                  'ApplicationIntent'    => 'ReadWrite',
                  'TransactionIsolation' => SQLSRV_TXN_READ_COMMITTED,
                  'APP'                  => 'MyWebApplication",
                  'ConnectionPooling'    => 1,
                  'LoginTimeout'         => 60,
                  'ReturnDatesAsStrings' => 0,
                  'WSID'                 => 'MyWebServer'
              ];

    public static function getDatabaseHandle(){
      return sqlsrv_connect(self::$_server, self::$_config);
    }
}

然后在我需要数据库句柄的任何地方: somefile.php:

$db = db::getDatabaseHandle();

$myQuery = sqlsrv_query($db, $tsql, $params);
...

请注意,这几乎可以在您的应用程序中的任何地方 - 在另一个函数中或在另一个 class 中 - 只要您通过正确地赋予 db.class.php 文件可见性就真的没关系静态包含或最好是 an autoloading function

... 或从 class 中作为您的示例:

class Register {

private static $_db;
public static function checkUserName(){
    if(!self::$_db){
        self::$_db = \db::getDatabaseHandle();
    }
    /**
     * Do database stuff with self::$_db as your database handle
     */

}

我喜欢@WOLFF 的直截了当的回答,但我想帮助解释你得到的错误,以便你以后在类似情况下理解。

http://php.net/manual/en/language.oop5.basic.php 说:

The pseudo-variable $this is available when a method is called from within an object context. $this is a reference to the calling object.

但是您正试图在静态函数中使用 $this,因此没有对调用对象的引用。因此伪变量 $this 未定义。

因为你不能在静态方法中使用$this,所以你不能使用任何对象属性,比如你的私有$this->_db。您只能在静态方法中使用静态 class 属性。

PHP 没有任何方法可以自动初始化 class 的静态属性。唯一的方法是在尝试使用任何其他静态方法之前调用 class 的静态初始化方法。

class test {

    private static $_staticDb = null;
    private $_db = null;

    public static function init() {
        self::$_staticDb = Database::getInstance();
    }

    public function __construct() {
        $this->_db = Database::getInstance();
    }

    public function test(){
       return $this->_db->getRow("SELECT * FROM users", PDO::FETCH_ASSOC, []);
    }

   public static function testStatic(){
        return self::$_staticDb->getRow("SELECT * FROM users", PDO::FETCH_ASSOC, []);
    }

}

test::init();
print_r(test::testStatic());

$test = new test();
print_r($test->test());

我在上面的示例中显示的 init() 静态方法没有什么神奇之处。您可以随意命名该方法。在使用依赖于它初始化的东西的其他静态方法之前,你只需要记住自己调用它。

那么为什么 PHP 没有任何神奇的方法来初始化 class?有一个草案建议将静态 class "constructor" 添加到 PHP,但它仍然只是草案。它尚未在 PHP 的任何已发布版本中实现。无法知道何时或是否会实施。

https://wiki.php.net/rfc/static_class_constructor


PS:FWIW,Python 和 Java 是具有静态 class 初始化功能的语言示例。

请参见本题中 Python 中的示例:Pythonic Way to Initialize (Complex) Static Data Members

请参阅此问题中 Java 中的示例:static variable initialization java

我知道您使用的是 PHP 而不是其他语言,我只是指出这样的事情是可能的。

在需要时获取数据库实例。

class test {

    public function test(){
       return Database::getInstance()->getRow("SELECT * FROM users", PDO::FETCH_ASSOC, []);
    }

   public static function testStatic(){
        return Database::getInstance()->getRow("SELECT * FROM users", PDO::FETCH_ASSOC, []);
    }
}