7

我一直在努力转移到 PHP 中的 OOP。我在 php.net 上阅读了解释,但我希望我能在这里得到一些具体的答案。

我试图创建以下示例来说明我的问题。假设我有“数据库”、“产品”和“用户”类,如果用户有权访问,我想显示产品。

所以我将“Products”类称为“showProducts()”函数,该函数依次创建“User”类的实例,该实例创建“Database”对象的实例并检查用户访问级别。

如果用户有权访问,则“showProducts()”函数创建“Database”对象的另一个实例,并查询数据库。

class Database{

   public function query(){ 
      //runs query here 
   }

   public function __construct() { 
      //sets up connection here 
   }

}

class User{

   public function checkAccess(){ 
      $db = new Database(); 
      $db->query( //pass in query to check access )
      //does stuff, then returns true or false
   }

}

class Products{

   public function showProducts(){

      $user = new User();

      if($user->checkAccess())
         $db = new Database(); 
         $db->query( //pass in query to get products )
      }

}

我希望有人可以说明如何以正确的方式做到这一点。

我想要某种控制器类,它创建一个“数据库”对象,可供所有需要访问它的类使用,而不必创建“数据库”对象的多个实例。我想要用户类也一样,所以有一个所有类都可以访问的 $users 对象,而不必每次我需要在“用户”类中使用某些东西时都创建一个新对象。

如果我的问题不清楚,我深表歉意,并提前感谢您的任何回复!

感谢大家的回复!

4

3 回答 3

12

当从过程形式转移到面向对象编程时,您应该掌握的不仅仅是如何构建类。OOP 不是编写类,它是关于遵循 OOP 中的最佳实践、原则和模式。

您不应该在另一个内部实例化新对象,您应该通过构造函数或 setter 方法提供 User 对象,即 User 所依赖的 Database 对象。这就是所谓的依赖注入。目标是通过构造函数或 setter 方法将对象提供给需要它们的类。并且它们应该从该类外部实例化,因此更容易配置类。并且在构建一个类时,您希望轻松查看该类具有哪些依赖项。您可以在此处阅读有关控制反转原理的信息:IoC

那么您的代码将如下所示:

<?php

// User object that depends on Database object, and expects it in constructor.

class User
{
    protected $database;

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

    // -- SNIP --
}

?>

现在要使用该用户类,您可以这样做:

<?php

    $database = new Database($connParams);
    $user = new User($database);

?>

您还可以使用 setter 方法使用依赖注入来设置依赖项,但我会让您自己搜索 :)

就是这样,请阅读有关 Inversion of Controll 原理以及有关 Dependency Injection 和 Dependency Injection Containers 的内容,这些是管理类的最佳方法。

我见过很多“OOP”的 PHP 代码,实际上它们只使用类作为功能名称空间:) 所以请学习 OOP 原则和模式。

玩得开心!:)

于 2012-10-09T19:56:39.680 回答
2

不要在构造函数或其他方法中实例化对象。将它们作为参数传递,最好在称为工厂的不同类中传递。这将使测试您的代码变得容易,同时也使创建对象变得容易。

另外,不要尝试使用单例。这是“全局变量”的面向对象版本,您不想使用全局变量。它使您的代码测试变得非常困难,几乎是不可能的。

观看此视频http://www.youtube.com/watch?v=-FRm3VPhseI以了解为什么使用单例是不好的。尤其是 19:00 的 CreditCard 示例值得一看。

如果你真的想做最先进的,看看“依赖注入”的概念。从本质上讲,将需要的东西从外部传递到一个类中是整个秘密,但是有些框架会自动为你做这件事,所以你不必再自己编写工厂了。这些被称为“依赖注入容器”或“DIC”。

于 2012-10-09T19:42:26.343 回答
0

要为所有代码创建一个对象,请使用单例模式:

class Database{
   private $db_descriptor;

   private function __construct(){
       /* connect and other stuff */
   }
   public static function getInstance(){
       static $instance;
       if($instance === null){
          $instance = new self();
       }
       return $instance;
   }
}

您可以对用户使用相同的技术,我说更多使用 php 5.4 您可以将 1 特征用于单例模式。最后一个提示:当您使用数据库和其他繁重的事物时,请使用称为延迟初始化的技术。当您提高 OOP 技能时,请查看Doctrine Project,他们会大量使用该技术!

于 2012-10-09T19:40:16.483 回答