PHP mysql_xdevapi 扩展:replaceOne() 似乎不是幂等的

问题描述

如果我在一个集合中用它自己替换一个文档,这个文档似乎被改变了。由于这个问题,我的数据变得无法使用。我做错了什么?

<?PHP

$login = '***removed***';
$pass = '***removed***';
$schema_name = 'dev';
$collection_name = 'test';

$session    = MysqL_xdevapi\getSession("MysqLx://$login:$pass@localhost");
$schema     = $session->getSchema($schema_name);
$collection = $schema->getCollection($collection_name);

// Delete all documents in the collection.
$collection->remove('true')->execute();

// Add one document and get its ID.
$result = $collection->add('{ "accent": "\u00e8" }')->execute();
$ids = $result->getGeneratedIds();
$doc_id = $ids[0];

// Read the document from the database.
$row = $collection->getone($doc_id);
print "1st getone() : " . $row['accent'] . "\n";

// Replace the document with itself.
$collection->replaceOne($doc_id,$row);

// Read the document from the database again.
$row = $collection->getone($doc_id);
print "2nd getone() : " . $row['accent'] . "\n";

// One more time.
$collection->replaceOne($doc_id,$row);

$row = $collection->getone($doc_id);
print "3rd getone() : " . $row['accent'] . "\n";

?>

上述脚本的输出

$ PHP test.PHP 
1st getone() : è
2nd getone() : \u00e8
3rd getone() : \\u00e8

我使用的是 PHP v7.3.19 和 MysqL_xdevapi v8.0.22。

解决方法

可能是转换问题。正如您在文档中看到的,add 和 replaceOne 方法接受集合对象或 JSON 文档:

https://www.php.net/manual/en/mysql-xdevapi-collection.add.php https://www.php.net/manual/en/mysql-xdevapi-collection.replaceone.php

在您的示例中,您在 add 方法中使用了一个 JSON 文档,但是当您使用 getOne 方法检索该文档时,结果是一个集合对象:https://www.php.net/manual/en/mysql-xdevapi-collection.getone.php

最后,当您尝试更新它时,您将使用之前生成的集合对象,并且集合对象和 JSON 对象的行为不同。

为了实现您想要的,我建议您使用集合对象而不是 JSON 对象创建第一个注册表,这应该可以避免在检索数据时出现字符集或转换问题。好看!

示例: [ '口音' => '\u00e8']