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

时间:2017-03-01 14:04:14

标签: php mysql mysqli pdo connection

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 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 :: ??     }

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

3 个答案:

答案 0 :(得分:3)

我喜欢@WOLFF直截了当的答案,但我想帮助解释你所得到的错误,以便你在将来的类似案例中理解。

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

  

从对象上下文中调用方法时,伪变量$this可用。 $this是对调用对象的引用。

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

由于您无法在静态方法中使用$this,因此您无法使用私有$this->_db等任何对象属性。您只能在静态方法中使用静态类属性。

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

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没有任何魔术方法来初始化类?有一个添加静态类"构造函数"的提案草案。到PHP,但它仍然只是一个草案。它尚未在任何已发布的PHP版本中实现。没有办法知道何时或是否会实施。

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

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

在此问题中查看Python中的示例:Pythonic Way to Initialize (Complex) Static Data Members

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

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

答案 1 :(得分:3)

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

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, []);
    }
}

答案 2 :(得分:-1)

我已经在我的应用程序中完成了这段时间。虽然是对所选数据库驱动程序的调用确实也只是函数 - 它们是需要大量参数的函数(登录/数据库信息/等),这些函数是重复的......

我使用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);
...

请注意,这可能在您的应用程序中的任何位置 - 在另一个函数内或在另一个类中 - 只要您通过静态包含或通过静态包含正确地给出db.class.php文件可见性,这实际上并不重要。最好是an autoloading function

...或者从一个类中作为你的例子:

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
     */

}