PHP OOP:如何在其他类中使用通用MySQL类

时间:2022-11-19 12:06:33

I've just started using OOP PHP and ran into a question. I've set up a generic mysql class that allows me to connect to a database and has some functions to obtain records from a table:

我刚刚开始使用OOP PHP并遇到了一个问题。我已经设置了一个通用的mysql类,它允许我连接到一个数据库,并有一些函数来从表中获取记录:

class mysql{
    //some lines to connect, followed by:
    public function get_record($sql)
    {
      $result = mysql_result(mysql_query($sql));
      return $result;
      //obiously it's a bit more advanced, but you get the picture.

    }
}

Next, I have a class to obtain user details:

接下来,我有一个类来获取用户详细信息:

class user{
    __construct($id)
    {  
        $this->id = $id
    }
    public function get_username($id)
    {
         $username = get_record("SELECT name FROM users WHERE id = '".$this->id."'");
         return $username;
    }
}

I tried this, but got the error that the function get_record was unkown. I solved this by adding $mysql = new mysql(); to the user class.

我试过这个,但得到了函数get_record未知的错误。我通过添加$ mysql = new mysql()来解决这个问题。到用户类。

However, it feels quite inefficient to have to instantiate the mysql object for every class that uses my database methods (that's pretty much all of them).

但是,为每个使用我的数据库方法的类实例化mysql对象(这几乎就是所有这些)都感觉效率很低。

Is there a way to make the mysql class and its methods accessible to all other classes, without having to call the mysql class in every method?

有没有办法让mysql类及其方法可供所有其他类访问,而无需在每个方法中调用mysql类?

6 个解决方案

#1


5  

For one, you don't need to use singleton in this case - or actually, you almost never do. See this article, for example.

首先,在这种情况下你不需要使用单身 - 或者实际上,你几乎从不这样做。例如,请参阅此文章。

Second, I think your OO designs are a bit off. The main point of object-oriented programming and design is to isolate responsibility into separate classes. Right now, you're giving your User class two main responsibilities - store / carry one user's relevant data, and query the data service (in this case, a simple MySQL / database abstraction layer).

其次,我认为你的OO设计有点偏。面向对象编程和设计的要点是将责任分离为单独的类。现在,您将为User类分配两个主要职责 - 存储/携带一个用户的相关数据,并查询数据服务(在这种情况下,是一个简单的MySQL /数据库抽象层)。

You should first move that functionality into a separate object. Usually, this is called a Service - so in this case, it's a UserService. A UserService has one responsibility: provide access to User objects. So it'd sorta look like this:

您应该首先将该功能移动到单独的对象中。通常,这称为服务 - 所以在这种情况下,它是UserService。 UserService有一个职责:提供对User对象的访问。所以它看起来像这样:

class UserService {
    public function __construct($mysql); // uses the mysql object to access the db. 
    public function get($id) {
        $result = $this->mysql->get_record("select x from y");
        $user = new User($result['id'], $result['name']); // assuming user has a constructor that takes an id and a name
        return $user;
    }
    public function save($user);
    public function delete($user);
}

You tie it all together at the start of your request (or where you need to access users):

您可以在请求开始时(或者您需要访问用户的位置)将所有内容绑定在一起:

$mysql = new MySQL($credentials);
$service = new UserService($mysql);
$user = $service->find(1337);

It's not perfect, but it's a much neater design. Your MySQL object does what it needs to do (build a connection, execute queries), your user object is plain dumb, and your service does only one thing, i.e. provide a layer between the actual storage layer and the thing calling it.

它并不完美,但它的设计更加整洁。您的MySQL对象执行它需要做的事情(构建连接,执行查询),您的用户对象显然是愚蠢的,并且您的服务只做一件事,即在实际存储层和调用它的事物之间提供一个层。

#2


2  

This is a common problem, and so there is a common solution to this. As you might know, in software development common solutions on common problems are called Design Patterns.

这是一个常见问题,因此有一个共同的解决方案。您可能知道,在软件开发中,常见问题的常见解决方案称为设计模式。

There are two design patterns that can help you solve this problem. In a more abstract sense the problem you are facing is:

有两种设计模式可以帮助您解决此问题。从更抽象的意义上讲,您面临的问题是:

How can i make class A available in class B?

如何在B级提供A级课程?

The Singleton pattern

单身人士模式

"In the singleton pattern a class can distribute one instance of itself to other classes."

“在单例模式中,类可以将自身的一个实例分发给其他类。”

This is not exactly what you are looking for, as your website may use multiple database connections. However, it is used by a lot of people in this way.

这并不是您正在寻找的,因为您的网站可能使用多个数据库连接。但是,它以这种方式被很多人使用。

Read some information about using a singleton class as a database provider here: https://www.ibm.com/developerworks/library/os-php-designptrns/#N10124

阅读有关在此处使用单例类作为数据库提供程序的一些信息:https://www.ibm.com/developerworks/library/os-php-designptrns/#N10124

More information on the singleton pattern in PHP: http://www.fluffycat.com/PHP-Design-Patterns/Singleton/

有关PHP中单例模式的更多信息:http://www.fluffycat.com/PHP-Design-Patterns/Singleton/

Another sensible approach is the registry pattern:

另一个明智的方法是注册表模式:

Registry Pattern

You can find information about the registry pattern on the link below, as well as an implementation almost identical that you are looking for: http://www.sitecrafting.com/blog/php-patterns-part/

您可以在下面的链接中找到有关注册表模式的信息,以及与您正在寻找的几乎完全相同的实现:http://www.sitecrafting.com/blog/php-patterns-part/

Even more powerful is a combination between the singleton and the registry.

更强大的是单例和注册表之间的组合。

Good luck and enjoy learning OOP PHP!

祝你好运,享受学习OOP PHP!

#3


1  

You should pass in the mysql object to each user object. So it would look like this:

您应该将mysql对象传递给每个用户对象。所以它看起来像这样:

$mysql = new mysql();
$user = new user( $mysql, $id);
$name = $user->get_username();

class user {
    public function __construct($mysql, $id) {
        $this->mysql = $mysql;
        $this->id = $id;
    }
    public function get_username() {
        $username = $this->mysql->get_record("SELECT name FROM users WHERE id = '".$this->id."'");
        return $username;
    }
}

#4


1  

Design your mysql class to be called statically:

设计你的mysql类静态调用:

$username = Mysql::get_record("SELECT name FROM users WHERE id = '".$this->id."'");

http://php.net/manual/en/language.oop5.static.php

#5


0  

using global variables, although that is probably not the best option.

使用全局变量,虽然这可能不是最好的选择。

$mysql = new mysql();

function someFunction() {
  global $mysql;
  $mysql->get_record(...)
}

or a static method for your mysql class (see Singleton)

或者mysql类的静态方法(参见Singleton)

class mysql {
  public static $theInstance = new mysql();
  public static function getInstance() {
    return $this->theInstance;
  }
}

function someFunction() {
  $database= mysql::getInstance();
  $database->get_record(...)
}

#6


0  

Start to think to use Doctrine, it's better

开始考虑使用Doctrine,它会更好

http://www.doctrine-project.org/

#1


5  

For one, you don't need to use singleton in this case - or actually, you almost never do. See this article, for example.

首先,在这种情况下你不需要使用单身 - 或者实际上,你几乎从不这样做。例如,请参阅此文章。

Second, I think your OO designs are a bit off. The main point of object-oriented programming and design is to isolate responsibility into separate classes. Right now, you're giving your User class two main responsibilities - store / carry one user's relevant data, and query the data service (in this case, a simple MySQL / database abstraction layer).

其次,我认为你的OO设计有点偏。面向对象编程和设计的要点是将责任分离为单独的类。现在,您将为User类分配两个主要职责 - 存储/携带一个用户的相关数据,并查询数据服务(在这种情况下,是一个简单的MySQL /数据库抽象层)。

You should first move that functionality into a separate object. Usually, this is called a Service - so in this case, it's a UserService. A UserService has one responsibility: provide access to User objects. So it'd sorta look like this:

您应该首先将该功能移动到单独的对象中。通常,这称为服务 - 所以在这种情况下,它是UserService。 UserService有一个职责:提供对User对象的访问。所以它看起来像这样:

class UserService {
    public function __construct($mysql); // uses the mysql object to access the db. 
    public function get($id) {
        $result = $this->mysql->get_record("select x from y");
        $user = new User($result['id'], $result['name']); // assuming user has a constructor that takes an id and a name
        return $user;
    }
    public function save($user);
    public function delete($user);
}

You tie it all together at the start of your request (or where you need to access users):

您可以在请求开始时(或者您需要访问用户的位置)将所有内容绑定在一起:

$mysql = new MySQL($credentials);
$service = new UserService($mysql);
$user = $service->find(1337);

It's not perfect, but it's a much neater design. Your MySQL object does what it needs to do (build a connection, execute queries), your user object is plain dumb, and your service does only one thing, i.e. provide a layer between the actual storage layer and the thing calling it.

它并不完美,但它的设计更加整洁。您的MySQL对象执行它需要做的事情(构建连接,执行查询),您的用户对象显然是愚蠢的,并且您的服务只做一件事,即在实际存储层和调用它的事物之间提供一个层。

#2


2  

This is a common problem, and so there is a common solution to this. As you might know, in software development common solutions on common problems are called Design Patterns.

这是一个常见问题,因此有一个共同的解决方案。您可能知道,在软件开发中,常见问题的常见解决方案称为设计模式。

There are two design patterns that can help you solve this problem. In a more abstract sense the problem you are facing is:

有两种设计模式可以帮助您解决此问题。从更抽象的意义上讲,您面临的问题是:

How can i make class A available in class B?

如何在B级提供A级课程?

The Singleton pattern

单身人士模式

"In the singleton pattern a class can distribute one instance of itself to other classes."

“在单例模式中,类可以将自身的一个实例分发给其他类。”

This is not exactly what you are looking for, as your website may use multiple database connections. However, it is used by a lot of people in this way.

这并不是您正在寻找的,因为您的网站可能使用多个数据库连接。但是,它以这种方式被很多人使用。

Read some information about using a singleton class as a database provider here: https://www.ibm.com/developerworks/library/os-php-designptrns/#N10124

阅读有关在此处使用单例类作为数据库提供程序的一些信息:https://www.ibm.com/developerworks/library/os-php-designptrns/#N10124

More information on the singleton pattern in PHP: http://www.fluffycat.com/PHP-Design-Patterns/Singleton/

有关PHP中单例模式的更多信息:http://www.fluffycat.com/PHP-Design-Patterns/Singleton/

Another sensible approach is the registry pattern:

另一个明智的方法是注册表模式:

Registry Pattern

You can find information about the registry pattern on the link below, as well as an implementation almost identical that you are looking for: http://www.sitecrafting.com/blog/php-patterns-part/

您可以在下面的链接中找到有关注册表模式的信息,以及与您正在寻找的几乎完全相同的实现:http://www.sitecrafting.com/blog/php-patterns-part/

Even more powerful is a combination between the singleton and the registry.

更强大的是单例和注册表之间的组合。

Good luck and enjoy learning OOP PHP!

祝你好运,享受学习OOP PHP!

#3


1  

You should pass in the mysql object to each user object. So it would look like this:

您应该将mysql对象传递给每个用户对象。所以它看起来像这样:

$mysql = new mysql();
$user = new user( $mysql, $id);
$name = $user->get_username();

class user {
    public function __construct($mysql, $id) {
        $this->mysql = $mysql;
        $this->id = $id;
    }
    public function get_username() {
        $username = $this->mysql->get_record("SELECT name FROM users WHERE id = '".$this->id."'");
        return $username;
    }
}

#4


1  

Design your mysql class to be called statically:

设计你的mysql类静态调用:

$username = Mysql::get_record("SELECT name FROM users WHERE id = '".$this->id."'");

http://php.net/manual/en/language.oop5.static.php

#5


0  

using global variables, although that is probably not the best option.

使用全局变量,虽然这可能不是最好的选择。

$mysql = new mysql();

function someFunction() {
  global $mysql;
  $mysql->get_record(...)
}

or a static method for your mysql class (see Singleton)

或者mysql类的静态方法(参见Singleton)

class mysql {
  public static $theInstance = new mysql();
  public static function getInstance() {
    return $this->theInstance;
  }
}

function someFunction() {
  $database= mysql::getInstance();
  $database->get_record(...)
}

#6


0  

Start to think to use Doctrine, it's better

开始考虑使用Doctrine,它会更好

http://www.doctrine-project.org/