简体   繁体   中英

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

Now in every class that needs database connection

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

Now it gives me an error saying cannot use $this, then how i can use it using self:: ?? }

Now how can i use it in static function and non static function together

I like the straightforward answer from @WOLFF, but I'd like to help explain the error you got, so you understand in similar cases in the future.

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

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

But you're trying to use $this in a static function, so there's no reference to a calling object. The pseudo-variable $this is therefore undefined.

Because you can't use $this in a static method, you can't use any object properties like your private $this->_db . You can only use static class properties in a static method.

PHP doesn't have any way of auto-initializing static properties of a class. The only way to do it is to call a static initialization method of the class before you try to use any other static methods.

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());

There's nothing magic about the init() static method I show in the example above. You can name the method anything you want. You just have to remember to call it yourself before using other static methods that depend on the stuff it initializes.

So why doesn't PHP have any magic method to initialize a class? There's a draft proposal to add a static class "constructor" to PHP, but it's still just a draft. It has not been implemented in any released version of PHP. There's no way to know when or if it will ever be implemented.

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


PS: FWIW, Python and Java are examples of languages that have the feature of static class initialization.

See example in Python in this question: Pythonic Way to Initialize (Complex) Static Data Members

See example in Java in this question: static variable initialization java

I know you're using PHP not those other languages, I'm just pointing out that such a thing is possible.

Get database instance when it is needed.

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

I've done this for quite some time in my applications. While yes calls to the database driver of choice are indeed also simply functions - they are functions with lots of parameters needed (login / db info /etc) that are SO repetitive...

I'm using sqlsrv - but same technique could be revised to whatever you needed

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

then wherever I need a database handle: somefile.php:

$db = db::getDatabaseHandle();

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

Note that this could be pretty much anywhere in your application - within another function or within another class - really doesn't matter as long as you have properly given the db.class.php file visibility via a static include or preferably an autoloading function

... or from within a class as your example:

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

}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM