简体   繁体   English

PHP使用类函数查询另一个类内的数据库

[英]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. 正如您将在下面的“ Distributors”类中看到的那样,我在构造函数中实例化了“ General”类。 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. Singleton只是全球状态的另一种形式,这很糟糕。 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); 当您以这种方式实例化时, $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 . 相反,应该像对PDO一样注入General实例。 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. 我有10个课程,需要重复进行。

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 . 除此之外,您的General班级显然违反了单一责任原则

You should use singleton for getting the DB in your classes, or use some ORM. 您应该使用单例在类中获取数据库,或使用一些ORM。

about mysql class with singleton: 关于单例的mysql类:

Establishing database connection in php using singleton class 使用Singleton类在php中建立数据库连接

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); 我不知道您会遇到什么问题,但我认为getTableNames函数将返回对象或数组,因此$tables的结果不是字符串,则执行var_dump($tables); to see what is in $tables 看看$tables什么

Try to google your way out from there. 尝试用谷歌搜索出路。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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