MongoDB对象映射(PHP)

MongoDB对象映射(PHP),php,mongodb,object,mapping,Php,Mongodb,Object,Mapping,导入问题: 当我从MongoCursor::getNext()接收到我的类T对象时,构建它的最佳实践是什么?就其本身而言,MongoCursor函数的getNext()返回一个数组。我希望将该点的结果用作类型为T的对象 我应该为接受数组的T类型编写自己的构造函数吗?是否有任何通用解决方案,例如,当类型T扩展了G,并且G以常规方式递归地(对于嵌套文档)执行此任务时 我是MongoDB新手,我想用一个漂亮的界面构建自己的通用映射器 赏金: 从PHP的角度来看,哪些是可能的方法、模式,哪些最适合Mo

导入问题:

当我从
MongoCursor::getNext()
接收到我的
类T
对象时,构建它的最佳实践是什么?就其本身而言,
MongoCursor
函数的
getNext()
返回一个
数组。我希望将该点的结果用作类型为
T
对象

我应该为接受数组的
T
类型编写自己的构造函数吗?是否有任何通用解决方案,例如,当类型
T扩展了G
,并且
G
以常规方式递归地(对于嵌套文档)执行此任务时

我是MongoDB新手,我想用一个漂亮的界面构建自己的通用映射器

赏金:

  • 从PHP的角度来看,哪些是可能的方法、模式,哪些最适合MongoDB的概念

    • 这个答案已经改写

      大多数数据映射器的工作方式是每个类表示一个对象,或者“模型”通常是一个虚构的术语。如果您希望允许通过单个对象(即
      $model->find()
      )进行多次访问,则通常会取消该对象的命名,以便该方法不会实际返回自身的实例,而是返回数组或
      MongoCursor
      将类加载到空间中的实例

      这种范例通常与“活动记录”有关。这是ORMs、odm和框架都使用的一种方法,用于以这样或那样的方式与数据库通信,不仅对于MongoDB,而且对于SQL和可能出现的任何其他数据库(Cassandra、CouchDB等)

      应该立即注意的是,即使活动记录提供了大量的能量,也不应该覆盖整个应用程序。有时,直接使用驱动程序会更有益。由于这个原因,大多数ORM、ODM和框架都提供了直接快速、轻松地访问驱动程序的能力

      正如许多人所说,没有轻量级的数据映射器。如果您要将返回的数据映射到类,那么它将消耗资源。这样做的好处是在操纵对象时获得的能量

      ActiveRecord非常擅长从PHP中提供事件和触发器。一个很好的例子是我为Yii制作的ORM:它可以为以下各项提供挂钩:

      • afterConstruct
      • beforeFind
      • afterFind
      • 在验证之前
      • afterValidate
      • 保存之前
      • afterSave
      需要注意的是,当涉及到像
      beforeSave
      afterSave
      这样的事件时,MongoDB没有触发器(),因此应用程序应该处理这一点是有意义的。除了应用程序处理此问题的明显原因之外,它还可以通过调用本机PHP函数来操作在接触数据库之前保存的每个文档,从而更好地处理save函数

      大多数数据映射程序也使用PHP自己的类CRUD来表示它们的类。例如,要创建新记录,请执行以下操作:

      $d=new User();
      $d->username='sammaye';
      $d->save();
      
      这是一个很好的方法,因为您创建了一个“新”(显示了我如何准备MongoYii中的新记录)类来创建一个“新”记录。它在语义上非常合适

      更新函数通常通过读取函数访问,您无法更新不知道存在的模型。这将使我们进入填充模型的下一步

      为了处理填充模型,不同的ORM、ODM和框架采用不同的方法。例如,我的MongoYii扩展在每个类中都使用一个名为
      model
      的工厂方法来带回它自己的一个新实例,这样我就可以调用动态
      find
      findOne
      以及其他类似的方法

      一些ORM、ODM和框架提供读取函数作为直接
      静态
      函数,使它们成为工厂方法,而一些使用单例模式,但是,我选择不使用()

      大多数(如果不是全部的话)实现了某种形式的游标。这用于返回模型的倍数,并直接(通常)包装
      MongoCursor
      ,以将
      current()
      方法替换为返回预填充模型

      例如呼叫:

      User::model()->find();
      
      将返回一个
      EMongoCursor
      (在MongoYii中),这将说明类
      User
      用于实例化游标的事实,调用时如下所示:

      foreach(User::model() as $k=>$v){
          var_dump($v);
      }
      
      将在此处调用
      current()
      方法:返回模型的一个新实例

      有一些ORMs、odm和框架实现了急切的数组加载。这意味着他们将把整个结果作为一组模型直接加载到RAM中。我个人不喜欢这种方法,因为在需要添加到旧记录的地方添加了一些新功能,所以当您需要使用active record进行更大的更新时,这种方法是浪费的,也不是好兆头

      在我继续之前的最后一个主题是MongoDB的无模式性。在MongoDB中使用PHP类的问题是,您需要PHP的所有功能,但MongoDB的可变特性。这在SQL中很容易克服,因为它有一个预定义的模式,您只需查询它和完成的作业;然而,MongoDB没有这样的东西

      这确实使得MongoDB中的模式处理非常危险。大多数ORM、ODM和框架要求您使用
      private
      变量和
      get
      set
      方法在现场预先定义模式(即条令2)。在MongoYii中,为了让我的生活变得轻松优雅,我决定通过使用能够检测属性在类中不可访问、字段在内部
      \u attributes
      数组中的魔法(是我的
      \u get
      还是我的
      \u set
      )来保持MongoDB的无模式性