5

我只是想知道是否有人可以帮助我了解如何充分利用 PHP 中的对象。

我对 PHP 对象的理解是它应该代表一个实体,提供获取和更改该实体属性的方法。例如,名为 Post 的对象将包含单个帖子的所有属性,可以根据需要对其进行访问和修改。

让我有些困惑的是,像 CodeIgniter 这样的库在这个庄园中不使用对象。他们将类更像是一组函数的包装器。因此,CodeIgniter 中的“帖子”类不会保存一篇帖子的属性,它会提供获取、编辑和删除帖子的功能。

那么如果我想从数据库中取出每篇文章并将其放入 Post 对象中会发生什么?我对它的理解是,我实际上需要两个类“Posts”和“Post”,一个定义 Post 对象,另一个处理从数据库中获取 Posts 并将它们放入 Post 对象。

这两种类型的类是否有名称(“正确”对象/函数集合)?让两个类像这样一起工作是否很常见,或者我完全误解了如何使用对象?

在我的 Posts 类中使用一个名为 getSinglePost($id) 的方法而不是使用 Post 对象是否更有意义,它只返回一个数组?

希望这个问题有意义,期待得到一些反馈。

4

3 回答 3

5

有关介绍,请参阅PHP 中的类是什么?

对于答案,我将特别解决您的问题。搜索粗体字词以了解有关其含义的更多信息。

我对 PHP 对象的理解是它应该代表一个实体,提供获取和更改该实体属性的方法。

实体只是对象的一种可能用途。但也有Value ObjectsService ObjectsData Access Objects等等——当你走 OO 路线时,一切都会是一个有一定责任的对象。

让我有些困惑的是,像 CodeIgniter 这样的库在这个庄园中不使用对象。

是的,Code Igniter 并没有真正接受 OOP。他们更多地使用基于类的编程方法,这更像是使用类和少量 OOP 进行程序编程。

他们将类更像是一组函数的包装器。因此,CodeIgniter 中的“帖子”类不会保存一篇帖子的属性,它会提供获取、编辑和删除帖子的功能。

不过那很好。一个帖子类可以是Repository,例如一个帖子实体的内存集合,它具有在后台检索和持久化这些实体的额外责任。我会谨慎使用Design Patterns和 Code Igniter,因为众所周知它们使用自己的模式解释(例如,它们的Active Record更像是Query Object)。

那么如果我想从数据库中取出每篇文章并将其放入 Post 对象中会发生什么?

这里有很多选择。一种常见的方法是使用Data Mapper,但您也可以使用 PDO 并将数据行直接提取到 Post 对象等中。

我对它的理解是,我实际上需要两个类“Posts”和“Post”,一个定义 Post 对象,另一个处理从数据库中获取 Posts 并将它们放入 Post 对象。

那将是前面提到的存储库数据映射器方法。您通常将这些与Table Data Gateway结合使用。但是,另一种选择也可能是不具有 Posts 类并使用Active Record模式,它将数据库中的一行表示为附加了业务和持久性逻辑的对象。

这两种类型的类是否有名称(“正确”对象/函数集合)?让两个类像这样一起工作是否很常见,或者我完全误解了如何使用对象?

是的,他们一起工作。OOP 是关于对象协作的。

在我的 Posts 类中使用一个名为 getSinglePost($id) 的方法而不是使用 Post 对象是否更有意义,它只返回一个数组?

那将是一个返回Record Sets的表数据网关。当您没有大量业务逻辑并且可以保留Domain Model时,这很好,例如在CRUD应用程序中

于 2012-10-07T11:55:09.880 回答
0

你对一个对象的理解是正确的。帖子是一个类的单个对象Post。但是当然你需要一个函数,从数据库中检索帖子或从其他地方收集它们。因此,您有所谓的工厂类。这就是可能引起一些混乱的原因。

工厂可以是单例,这通常意味着您有一个此类的实例。但是您根本不需要实例化工厂(而是使用静态函数来访问该功能):

$posts = PostFactory::getPosts();

然后是函数:

static function getPosts() {
  $list = array();
  $sql = "select ID from posts order by datetime desc"; // example, ID is the primary key
  // run your sql query and iterate over the retrieved IDs as $id
  {
  ...
    $post = new Post($id);
    array_push($list, $post);
  }
  return $list;
}

在这个工厂中,您有一组“访问”功能,它们不适合其他地方,例如对象创建(数据库方面)和对象检索。对于第二部分(检索),如果没有“父”对象(就关系而言),只需将函数放入工厂。所以你可以有一个 class 的实体Blog,你实例化博客,然后通过博客实例检索博客的帖子,不需要单独的工厂。

命名只是为了帮助您理解。我不建议调用一个类Post并且它是工厂Posts,因为它们很容易混淆并且代码更难阅读(您需要注意细节)。我通常在类名中混合“工厂”这个词,所以我知道它实际上是一个工厂类,其他人也看到了。

此外,您还可以拥有与任何特定实体类无关的Helper类。所以你可以有一个PostHelper单例,它可以包含既不适合对象类也不适合工厂的功能。虽然我想不出任何对Post对象有用的功能。一个例子是一些软件,它计算东西,你有一个Helper,它使用不同类型的对象执行实际计算。

于 2012-10-07T11:54:54.033 回答
0

理想情况下,类也应该与 PHP 中的其他任何地方具有相同的解释。类从抽象开始,提炼你不需要的东西。因此,完全取决于您以您想要的方式定义类。Codeigniter 确实有一种奇怪的方式来启动和访问对象。主要是因为它们被加载一次并在以后使用,从而阻止它具有围绕数据的功能。有一些方法可以解决它,并且仍然可以正常处理类。我通常使用自动加载器并使用普通类。“那么,如果我想从数据库中取出每个帖子并将其放入 Post 对象中会发生什么?我对它的理解是,我实际上需要两个类 'Posts' 和 'Post',”你本质上是指一个模型来访问数据(“帖子”)和一个实体来表示“帖子”。

$this->load->model("posts");
$this->posts->get_all(); // <- This can then initiate set of objects of type "Post" and return. Or even standard classes straight out from DB.
于 2012-10-07T11:55:22.077 回答