简体   繁体   中英

php Use class function that queries db inside another class

I have multiple classes set up and they all need to access the database, which they do. The trouble comes when I want to use a function from one class inside another.

class General
{

private $_db = NULL;
private $_db_one;
private $_db_two;
private $offset;

public function __construct ( PDO $db ) {

    $this->_db     = $db;
    $this->_db_one = 'lightsnh_mage1';
    $this->_db_two = 'lightsnh_inventory';  
    $this->offset  = 10800; 

}
public function getTableNames() {

    $sql = 'SELECT TABLE_NAME 
            FROM INFORMATION_SCHEMA.TABLES
            WHERE TABLE_TYPE = "BASE TABLE" AND TABLE_SCHEMA="' . $this->_db_two . '"';

    $statement = $this->_db->query($sql);
    $result = $statement->fetchAll(PDO::FETCH_ASSOC);
    return $result;
}   

This works fine and then my other class connects the same way. As you will see in my "Distributors" class below, I instantiate my "General" class in the constructor. As I am learning while I write, I cant help but feel that there is a more versatile way or efficient way to connect.

class Distributors
{

private $_db = NULL;
private $_db_one;
private $_db_two;
private $_source_tbl;
public  $lights;


public function __construct ( PDO $db ) {

    $this->_db = $db;
    $this->_db_one = 'lightsnh_mage1';
    $this->_db_two = 'lightsnh_inventory';
    $this->_source_tbl = 'distributors';
    // is this the best way to get functions from another class inside of this class? I have 10 classes I will need to repeat this for.
    $this->lights = new General($db);

}



public function getInventorySources() {

    // calling function from General class inside my distributor class
    $tables = $this->lights->getTableNames();

    // using result of General function inside of a function from Distributors class
    $sql = 'SELECT * FROM `' . $tables . '` WHERE `exclude` = 0';
    $statement = $this->_db->query($sql);
    $result = $statement->fetchAll(PDO::FETCH_ASSOC);

    return $result;

}

Singleton is just another form of global state, which is bad. You should always avoid it.

From your code example,

public function __construct ( PDO $db ) {

    $this->_db = $db;
    $this->_db_one = 'lightsnh_mage1';
    $this->_db_two = 'lightsnh_inventory';
    $this->_source_tbl = 'distributors';
    // is this the best way to get functions from another class inside of this class? I have 10 classes I will need to repeat this for.
    $this->lights = new General($db);
}

When you do instantiate this way $this->lights = new General($db); you take General class from global scope. So that, mocking and unit-testing is almost impossible.

Instead you should, inject an instance of General just like as you do for PDO . Like this:

public function __construct (PDO $db, General $general)
{

    $this->_db = $db;
    $this->_db_one = 'lightsnh_mage1';
    $this->_db_two = 'lightsnh_inventory';
    $this->_source_tbl = 'distributors';
    // is this the best way to get functions from another class inside of this class? I have 10 classes I will need to repeat this for.
    $this->lights = $general;
}

And you would use it this way:

$pdo = new PDO(...);
$pdo->setAttribute(...);

$general = new General($pdo);
$distributors = new Distributors($pdo, $general);

is this the best way to get functions from another class inside of this class? I have 10 classes I will need to repeat this for.

Yes, you should repeat that, not instantiation, but dependency injection. This makes your code more maintainable and does not introduce global state.

Apart from that, your General class seems obvious violation of the Single-Responsibility Principle .

You should use singleton for getting the DB in your classes, or use some ORM.

about mysql class with singleton:

Establishing database connection in php using singleton class

I don't know what problems you run into but i think the function getTableNames whil return an object or an array so the result in $tables is not a string do a var_dump($tables); to see what is in $tables

Try to google your way out from there.

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