如何使用 OOP 将 $db 从另一个 .php 使用到另一个 .php 的类?

Posted

技术标签:

【中文标题】如何使用 OOP 将 $db 从另一个 .php 使用到另一个 .php 的类?【英文标题】:How to use $db from another .php to another .php's class using OOP? 【发布时间】:2016-04-17 20:13:31 【问题描述】:

我是 OOP php 新手,自从我开始 Web 开发以来,我一直在使用过程 API,所以我很难迁移到 OOP。

假设我在下面有这四个.php 文件和结构。

connection.db.php

<?php
    define("DB_HOST", "127.0.0.1");
    define("DB_USER", "root");
    define("DB_PASS", "");
    define("DB_NAME", "sample_db");

    $db = new mysqli(DB_HOST, DB_USER, DB_PASS, DB_NAME);

    echo (!$db->connect_error) ? NULL : die("<pre>Unable to connect to the MySQL Server -> $db->connect_error</pre>");
?>

sampleclass.class.php

<?php
    public $db;

    class MySQLqueries 
        public function samplefunction($queryString) 
            $sqlQry = mysqli->query($queryString);

            return ($sqlQry) ? "<pre>Query Executed Successfully</pre>" : die("<pre>An error occured -> $db->error</pre>");
        
    
?>

包括.inc.php

<?php
    error_reporting(0);
    date_default_timezone_set("Asia/Manila");

    require 'connection.db.php';
    require 'sampleclass.class.php';
?>

index.php

<?php
    require 'includes.inc.php';

    $todo = new MySQLqueries;
    echo $todo->samplefunction("SELECT `sample_column` FROM `sample_table` WHERE `sample_column` = 'sample_value';");
?>

您可能注意到也可能没有注意到,我的问题是如何在sampleclass.class.phpsamplefunction 中使用来自connection.db.php$db

你可能会问我,为什么不在 sampleclass.class.php 中创建一个__construct() 方法,然后移动“$db = new mysqli(DB_HOST, DB_USER, DB_PASS, DB_NAME);”那里 ?。好吧,如果我要这样做,所有其他类都必须有它自己的 constructor$db = new mysqli(DB_HOST, DB_USER, DB_PASS, DB_NAME); 声明在那里对吗?

connection.db.php 上使用$db = new mysqli(DB_HOST, DB_USER, DB_PASS, DB_NAME);,我认为我可以灵活地重复使用它。

你看我已经在sampleclass.class.php 中声明了一个public $db;,但我不知道接下来会发生什么。如果有人能帮助我,我将不胜感激。

PS:我已经咨询过 Google 博士。关于这个问题,我只有大量的文章或视频教程展示了如何使用和进行 OOP PHP-MySQLi 编程,但没有使用类和方法。

【问题讨论】:

【参考方案1】:

您最好创建一个DB 类或利用已经创建的类来实现您想要做的事情。

此类事情的通常流程是调用Lazy Loading/Dependency Injection。您将所需对象传递给类的位置。

如果你选择这条路,我建议你阅读依赖注入,就像很多事情一样,它有利有弊,但在 OOP 中是必不可少的。

As Ben Stated in the comments:

依赖注入是 OOP 中的一个关键原则。我想补充一点 如果您对 OOP 很认真,您还应该查看 autoloaders in general、PSR-4 和 Composer。

上面没有提到的一面,你最好看看PHPTheRightWay,他们列出了很多的东西,包括Dependency Injection。

你最终会创造出类似的东西。如果你按照这个例子来理解它是如何工作的,那就更好了:

Class DB 

    function __construct($host, $user, $pass, $db)  
        return $this->connect($host, $user, $pass, $db); 
    

    function connect($host, $user, $pass, $db) 
        //..connect and all.
    

    //...the rest of your functions/class...

你可以随心所欲地构造它。或者只是让mysqli 对象可访问,允许您调用它。

现在我们来看看有趣的东西。实际上将其注入您的班级;

Class Foo 

    $private $db;

    // your construct method here will ONLY except a `DB` class instance/object as $db. 
    // Try it with anything else and learn from the errors to understand what I mean.
    function __construct(DB $db)
        $this->db = $db;
    



$db = new DB($host, $user, $pass, $db);
// you can error check it here

$foo = new Foo($db);// inject the $db object.

如果你只是想共享资源,你可以使用global但强烈建议不要这样做

include('connection.db.php');

class MySQLqueries 
        public function samplefunction($queryString) 
            global $db;
            $sqlQry = mysqli->query($queryString);

            return ($sqlQry) ? "<pre>Query Executed Successfully</pre>" : die("<pre>An error occured -> $db->error</pre>");
        

如果您选择此路径,最好将$dbglobal 实例分配给内部类变量,例如$this-&gt;db

【讨论】:

+1 依赖注入是 OOP 中的一个关键原则。我想补充一点,如果您对 OOP 很认真,您还应该关注 autoloaders in general、PSR-4 和 Composer。 @BenHarold 感谢您的链接,我会将它们添加到答案中! 谢谢大家。虽然我很难吸收这些东西,因为我对 OOP 真的很陌生。你想说的是我最好在我的 connection.db.php 中创建一个 DB 类并将其注入其他类,对吗? @TheQuestioner 你最好遵循一个标准。而且,如果您要走 OOP 路径,那么拥有一个处理与数据的任何和所有交互的数据库类是绝对有意义的。这个类基本上就是你的DAO (Data Access Object)。它使所有交互保持统一,并且应该在进行重大项目之前学习。您应该始终将数据访问层与应用程序分开。 (将其视为您银行帐户(包含数据的数据库)的密码 (DAO)。) 对不起。我差点忘了。 :)【参考方案2】:

由于您已经在使用对象,您可能还应该使用 OOP(面向对象编程)实现。

因此,您可以将$db 变量作为静态变量放在sampleclass.class.php 文件中,如下所示:

class MysqlConn

    public static $db;

就像您使用此代码实例化 mysqli 对象一样:

MysqlConn::$db = new mysqli(DB_HOST, DB_USER, DB_PASS, DB_NAME);

更好的是,您可以创建一个方法来实例化 $db 连接,初始化该类中的变量:

<?php
class MysqlConn

    protected
        static $DB_HOST = "127.0.0.1",
        static $DB_USER = "root",
        static $DB_PASS = "",
        static $DB_NAME = "sample_db";

    protected static $db;

    public static function getDB()
    
        if (!isset(self::$db) 
            self::$db = new mysqli(DB_HOST, DB_USER, DB_PASS, DB_NAME);

            if ($db->connect_error) 
                die("<pre>Unable to connect to the MySQL Server -> $db->connect_error</pre>");
            
        
        return self::$db;
    


MysqlConn::getDB();

index.php中,你可以通过如下代码获取db实例,而不是每次都重新连接:

$db = MysqlConn::getDB();

【讨论】:

这还不错。但我也很难吸收它。谢谢:) 还没有测试我的方法,这更接近你所拥有的,但无论如何@darren 的答案要好得多。而且,他在我写的时候回复了。 ;) 你也得到了我的投票@NunoPereira,我们都在这里讨论同样的事情:) 你只是采用了单例方法!好答案!【参考方案3】:

我的问题是如何使用来自 connection.db.php 的 $db sampleclass.class.php的示例函数

您可以在您的情况下使用 global,只需包含或要求 connection.db.php,然后在 php 中使用 global

这样的事情可能会对你有所帮助

   require_once 'connection.db.php';

        class MySQLqueries 
                public function samplefunction($queryString) 
                    global $db;
                    //You can now use $db variable as you want
                    print_r($db);
                    $sqlQry = mysqli->query($queryString);

                    return ($sqlQry) ? "<pre>Query Executed Successfully</pre>" : die("<pre>An error occured -> $db->error</pre>");
                
        

【讨论】:

这里的global 会降低类的可移植性——也许$db 最好在构造函数中发送? @halfer 是的,我也这么认为,但 OP 的问题是 How to use $db from another .php to another .php's class using OOP? 您将如何直接回答?据我了解,将其传递给构造函数或为数据库创建另一个类并将其注入另一个类没有使用$db 变量它正在传递$db 变量。

以上是关于如何使用 OOP 将 $db 从另一个 .php 使用到另一个 .php 的类?的主要内容,如果未能解决你的问题,请参考以下文章

如何运行 db:migrate 从另一个带参数的 rake 任务?

通过PHP中的OOP连接到数据库和活动

我正在尝试将 PDO 和 OOP 结合起来,但无法正常工作

如何在 PHP 中使用多个类

OOP PHP未定义变量

如何使用 OOP 概念将 arraylist 对象设置为表