pcmnac/mongoyii-php7

适用于PHP7的Yii MongoDB ORM

安装: 11

依赖项: 0

建议者: 0

安全: 0

星标: 0

关注者: 1

分支: 12

类型:yii-extension

3.0.1 2018-12-14 17:18 UTC

This package is auto-updated.

Last update: 2024-09-15 05:34:16 UTC


README

这是一个专为PHP7和与新MongoDB驱动程序一起工作的mongoyii版本

关于本文档

这不是对旧文档的完全重写,而是仅详细说明PHP7扩展的新功能/理念。

如果您是mongoyii的新用户,请先阅读旧文档。.

测试应用程序

为此扩展提供了一个新的测试应用程序,这是对旧测试应用程序的重新编写。

您可以在以下位置找到它.

运行内置测试与之前相同。

问题/错误 & 问题

请使用新的Github问题跟踪器来处理您所有的问题和错误报告。如果在论坛中发布,请将其链接到Github问题跟踪器。

您可以通过以下链接访问Github问题跟踪器.

版本控制

此扩展,就像之前一样,使用语义版本控制2.0.0

许可证

此扩展的许可证也与之前相同,BSD 3条款。简而言之:您可以随意使用它。

关于更改的说明

在深入介绍此扩展中发生的变化之前,值得注意的是,许多更改并非出于我的意愿,而是因为MongoDB驱动程序和PHPLib它们发布的新版本,与旧驱动程序相比,其工作方式发生了巨大的变化,因此我不得不适应这种新的工作标准。

您可能喜欢驱动程序和其PHPLib的一些部分,而其他部分您可能肯定不会喜欢。

安装

所有安装现在都通过composer完成。我不建议手动安装,因为此扩展需要与MongoDB一起发布的驱动程序和PHPLib(这些也仅在composer中可用)。

要安装,请执行以下操作(针对 dev-master

composer require sammaye/mongoyii-php7:*

您可以在以下位置找到Packagist仓库.

命名空间

此扩展完全命名空间,如下所示

sammaye\mongoyii

不用担心!这不会给旧应用程序带来太多变化。我用了大约3个小时来重写我的测试应用程序。

例如,以下是如何声明一个新的模型(从我的测试应用程序中摘取)

use MongoDB\BSON\ObjectID;
use MongoDB\BSON\UTCDateTime;

use sammaye\mongoyii\Document;

/**
 * Represents the article itself, and all of its data
 */
class Article extends Document
{
}

这将给您带来与之前相同的一切。

现在,让我向您展示如何在main.php中配置sessioncache组件(同样,从我的测试应用程序中摘取)

'session' => array(
	'class' => 'sammaye\mongoyii\util\Session',
),
'cache' => array(
	'class' => 'sammaye\mongoyii\util\Cache',
),

因此,您可以看到使用命名空间非常容易上手。

作为最后的例子,让我们看看一个行为

public function behaviors()
{
	return [
		'TimestampBehavior' => [
			'class' => 'sammaye\mongoyii\behaviors\TimestampBehavior' 
			// adds a nice create_time and update_time Mongodate to our docs
		]
	];
}

所以,您可以看到:在这个扩展中使用命名空间非常简单。如果您不确定使用哪个命名空间,请查找项目中的文件,并查看第一行中提到的类似内容

namespace sammaye\mongoyii\validators;

将类名添加到那里,您就有了命名空间类。

声明扩展

这可能是变化最大的部分。首先,为什么不展示我使用的示例

'mongodb' => [
	'class' => 'sammaye\mongoyii\Client',
	'uri' => 'mongodb://sam:blah@localhost:27017/admin',
	'options' => [],
	'driverOptions' => [],
	'db' => [
		'super_test' => [
			'writeConcern' => new WriteConcern(1),
			'readPreference' => new ReadPreference(ReadPreference::RP_PRIMARY),
		]
	],
	'enableProfiling' => true
],

现在,让我们分析一下这个例子

  • 我将类声明为 sammaye\mongoyii\Client。这是必需的,且不会变化。
  • uri 是我的服务器连接字符串,遵循 PHP 文档 中规定的标准。
  • options 直接关联到 PHP 文档 中的 uri 选项,允许连接副本集等。
  • 同样,驱动程序选项也在 PHP 文档 中。
  • enableProfiling 允许您像以前一样对查询进行性能分析。
  • db 现在已改为按您要连接的数据库名称索引的数组。每个索引的值是 PHPLib Database 对象 的选项。

基本上就是这样。写入关注、读取关注和其他属性现在按数据库执行,而不是在客户端级别。

如果您在配置中还有其他数据库,并想将其设置为默认数据库,可以像下面这样添加 active 选项。

'super_test' => [
	'writeConcern' => new WriteConcern(1),
	'readPreference' => new ReadPreference(ReadPreference::RP_PRIMARY),
	'active' => true
]

客户端 __get 只获取数据库吗?

是的,这是旧驱动程序与新驱动程序之间最大的变化。

客户端、数据库和集合之间现在有明确的分离。

因此,要获取数据库,准备获取集合,您现在需要这样做:

Yii::$app->mongodb->selectDatabase()

身份验证

在新 PHP 驱动程序中,没有 auth() 函数。您必须在 mongodb 组件的 uri 中进行身份验证。您将决定如何最好地处理您的身份验证数据库,但我将所有用户放入 admin 数据库中。这使得我能够非常容易地对一个数据库进行身份验证,然后按需切换。

使用多个数据库

如您所见,此扩展考虑了多个数据库。

如果您使用身份验证,请确保您以某种方式布置用户,以便您只需要一个套接字连接(像我上面那样),或者为每次需要身份验证创建一个新的组件。您不能再在连接之后进行身份验证。

至于重新编码 DocumentgetDbConnection(),您现在可以使用 getCollection() 如此(由于上述的分离)。

public function getCollection()
{
	return $this
		->getDbConnection()
		->selectDatabase('my_other_db_not_default')
		->{$this->collectionName()};
}

完成了...

如果您真的知道自己在做什么,您可以实际设置一个数据库为 active,使其成为一系列过程的默认数据库。

Yii::$app->mongodb->selectDatabase('my_other_db', ['active' => true]);

但这仅适用于高级用户!

查询

这是从 Yii1 以来最大的变化。其他一切都保持不变,不需要记录。

基本上,由于新驱动程序不再使用游标,而是使用流,我已经将 EMongoDBCriteria 对象重编为 Query(类似于 Yii2),并且它甚至在功能上与 Yii2 类似。

然而,值得注意的是,find()findOne()Document 函数返回与正常 Yii1 相同的结果。那里的返回没有变化。

值得注意的是,查询的方式已经改变,这与驱动程序一致。

Article::find(
	[
		'title' => 'Test'
	],  
	[
		'sort' => ['date_created' => -1],
		'limit' => 2
		// etc
	]
)

这是由于 MongoDB 使用贪婪加载的流。因此,整个查询必须在现在形成 PHP "游标" 对象之前定义。

了解如何使用新驱动程序进行查询的好方法是查看 MongoDB PHPLib 的 GitHub 文档。

作用域

由于 EMongoCriteria 的变化,您可能需要重新编写模型作用域才能使其正常工作。一个很好的例子是:

[
	'condition' => ['deleted' => 0],
	'select' => ['_id' => 1],
	'sort' => ['date' => -1],
	'limit' => 2
	'skip' => 1
]

在公开场合您不会看到很多变化,其中最大的变化是我不再在SQL中的SELECT语句中使用project这个词。MongoDB仍然使用,但我不再使用了。

为什么没有EMongoCriteria?

这是为了实现干净和可操作的查询而做出的决定。

最后,我决定使我的查询更像Yii2。这实际上意味着您现在可以这样做

$docs = new Query([
	'from' => 'colllection',
	'condition' => ['what' => 'ever'],
	'limit' => 1
])->all()

所以,这是一个从Yii1到Yii2的突破,但这是一个好的突破。

查询记录

查询记录现在更加广泛。不再只是通过模型记录查询,现在将记录所有查询,这得益于一个小改写,这本来就应该在原始扩展中。

现在,每当您从配置中的MongoDB组件获取集合时,它将返回我自己的自定义Collection类,该类与记录结合在一起。

希望这可以减少构建应用程序时的猜测工作。

关于怪癖的说明

子文档

MongoDB驱动程序的PHPLib将子文档作为ArrayObject返回。这意味着在将它们用于显示和表单等之前,您需要首先通过(array)$subdoc进行类型转换。

BSON序列化

请确保不要使用ObjectID作为您的yii会话ID。这是因为这个问题,您无法序列化BSON对象。

例如,这里是一个可以使用的UserIdentity authenticate()方法(也取自我的示例应用程序)

public function authenticate()
{
	$record=User::model()->findOne(array('username' => $this->username));
	if ($record === null) {
		$this->errorCode = self::ERROR_USERNAME_INVALID;
	} else if ($record->password !== crypt($this->password, $record->password)) { // check crypted password against the one provided
		$this->errorCode = self::ERROR_PASSWORD_INVALID;
	} else {
		$this->_id = (String)$record->_id;
		$this->errorCode = self::ERROR_NONE;
	}
	return !$this->errorCode;
}

注意这一行:$this->_id = (String)$record->_id;它非常重要,否则将无法正常工作!

DBRef已弃用

是的,它已经弃用了。如果您在使用它,在使用此扩展之前需要将其删除。新的驱动程序中根本没有处理它的功能。

未完成的事情

GridFS

这不是我的错。实际上,PHPLib中还没有。

到此为止!

这就是全部了。其他的东西几乎都是一样的,很酷,对吧?

请告诉我,如果我没有遗漏任何内容或者需要更好地解释某些内容。