【问题标题】:Using PHP's mysqli connection as an object for other classes使用 PHP 的 mysqli 连接作为其他类的对象
【发布时间】:2014-01-29 04:28:21
【问题描述】:

我有以下代码,其中包含使用 mysqli 与 SQL 数据库建立连接的类 DB

<?php
class DB
{
    private $mysqlilink;
    private $errors;
    function __construct($errors = array())
    {
        $this -> errors = $errors;
        $this -> connect();
    }

    function connect()
    {
        $server = "127.0.0.1";
        $user_name = "un";
        $password = "pw";
        $database = "db";

        if ($this -> mysqlilink == null)
        {
            $this -> mysqlilink = new mysqli($server, $user_name, $password, $database);
            if (mysqli_connect_errno())
            {
                printf("Connect failed: %s\n", mysqli_connect_error());
                exit();
            }
        }
        return $this -> mysqlilink;
    }

    function __destruct()
    {
        $stmt -> close();
    }
}
?>

我计划至少使用一个类(在它自己的脚本文件中)和专用的 PHP 函数,这些函数可以访问网站各个部分的数据库。在上面导入这个脚本后,我如何链接到它并通过对象的连接调用数据库?我正在使用以下代码:

<?php
include_once("connect.php");
class PageFunctions
{

    function printText()
    {
        if ($stmt = $this -> mysqlilink -> prepare("SELECT Text, MoreText FROM mytext WHERE id = 1"))
        {
            $stmt -> execute(); $stmt -> store_result();
            $rows = $stmt -> num_rows;
            if ($rows == 0) { return 'Database Not Found'; }
            else
            {
                $stmt -> bind_result($returnedText, $moreReturnedText); // Output variable(s)
                while ($stmt -> fetch()) // Return results
                {
                    return 'First text: ' . $returnedText . ' Second text: ' . $moreReturnedText;
                }
            }
            $stmt -> free_result();
            return;
        }
        else { printf("Prepared Statement Error: %s\n", $this -> mysqlilink -> error); }
    }
}
?>

重申一下,我需要将第一个代码示例用作在多个其他类/代码文件中形成一个对象的类,例如第二个代码示例。由于我是 PHP 面向对象的新手,因此无法成功完成此任务,因此我想在想出一个糟糕的解决方案之前先征求一些专家的建议。

【问题讨论】:

    标签: php oop mysqli


    【解决方案1】:

    听起来您正在寻找依赖注入。还有其他方法,但这是最佳做法。

    //create an object of the DB class
    $DB = new DB();
    
    //create a PageFunctions object and pass the DB object into it as a dependency
    $PF = new PageFunctions($DB);
    
    //call your function from PageFunctions
    $PF->myFunction();
    
    //follow these concepts and do whatever you want!
    

    您可以通过为 PageFunctions 设置构造函数来完成这项工作:

    class PageFunctions() {
    
       //we don't want to accidentally change DB, so lets make it private;
       private $DB; 
    
       //this is the class constructor
       //the constructor is called when instantiating the class - new PageFunctions()
       public function __construct(DB $DB) {
         //now the DB object is available anywhere in this class!
         $this->DB = $DB;
       }
       //sample function
       public function myFunction() {
         $this->DB->connect();
       }
    }
    

    因此,任何时候您需要在另一个类中使用一个类,创建它的实例(对象)(或使用现有的)并在创建它的实例时将其传递给需要它的新类。

    您可能会看到这种行为是使用依赖注入容器完成的,但它仍然是相同的概念、系统和结果。它只是更抽象一点。正如您可能已经从我的解释中注意到的那样,如果您有很多依赖于其他类、依赖于其他类等的类,那么手动创建实例并将它们传入时会变得非常困难。依赖注入容器是很好,因为它可以让你告诉它如何制作每个类,然后它会负责把它们全部放在一起。

    【讨论】:

    • 我实施了我们的解决方案,但出现两个错误。我误解了你的指示吗?对于与原始问题的样本略有不同的变量和函数名称,我们深表歉意。所有 3 个代码文件和错误都在这里 pastebin.com/QCva7hDK 谢谢
    • @Keavon 看起来您尝试在 PageIndex 类中使用 $this-&gt;mysqlilink 之类的东西。这是您传入的 DB 的属性。PageIndex 不吸收 DB,它将 DB 作为自己的 DB,因此您需要像 $this-&gt;DB-&gt;$mysqlilink 一样访问该属性。如果您喜欢,请不要忘记接受我的回答:)
    • 谢谢。当我使它起作用时,我一定会投票并接受答案。我添加了DB -&gt;,它摆脱了它产生的第一个Notice,但我收到了这个错误:Fatal error: Cannot access private property DB::$mysqlilink in D:\XAMPP\htdocs\includes\page_index.php on line 19
    • @Keavon 私有属性只能在类本身内访问(DB 的一种方法)。因此,您不能直接从它的实例访问该属性。标准做法是使用 getter/setter,也就是 mutators 来获取或设置私有变量。基本上是public function getMysqliLink() { return $this-&gt;mysqliLink; },然后是$this-&gt;DB-&gt;getMysqliLink()。这超出了您的问题范围:)
    • SomeKittensUx2666 无需刺激。我知道该网站是如何运作的,我不会忘记。 @m59 我不确定它是否超出了我的问题范围,因为问题询问如何使我提供的代码工作,所以我相信它仍在范围内。感谢您迄今为止提供的支持,但我仍然对您的最后评论感到非常困惑。我讨厌要求人们为我编写代码,但仍然不清楚。您能否从 pastebin.com/n6PnhCKM 创建一个新的 Pastebin 并进行所需的更改?再次抱歉,请您编写我的代码,但我无法理解您。
    猜你喜欢
    • 1970-01-01
    • 2023-04-09
    • 2017-11-27
    • 1970-01-01
    • 2017-06-04
    • 2012-07-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多