【问题标题】:Passing one global variable to all methods of a class by default默认将一个全局变量传递给一个类的所有方法
【发布时间】:2012-10-23 20:24:21
【问题描述】:

假设我创建了一个全局变量 global $db3; ($db3其实是另一个类的实例化对象)。与其把这个全局变量一一传递给每个方法,我想把这个变量默认传递给一个类的所有方法。

我的第一个数据库类是 as

class dtb{
public $connection;

public function __construct(){

    $this->connection=mysqli_connect('localhost','root','','new5');

     }

     }
 $db3=new dtb();

二等舱是

  session_start();
  $a = new session($db3);

       class user{
         public $db;

          public function __construct($db)
    {
        $this->db = $db;

    }

function login(){
 //global $db3;


 //$db3->show_new();
   $results=mysqli_query($this->db->connection,"select * from user");  //(I want to use $db3 of another class here as resource link)


      }


   }

【问题讨论】:

  • 使用构造函数并将$db设置为类变量,那么它将在所有方法中都可用$this->db
  • 强烈不推荐使用这样的全局变量。当您无法确定谁编辑了全局变量上的内容时,事情很快就会失控,这会影响您程序的其余部分。
  • 如果在全局范围内将其声明为global,则可以在任何地方以$GLOBALS['db3'] 获取它。
  • @Claudrian:静态变量 === 全局变量。
  • @Claudrian:错了,我可以从程序中的任何地方调用class::$static。它不与otherclass::$static 碰撞的事实可以与global $class_static 不与global $otherclass_static 碰撞的事实相比较。

标签: php oop mysqli


【解决方案1】:

强烈建议不要使用全局变量。它会妨碍您的应用程序的可读性和可维护性,并可能导致您失去理智。

See this question for more details.

将变量传递给类的构造函数。通过访问$this->db,它可用于所有其他方法。

class A {

    private $db;

    public function __construct($db) {
        $this->db = $db;
    }

    public function someFunction() {
        $this->db->doSomething();
    }

    /*
     * Etc
     */
}

然后您继续通过以下方式调用它:

$db3 = new dtb;
$a = new A($db3);
$a->someFunction();

someFunction() 将有权访问 $db3 实例,因为它已传递给构造函数并保存为对象字段。

【讨论】:

  • ,还有其他方法吗?,我实际上想在这个类的函数中访问其他类的$db3对象
  • @SidraNaeem:我的解决方案怎么不适合你?只需像这样在构造函数中传递它:$a = new A($db_object);.
  • $Madara,我更新了问题内容,​​还添加了我的第一个数据库类,其对象在第二类中使用作为资源链接,请查看我的简单数据库类。谢谢
  • @SidraNaeem:这不会改变我的答案,您只需将$db3 传递给构造函数,就像我之前的评论一样。
  • 我改变了它,但它没有被通过。可能是我没有以正确的方式做它。你能把上面的答案编辑为一个完整的代码解决方案吗。没关系,请。跨度>
【解决方案2】:

您的代码示例中存在一些与您在问题中所要求的内容相关的问题,因此我想强调一下。

最明显的问题是您没有传递数据库连接对象。相反,您将其包装到类型 dtb 中,以便稍后在其他类型中解包,例如在您的 user 中:

function login() {
   ...

   $results = mysqli_query($this->db->connection,"select * from user");
                                  ^--^--- unwrapping
   ...

user 类型应该只有连接。它不需要知道dtb 包装:

function login() {
   ...

   $results = mysqli_query($this->connection, "select * from user");
                                      ^--- one thing, not one thing and another
   ...

接下来你没有使用mysqli扩展的OO接口。您的示例代码很好地证明了这不必要地会使您的代码复杂化。让我们用mysqli的方式来做吧:

function login() {
   ...

   $results = $this->connection->query("select * from user");

   ...

如您所见,您无需使用指定的mysqli_* 函数即可使用连接,而只需使用对象的query 方法即可。

所以现在这行代码就非常本地化了。 $connection 对象需要进入user,因为到目前为止您已经使用了非 OO 后台全局变量。但是在面向对象编程中,类的代码中不应该使用全局变量。这是因为程序代码中的全局变量是类中的 $this 变量。 $this 应该包含类中方法所需的所有内容 - 如果没有提供方法参数。

因此,您的不同类基于数据库连接。你想在每个班级都有它。一个类在它的构造方法中被初始化。在那里,您将所有内容作为初始化类所需的参数传递。让我们以user 示例类为例:

class User
{
    private $connection;

    public function __construct(Mysqli $connection) {
        $this->connection = $connection;
    }

    public function login() {
        $resultSet = $this->connection->query("SELECT * FROM user;");
    }
}

如您所见,User 在其构造方法__construct 中使用Mysqli 连接进行初始化。然后,该连接可以与 $this->connection 一起使用,因为它已分配给该私有变量。

您现在可以放心,一旦类被实例化,连接将保持不变。如果您需要同时打开与另一个数据库的连接,这也很有用。无论您需要创建多少个 Mysqli 连接,您的代码都将继续工作。

现在到用法:

$connection = new Mysqli('localhost','root','','new5');

$user = new User($connection);

$user->login();

就是这样。当然,在创建 Mysqli 连接对象的位置和创建用户的位置之间可能存在一些代码,但您需要做的就是传递连接。

这不会停在这里,尽管我已经接近这里的博客文章。您可能想要做的甚至是消除每个类中连接细节的负担,而是从负责重复数据库交互代码的基类扩展,以便在更高级别的类中您可以更专注于数据库细节上的工作和更少。有很多不同的方法可以做到这一点。从基类扩展只是其中之一。一个非常简单的例子:

class Database
{
    private $connection;

    public function __construct(Mysqli $connection) {
        $this->connection = $connection;
    }

    protected function query($sql) {
        return $this->connection->query($sql);
    }
}

class User extends Database
{
    $resultSet = $this->query("SELECT * FROM user;");
}

例如,如果您有一组公共类,只是其属性名称不同,则公共基类可以包含实现该目的的代码,而从它扩展的类只需要为此指定参数。

但正如所写,有许多不同的方法可以将类映射到数据库连接。有时您根本不想映射它们。做最适合你的事情,玩一点。如果您始终在构造函数中进行初始化并阻止使用全局变量(以及也是全局变量的静态类变量),那么您将保持灵活性并且实际上可以玩得更好。

请记住:每个人都在用水做饭,这背后没有魔法。

【讨论】:

  • @hakre,感谢您的详细回复。我正在从 mysql 转移到 mysqli,所以我必须使用 mysqli 程序方式,因为我已经有大约 2000 个 mysql 查询。
【解决方案3】:

在构造函数中将其设置为类变量

Class a{

  public __construct( $db ){
    $this->db = $db;
  }

  function b(){
    $this->db->query();
  }
}

【讨论】:

  • 没有否决你,但你希望$this->db(); 做什么?
  • 无论它被写做什么
猜你喜欢
  • 1970-01-01
  • 2011-03-15
  • 2021-04-12
  • 1970-01-01
  • 2012-12-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多