默认情况下,将一个全局变量传递给类的所有方法

Sid*_*eem 1 php oop mysqli

假设我创建了一个全局变量global $ db3; ($ db3实际上是另一个类的一个保留对象).而不是将这个全局变量逐个传递给每个方法,我想默认将这个变量传递给一个类的所有方法.

我的第一个数据库类是

class dtb{
public $connection;

public function __construct(){

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

     }

     }
 $db3=new dtb();
Run Code Online (Sandbox Code Playgroud)

第二类是

  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)


      }


   }
Run Code Online (Sandbox Code Playgroud)

Mad*_*iha 10

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

有关详细信息,请参阅此问题.

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

class A {

    private $db;

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

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

    /*
     * Etc
     */
}
Run Code Online (Sandbox Code Playgroud)

然后,您可以通过以下方式调用它:

$db3 = new dtb;
$a = new A($db3);
$a->someFunction();
Run Code Online (Sandbox Code Playgroud)

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


hak*_*kre 5

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

最明显的问题是您不传递数据库连接对象.而是将它包装到类型中dtb,以便稍后在其他类型内部进行解包,例如在user:

function login() {
   ...

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

相反,user类型应该只有连接.它不需要知道dtb包装:

function login() {
   ...

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

接下来,您没有使用mysqli扩展的OO接口.您的示例代码很好地证明了这会使您的代码变得不必要地复杂化.让我们以mysqli的方式做到这一点:

function login() {
   ...

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

   ...
Run Code Online (Sandbox Code Playgroud)

如您所见,您可以在不使用mysqli_*特定功能的情况下使用连接,只需使用query对象的方法即可.

所以现在这个单行代码已经非常本地了.该$connection对象需要接触到的user,对你有什么迄今与非面向对象背景的全局变量使用.但是在面向对象编程中,类的代码中不应该使用全局变量.那是因为过程代码中的全局变量是$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;");
    }
}
Run Code Online (Sandbox Code Playgroud)

如您所见,User在构造函数方法中初始化__constructMysqli连接.然后可以使用该连接,$this->connection因为它已被分配给该私有变量.

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

所以现在用于:

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

$user = new User($connection);

$user->login();
Run Code Online (Sandbox Code Playgroud)

就是这样.当然,在创建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;");
}
Run Code Online (Sandbox Code Playgroud)

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

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

请记住:每个人都在用水烹饪,背后没有任何魔力.