Giter Club home page Giter Club logo

mongo-php-adapter's Introduction

Mongo PHP Adapter

Build Status Code Coverage Scrutinizer Code Quality

The Mongo PHP Adapter is a userland library designed to act as an adapter between applications relying on ext-mongo and the new driver (ext-mongodb).

It provides the API of ext-mongo built on top of mongo-php-library, thus being compatible with PHP 7.

Goal

This library aims to provide a compatibility layer for applications that rely on libraries using ext-mongo, e.g. Doctrine MongoDB ODM, but want to migrate to PHP 7 on which ext-mongo will not run.

You should not be using this library if you do not rely on a library using ext-mongo. If you are starting a new project, please check out mongodb/mongodb.

Installation

This library requires you to have the mongodb extension installed, and it conflicts with the legacy mongo extension.

The preferred method of installing this library is with Composer by running the following from your project root:

$ composer config "platform.ext-mongo" "1.6.16" && composer require alcaeus/mongo-php-adapter

The above command first marks the mongo extension as installed, then requires this adapter. This is to work around a bug in composer, see composer/composer#5030.

Known issues

Return values and exceptions

Some methods may not throw exceptions with the same exception messages as their counterparts in ext-mongo. Do not rely on exception messages being the same.

Methods that return a result array containing a connectionId field will always return 0 as connection ID.

Errors

All errors and warnings triggered by ext-mongo are triggered as E_USER_WARNING and E_USER_ERROR because trigger_error doesn't accept the E_WARNING and E_USER codes. If you rely on these error codes in your error handling routines, please update your code accordingly.

Serialization of objects

Serialization of any Mongo* objects (e.g. MongoGridFSFile, MongoCursor, etc.) will not work properly. The objects can be serialized but are not usable after unserializing them.

Mongo

  • The Mongo class is deprecated and was not implemented in this library. If you are still using it please update your code to use the new classes.

MongoLog

  • The MongoLog class does not log anything because the underlying driver does not offer a method to retrieve this data.

MongoClient

  • The connect and close methods are not implemented because the underlying driver connects lazily and does not offer methods for connecting disconnecting.
  • The getConnections method is not implemented because the underlying driver does not offer a method to retrieve this data.
  • The killCursor method is not yet implemented.

MongoDB

  • The authenticate method is not supported. To connect to a database with authentication, please supply the credentials using the connection string.
  • The $cmd collection cannot be used due to an issue in the underlying driver. To run commands, use the command method instead of querying the virtual $cmd collection.

MongoCollection

  • The insert, batchInsert, and save methods take the first argument by reference. While the original API does not explicitely specify by-reference arguments it does add an ID field to the objects and documents given.
  • The parallelCollectionScan method is not yet implemented.

MongoCursor

  • The info method does not reliably fill all fields in the cursor information. This includes the numReturned and server keys once the cursor has started iterating. The numReturned field will always show the same value as the at field. The server field is lacking authentication information.
  • The setFlag method is not yet implemented.
  • The timeout method will not change any query options. Client-side timeouts are no longer supported by the new driver. Use the maxTimeMS setting as a replacement.

MongoCommandCursor

  • The createFromDocument method is not yet implemented.
  • The info method does not reliably fill all fields in the cursor information. This includes the at, numReturned, firstBatchAt and firstBatchNumReturned fields. The at and numReturned fields always return 0 for compatibility to MongoCursor. The firstBatchAt and firstBatchNumReturned fields will contain the same value, which is the internal position of the iterator.

Development

If you are working on patches to this driver, you can run the unit tests by following these steps from the root of the repo directory:

$ composer install
$ vendor/phpunit/phpunit/phpunit --verbose

It assumes that the the localhost is running a mongod server. Here is a sample command to start mongod for these tests:

$ mongod --smallfiles --fork --logpath /var/log/mongod.log --setParameter enableTestCommands=1

The tests also assume PHP 5.6+ and the ext-mongodb extension being available.

mongo-php-adapter's People

Contributors

alcaeus avatar carusogabriel avatar damienalexandre avatar derickr avatar dermanomann avatar dzuelke avatar emirb avatar gergderkson avatar guilliamxavier avatar idr0id avatar jmikola avatar kevindh89 avatar malarzm avatar marcinrosinski avatar martinatsli avatar noisebynorthwest avatar nonameffh avatar peterrehm avatar stephanedelprat avatar stevan-tosic avatar vntw avatar webmozart avatar yurok1505 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

mongo-php-adapter's Issues

BulkWrite error :: '$set' is empty. You must specify a field like so: {$set: {<field>: ...}}

Hey,

We recently switched our production server to PHP7:

$ php -v
PHP 7.0.4-7+deb.sury.org~trusty+2 (cli) ( NTS )
Copyright (c) 1997-2016 The PHP Group
Zend Engine v3.0.0, Copyright (c) 1998-2016 Zend Technologies
    with Zend OPcache v7.0.6-dev, Copyright (c) 1999-2016, by Zend Technologies

And using the new Mongodb driver (1.1.5).

We noticed that sometimes there's a weird behaviour but unfortunately I can't reproduce it yet. When I run the code on dev it works perfectly. I am seeing the following error:

BulkWrite error :: '$set' is empty. You must specify a field like so: {$set: {<field>: ...}}
app/vendor/composer/mongodb/mongodb/src/Operation/Update.php (121)
MongoDB\Driver\Server::executeBulkWrite


File:      app/vendor/composer//mongodb-odm-light/lib/Doctrine/MongoDB/Collection.php in line 1397
Method:    MongoCollection->update
Parameter: [['_id' => 'req-a10cd3c3-8485-4d21-9928-239379251472'], ['$set' => ['creatorHostname' => 'prod.cloud.net', 'handledAt' => MongoDate]], ['upsert' => true]]

File:      app/vendor/composer/alcaeus/mongo-php-adapter/lib/Mongo/MongoCollection.php in line 387
Method:    Alcaeus\MongoDbAdapter\ExceptionConverter::toLegacy
Parameter: [MongoDB\Driver\Exception\BulkWriteException]

As you can see, the $set parameter is definitely not empty. I have tried to debug a bit but still can't figure this issue.

I am not sure if this bug should be here or maybe in https://github.com/mongodb/mongo-php-driver/issues

The moment I have a way to reproduce it, will attach a code snippet but maybe in the meanwhile there's something I have missed.

Thank you

Nesting level too deep - recursive dependency?

I'm using:

  • archlinux x86_64
  • php 7.0.5
  • mongodb 3.2.3
  • php mongodb extension 1.1.6
  • Symfony 3.0.4
  • doctrine-mongodb 1.3.0
  • doctrine-mongodb-odm-bundle 3.1.0

I've updated the adapter from 1.0.2 to 1.0.3 on my production server and receive after browser the site for a few seconds the following exception:

"Error: Nesting level too deep - recursive dependency?" at /..vendor/alcaeus/mongo-php-adapter/lib/Alcaeus/MongoDbAdapter/TypeConverter.php line 103

After this exception, browsing any site is impossible, until php-fpm and cache get's restarted / removed. It's so far reproducable, as it always occur after a few seconds on simple browsing the site (nothing get's persisted, only data get fetched from db).

I've switched back to 1.0.2, where this exception did not occur.

MongoCollection->aggregate makes php error with pipeline operators given as arguments

The thing is the first argument is overwritten. :(

Bad code:

        if (! TypeConverter::isNumericArray($pipeline)) {
            $pipeline = [];
            $options = [];

            $i = 0;
            foreach (func_get_args() as $operator) {

Good code:

        if (! TypeConverter::isNumericArray($pipeline)) {
            $operators = func_get_args();
            $pipeline = [];
            $options = [];

            $i = 0;
            foreach ($operators as $operator) {

If the func_get_args is called after$pipeline = [], the first value of the array will be an empty array.

Test case, and pull request is in progress.

How to use it for application without composer?

You did a wonderful job! But I want to use it for RockMongo but it doesn't use composer for package managing, so can this adapter work for it? I would appreciate it a lot if you can help me.

find([]) with error Method MongoDB::__toString() must return a string value

selectDB('test'); $test1 = $client->selectCollection($db, 'test1'); $test2 = $client->selectCollection($db, 'test2'); $test1->drop(); $test2->drop(); for ($i = 0; $i < 5; $i ++) { $inertData = array( 'a' => $i, 'b' => time() ); var_dump($test1->insert($inertData)); $inertData1 = array( 'a' => $i, 'b' => time() ); var_dump($test2->insert($inertData1)); } $test1->findOne(array());//<--- is ok $cursor = $test1->find(array());//<--- error error info: PHP Catchable fatal error: Method MongoDB::__toString() must return a string value in D:\MyCode\mongo-php-adapter-test\vendor\alcaeus\mongo-php-adapter\lib\Mongo\MongoCollection.php on line 91

Ensure type conversion between drivers

The TypeConverter class should ensure that all objects/arrays are properly converted:

  • ext-mongo methods always return an array
  • ext-mongo methods only return types from ext-mongo
  • Adapter converts any ext-mongo types to their ext-mongodb counterparts before passing them along

Implement MongoDB class

Note: some methods return dummy values to ensure basic CRUD functionality. These will have to be properly implemented.

  • Implement missing methods

MongoCursor hasNext iteration problem if nest find ๏ผŒcursor will not iteration

<?php
include "vendor/autoload.php";

$client = new MongoClient('mongodb://127.0.0.1:27017');
$test1 = $client->selectCollection('test', 'test1');
$test2 = $client->selectCollection('test', 'test2');
$test1->drop();
$test2->drop();

for ($i = 0; $i < 5; $i ++) {
    $inertData = array(
        'a' => $i,
        'b' => time()
    );
    var_dump($test1->insert($inertData));
    $inertData1 = array(
        'a' => $i,
        'b' => time()
    );
    var_dump($test2->insert($inertData1));
}

$cursor = $test1->find([],['a'=>true]);
$cursor->limit(10);
$cursor->sort(array(
    '_id' => - 1
));

$data = array();
while ($cursor->hasNext()) {
    $row = $cursor->getNext();
    $test2->count(array(
        'a' => $row['a']
    ));
    $data[] = $row;
}

var_dump($data);

**# the correct result is a from 0 to 4

but the real result is :
double 3 like this:**

array(5) {
  [0]=>
  array(2) {
    ["_id"]=>
    object(MongoId)#43 (1) {
      ["objectID":"MongoId":private]=>
      object(MongoDB\BSON\ObjectID)#36 (1) {
        ["oid"]=>
        string(24) "5704d1c991a65e2384002817"
      }
    }
    ["a"]=>
    int(3)
  }
  [1]=>
  array(2) {
    ["_id"]=>
    object(MongoId)#48 (1) {
      ["objectID":"MongoId":private]=>
      object(MongoDB\BSON\ObjectID)#47 (1) {
        ["oid"]=>
        string(24) "5704d1c991a65e2384002817"
      }
    }
    ["a"]=>
    int(3)
  }
  [2]=>
  array(2) {
    ["_id"]=>
    object(MongoId)#45 (1) {
      ["objectID":"MongoId":private]=>
      object(MongoDB\BSON\ObjectID)#44 (1) {
        ["oid"]=>
        string(24) "5704d1c991a65e2384002815"
      }
    }
    ["a"]=>
    int(2)
  }
  [3]=>
  array(2) {
    ["_id"]=>
    object(MongoId)#52 (1) {
      ["objectID":"MongoId":private]=>
      object(MongoDB\BSON\ObjectID)#51 (1) {
        ["oid"]=>
        string(24) "5704d1c991a65e2384002813"
      }
    }
    ["a"]=>
    int(1)
  }
  [4]=>
  array(2) {
    ["_id"]=>
    object(MongoId)#54 (1) {
      ["objectID":"MongoId":private]=>
      object(MongoDB\BSON\ObjectID)#53 (1) {
        ["oid"]=>
        string(24) "5704d1c991a65e2384002811"
      }
    }
    ["a"]=>
    int(0)
  }
}

broken findAndModify call

In our codebase we do have a findAndModify call that looks something like this:

$result = $collection->findAndModify(
  array(
    "path"=> "phpunit.test",
  ),
  array(),
  array(),
  array(
    "update"=> array(
      "path"=> "bar.foo",
      "position"=> 1,
      "indexable"=> true,
    ),
    "new"=> true
  )
);

The adapter throws the following exception:

PHP Fatal error:  Uncaught MongoDB\Driver\Exception\RuntimeException: need remove or update in ./vendor/mongodb/mongodb/src/Operation/FindAndModify.php:137
Stack trace:
#0 ./vendor/mongodb/mongodb/src/Operation/FindAndModify.php(137): MongoDB\Driver\Server->executeCommand('mongodb_test', Object(MongoDB\Driver\Command))
#1 ./vendor/mongodb/mongodb/src/Operation/FindOneAndReplace.php(113): MongoDB\Operation\FindAndModify->execute(Object(MongoDB\Driver\Server))
#2 ./vendor/mongodb/mongodb/src/Collection.php(526): MongoDB\Operation\FindOneAndReplace->execute(Object(MongoDB\Driver\Server))
#3 ./vendor/alcaeus/mongo-php-adapter/lib/Mongo/MongoCollection.php(513): MongoDB\Collection->findOneAndReplace(Object(MongoDB\Model\BSONDocument), Array, Array)
#4 ./mongo_bug.php(45): MongoCollection->findAndModify(Object(MongoDB\Model\BSONDocument) in ./vendor/alcaeus/mongo-php-adapter/lib/Alcaeus/MongoDbAdapter/ExceptionConverter.php on line 83

There is an index on path.

MongoCursor hasNext iteration problem if nest find ๏ผŒcursor will not iteration

    $datas = array();
    $cursor = $this->_collection->find($query, array(
        'hookLastResponseResult' => false
    ));
    $cursor->sort($sort);
    $cursor->skip($start)->limit($limit);
    while ($cursor->hasNext()) {
        $row = $cursor->getNext();
        if (! isset($row['isEditSafe'])) {
            $row['isEditSafe'] = true;
        }
        $row['locked'] = false;
        $lockInfo = $this->_lock->count(array(
            'project_id' => $this->_project_id,
            'collection_id' => myMongoId($row['_id']),
            'active' => true
        ));
        if ($lockInfo > 0) {
            $row['locked'] = true;
        }

        // ๅˆคๆ–ญๅฝ“ๅ‰้›†ๅˆๆ˜ฏๅฆ้ป˜่ฎคๆ•ฐๆฎ้›†ๅˆ๏ผŒๅฆ‚ๆžœๆ˜ฏๆ˜พ็คบๆญฃ็กฎ็š„้›†ๅˆ
        if ($this->_plugin_data->isDefault(myMongoId($row['_id']))) {
            $row['defaultSourceData'] = true;
        } else {
            $row['defaultSourceData'] = false;
        }
        $row['indexNumber'] = $this->_index->getIndexNumber(myMongoId($row['_id']));

        $datas[] = $row;
    }

var_dump($datas);

Drop in Performance compared to \MongoClient() or mongo-php-library

I'm about to migrate a PHP webapplication w/ MongoDB as main database to PHP7.

The adapter works quite good as drop in replacement.

When I did some performance tests i noted a significant drop in performance.

I iterated over a collection w/ ~1.000.000 documents and got following execution time results:

  • php5 ~5sec (legacy \MongoClient())
  • php7 ~6-7 sec (w/ mongo-php-library)
  • php7 ~18 sec (w/ mongo-php-adapter+mongo-php-library)

[...]
$coll = $mongo->selectCollection('examples.demo');
$allDocs = $coll->find();
foreach ($allDocs as $doc) {
[...]

Are there any possible tweaks to get the execution time down to be in the same time range as the mongo-php-library?

MongoDB\BSON\UTCDateTime

Just after update to php7 with doctrine mongoDb, have this error:

MongoResultException: MongoDB\BSON\UTCDateTime::__construct() expects parameter 1 to be integer, float given

The error stack:

\vendor\alcaeus\mongo-php-adapter\lib\Mongo\MongoDate.php:80
\vendor\alcaeus\mongo-php-adapter\lib\Alcaeus\MongoDbAdapter\TypeConverter.php:43
\vendor\alcaeus\mongo-php-adapter\lib\Alcaeus\MongoDbAdapter\TypeConverter.php:49
\vendor\alcaeus\mongo-php-adapter\lib\Alcaeus\MongoDbAdapter\TypeConverter.php:49
\vendor\alcaeus\mongo-php-adapter\lib\Mongo\MongoCollection.php:339
\vendor\doctrine\mongodb\lib\Doctrine\MongoDB\Collection.php:966
\vendor\doctrine\mongodb\lib\Doctrine\MongoDB\Collection.php:152
\vendor\doctrine\mongodb\lib\Doctrine\MongoDB\LoggableCollection.php:102
\vendor\doctrine\mongodb-odm\lib\Doctrine\ODM\MongoDB\Persisters\DocumentPersister.php:252
\vendor\doctrine\mongodb-odm\lib\Doctrine\ODM\MongoDB\UnitOfWork.php:1117
\vendor\doctrine\mongodb-odm\lib\Doctrine\ODM\MongoDB\UnitOfWork.php:425
\vendor\doctrine\mongodb-odm\lib\Doctrine\ODM\MongoDB\DocumentManager.php:526
\vendor\nelmio\alice\src\Nelmio\Alice\Persister\Doctrine.php:41
\src\AC\Tests\WebTestCase.php:44
\src\AC\Tests\MongoDbWebTestCase.php:24

Do you need more info ?

Class "MongoID" not found

Originally reported by @Diarselimi at doctrine/DoctrineMongoDBBundle#376:

Attempted to load class "ObjectID" from namespace "MongoDB\BSON".
Did you forget a "use" statement for another namespace?

in vendor/alcaeus/mongo-php-adapter/lib/Mongo/MongoId.php at line 215

            } elseif ($id instanceof self || $id instanceof ObjectID) {
                $this->objectID = new ObjectID((string) $id);
            } else {
                $this->objectID = new ObjectId();
            }
        } catch (\Exception $e) {
            throw new MongoException('Invalid object ID', 19);

MongoCollection::distinct returns an empty array when an array of MongoId's are used in an $in statement

With the following query I receive an empty array instead of a cursor like I expect.

$this->collection
       ->distinct(
           'sp',
           ['sl' => ['$in' => $sellerIds]]
      );

I know that data exists and should be returned via this query because I can change it to a find query and I get the 16 documents in a cursor like expected.

It seems to be something specific to passing MongoId's to the $in clause. I have distinct queries working where the array passed to $in is an array of strings instead of MongoId objects. Unfortunately this is all the info I have currently. I don't see queries in the logs so can't see what it is actually running. Let me know what I can do to help track down the issue (Or where I am missing something simple.

Changed to be the case

<?php include "vendor/autoload.php"; $alias = 'ABCDEFG'; try { new \MongoId($alias); var_dump($alias); } catch (\MongoException $ex) { var_dump($alias);//"abcdefg" }

hasNext

Hi, thx for this great work, you save my life, but i need use method hasNext, you have provision to implement this or suggestion to other form to make this ?

thx

Implement MongoClient class

  • Implement methods not yet implemented
  • Provide __get for properties such as $connected?
  • Ensure handling of read preference (must be passed on to other classes)

Can't call count on a cursor after a call to `iterator_to_array`has been made.

I am not sure if this is actually an issue or something that you feel should be supported. I noticed this behavior when trying to update a test.

Here is an example of some code using Doctrine to be able to recreate

PaginatedCursor.php

    class PaginatedCursor implements Paginatable
    {
        private $cursor;
        private $data;

        public function __construct(CursorInterface $cursor, $page = 1, $perPage = 20)
        {
            $this->cursor = $cursor;
            $this->page = $page > 0 ? $page : 1;
            $this->perPage = $perPage;
            $this->cursor
                ->skip($this->getOffset())
                ->limit($this->getLimit());
            $this->hasNextPage = $this->cursor->count(true) > $this->perPage;

            $this->data = new ArrayIterator(array_slice($this->cursor->toArray(), 0, $this->perPage));
        }

       public function count()
       {
           return $this->data->count();
       }
   }
$cursor = $this->container->get('admin.sellable.repo')->createQueryBuilder()
        ->getQuery()
        ->execute();

$paginatedCursor = new PaginatedCursor($cursor);
$paginatedCursor->count(true); // returns valid count.
dump($cursor->count(true));

The $cursor->count(true) call returns the following error.

Cannot traverse an already closed generator

So once a Generator has iterator_to_array called you can no longer call iterator_count on it. I know this is a language "issue" but wasn't sure if this was something you intended to support with the adapter. I don't think this is something that many will actually do in the wild.

Using mongo-php-adapter with mongodb-odm-bundle.

Updating an application using mongodb-odm-bundle to work with PHP 7 and can't get the mongo-php-adapter working. I got stuck on the following error:

MongoConnectionException: Authentication failed. in Alcaeus\MongoDbAdapter\ExceptionConverter::toLegacy() (line 83 of /srv/www/vendor/alcaeus/mongo-php-adapter/lib/Alcaeus/MongoDbAdapter/ExceptionConverter.php).

Turned out I hadn't updated the php version in composer.json!

Performance problems

Hi!

My project used the Doctrine 2.2.2 version and now we are moveing to a new server, where the Mongo 3.2 is installed with the mongodb driver (1.1.5). I had to upgrade the Doctrine to 2.7, so I have to use this adapter now.

My site is extremely slow now, so I've tried to find the problem with the xdebug profiler. The first rows of the output (the numbers are in percentage):

profiler_output

Is it possible? Is there any solution for this problem?

Parameter 1 to MongoCollection::insert() expected to be a reference, value given

Hi,
When we upgrade our website from php5.5 to php7.0.6. We got some warning like this:

PHP Warning: Parameter 1 to MongoCollection::insert() expected to be a reference, value given in /website/helper/mongo/collection.php on line 66.

And I saw the same question occurs on wordpress. May I remove the "&" in "alcaeus/mongo-php-adapter/lib/Mongo/MongoCollection.php::insert on line 277"?

exception: invalid operator '$filter' in aggregation via MongoCollection

Hi,

We can't do this aggregation with MongoClient

db.Collection.aggregate([
    {$project:{
        filtered: {
            $filter: {
                input: "$data",
                as: "item",
                cond: {
                    $eq: [
                        "$$item.foo",
                        1
                    ]
                }

            }
        }
    }}
]);

In PHP :

            $result = $collection->aggregate(
                array(
                    '$project' => array(
                        'filtered' => array(
                            '$filter' => array(
                                'input' => '$data',
                                'as' => 'item',
                                'cond' => array('$eq' => array('$$item.foo', 1))
                            )
                        ),
                    )
                )
            );

This exception is throw :

exception: invalid operator '$filter'

0 /vendor/alcaeus/mongo-php-adapter/lib/Mongo/MongoCollection.php(172): Alcaeus\MongoDbAdapter\ExceptionConverter::toLegacy(Object(MongoDB\Driver\Exception\RuntimeException), 'MongoResultExce...')

Setup with doctrine/mongodb-odm

Is it possible to configure doctrine/mongodb-odm to work with ext-mongodb instead of ext-mongo using alcaeus/mongo-php-adapter? I followed instructions included your adapter in doctrine/mongodb-odm@dev-master but yet while running tests, i've got plenty of errors...

modified doctrine/mongodb-odm composer.json:

"provide": {"ext-mongo": "1.6.12"},
    "require": {
        "php": "^5.5 || ^7.0",
        "ext-mongo": "^1.5",
        "symfony/console": "~2.3|~3.0",
        "doctrine/annotations": "~1.0",
        "doctrine/collections": "~1.1",
        "doctrine/common": "~2.4",
        "doctrine/cache": "~1.0",
        "doctrine/inflector": "~1.0",
        "doctrine/instantiator": "~1.0.1",
        "doctrine/mongodb": "dev-master",
        "alcaeus/mongo-php-adapter": "dev-master"
    },

Installing mongo-php-adapter via composer

Hi, I'm trying to find a solution for creating project with PHP7, Symfony3, MongoDB 3+, Doctrine combination. Doctrine ODM is not yet compatible...This mongo-php-adapter was suggested as workaround. But when I try to install it via composer in my symfony project I get the error:
Your requirements could not be resolved to an installable set of packages.

Problem 1
- Installation request for ext-mongo 1.6.12 -> satisfiable by ext-mongo[1.6.12].
- don't install alcaeus/mongo-php-adapter dev-master|remove ext-mongo 1.6.12
- Installation request for alcaeus/mongo-php-adapter dev-master -> satisfiable by alcaeus/mongo-php-adapter[dev-master].

So it expects ext-mongo 1.6.12 to be installed? But that's the main reason I have to use mongo-php-adapater...that ext-mongo 1.6.12 could not be installed for php7.
Am I missing something?
Thank you for your answer.

Receive exception Cannot do an empty bulk write message, when attempting a bulk write.

The adapter is attempting a replaceOne update on a document persisted and flushed with Doctrine. I receive the above Exception message and the error mongoc: WARNING > mongoc_bulk_operation_replace_one(): replacement document may not contain $ or . in keys. Ignoring document. from the mongo driver. I scanned the update produced and the only $ or . I see is in the Mongo IDs. I am thinking / wondering if this is a case where the type needs to be converted from Legacy? As always thanks for looking and let me know if you need more info. I provided the BSONDocument below, its rather large but wanted to provide the entire Document for context.

UPDATE: I pulled down the repo and transformed the below into an array changing ObjectId to new \MongoId() and UTCDateTime to new \MongoTimestamp() and I was able to insert and retrieve the document back out fine in a functional test.

MongoDB\Model\BSONDocument {#16059
  flag::STD_PROP_LIST: false
  flag::ARRAY_AS_PROPS: true
  iteratorClass: "ArrayIterator"
  storage: array:52 [
    "allowCredits" => true
    "attributeValueImageMap" => []
    "buyWithMeMode" => "i"
    "checklist" => MongoDB\Model\BSONDocument {#16034
      flag::STD_PROP_LIST: false
      flag::ARRAY_AS_PROPS: true
      iteratorClass: "ArrayIterator"
      storage: array:5 [
        "images" => true
        "productDetails" => true
        "published" => true
        "sellerCopy" => false
        "video" => false
      ]
    }
    "clearance" => false
    "createdAt" => MongoDB\BSON\UTCDateTime {#16035}
    "cs" => false
    "customizable" => false
    "description" => "<p>A <b>circle</b> is a simple <a href="http://en.wikipedia.org/wiki/Shape">shape</a> of <a href="http://en.wikipedia.org/wiki/Euclidean_geometry">Euclidean geometry</a> that is the set of all <a href="http://en.wikipedia.org/wiki/Point_%28geometry%29">points</a> in a <a href="http://en.wikipedia.org/wiki/Plane_%28mathematics%29">plane</a> that are at a given distance from a given point, the <a href="http://en.wikipedia.org/wiki/Centre_%28geometry%29">centre</a>. The distance between any of the points and the centre is called the <a href="http://en.wikipedia.org/wiki/Radius">radius</a>. It can also be defined as the locus of a point equidistant from a fixed point.<br></p>"
    "disc" => true
    "estimatedShippingDays" => 7
    "exclusive" => true
    "freeShipping" => false
    "handlingDetail" => "Our circles are delicate"
    "handlingFee" => 0
    "hasBeenLive" => true
    "introducedToFeed" => false
    "lastActivityDate" => MongoDB\BSON\UTCDateTime {#16036}
    "lastCommentDate" => MongoDB\BSON\UTCDateTime {#16037}
    "liveDate" => MongoDB\BSON\UTCDateTime {#16038}
    "ll" => MongoDB\BSON\UTCDateTime {#16039}
    "lockedAt" => MongoDB\BSON\UTCDateTime {#16040}
    "lockedBy" => null
    "loveCount" => 9
    "ltl" => MongoDB\Model\BSONDocument {#16041
      flag::STD_PROP_LIST: false
      flag::ARRAY_AS_PROPS: true
      iteratorClass: "ArrayIterator"
      storage: array:2 [
        "$ref" => "identities"
        "$id" => MongoDB\BSON\ObjectID {#15984}
      ]
    }
    "maxPrice" => 75.99
    "media" => MongoDB\Model\BSONDocument {#16047
      flag::STD_PROP_LIST: false
      flag::ARRAY_AS_PROPS: true
      iteratorClass: "ArrayIterator"
      storage: array:4 [
        "images" => array:1 [
          0 => MongoDB\Model\BSONDocument {#16045
            flag::STD_PROP_LIST: false
            flag::ARRAY_AS_PROPS: true
            iteratorClass: "ArrayIterator"
            storage: array:13 [
              "_id" => MongoDB\BSON\ObjectID {#15988}
              "h" => 594
              "highRes" => false
              "oq" => 90
              "percentWhitespace" => 91
              "pid" => "c14b55a"
              "processed" => true
              "processingQueued" => false
              "resolution" => MongoDB\Model\BSONDocument {#16042
                flag::STD_PROP_LIST: false
                flag::ARRAY_AS_PROPS: true
                iteratorClass: "ArrayIterator"
                storage: array:2 [
                  "x" => 72
                  "y" => 72
                ]
              }
              "t" => "jpeg"
              "updatedAt" => MongoDB\BSON\UTCDateTime {#16043}
              "versions" => MongoDB\Model\BSONDocument {#16044
                flag::STD_PROP_LIST: false
                flag::ARRAY_AS_PROPS: true
                iteratorClass: "ArrayIterator"
                storage: array:3 [
                  "original" => "images/2013/09/23/16/5240a14272989a9e5d000122.jpg"
                  "source" => "images/2013/09/23/16/5240a14272989a9e5d000122-source.jpeg"
                  "transformed" => "images/2015/04/14/08/5240a14272989a9e5d000122-transformed.jpeg"
                ]
              }
              "w" => 594
            ]
          }
        ]
        "unusedImages" => []
        "updatedAt" => MongoDB\BSON\UTCDateTime {#16046}
        "videoUrl" => ""
      ]
    }
    "metadata" => MongoDB\Model\BSONDocument {#16051
      flag::STD_PROP_LIST: false
      flag::ARRAY_AS_PROPS: true
      iteratorClass: "ArrayIterator"
      storage: array:7 [
        "comments" => []
        "copySourced" => false
        "financeApproved" => false
        "imageSourced" => false
        "productSourced" => false
        "readyForEmail" => false
        "team" => array:3 [
          0 => MongoDB\Model\BSONDocument {#16048
            flag::STD_PROP_LIST: false
            flag::ARRAY_AS_PROPS: true
            iteratorClass: "ArrayIterator"
            storage: array:1 [
              "role" => "Creator"
            ]
          }
          1 => MongoDB\Model\BSONDocument {#16049
            flag::STD_PROP_LIST: false
            flag::ARRAY_AS_PROPS: true
            iteratorClass: "ArrayIterator"
            storage: array:1 [
              "role" => "Buyer"
            ]
          }
          2 => MongoDB\Model\BSONDocument {#16050
            flag::STD_PROP_LIST: false
            flag::ARRAY_AS_PROPS: true
            iteratorClass: "ArrayIterator"
            storage: array:1 [
              "role" => "Producer"
            ]
          }
        ]
      ]
    }
    "minPrice" => 75.99
    "mrch" => MongoDB\BSON\ObjectID {#16023}
    "name" => "Circle"
    "numActivities" => 10
    "numComments" => 1
    "numPageViews" => 53
    "originator" => MongoDB\Model\BSONDocument {#16052
      flag::STD_PROP_LIST: false
      flag::ARRAY_AS_PROPS: true
      iteratorClass: "ArrayIterator"
      storage: array:2 [
        "$ref" => "originators"
        "$id" => MongoDB\BSON\ObjectID {#16021}
      ]
    }
    "primaryTaxon" => MongoDB\Model\BSONDocument {#16053
      flag::STD_PROP_LIST: false
      flag::ARRAY_AS_PROPS: true
      iteratorClass: "ArrayIterator"
      storage: array:2 [
        "$ref" => "taxonomy"
        "$id" => MongoDB\BSON\ObjectID {#16019}
      ]
    }
    "private" => false
    "product" => MongoDB\Model\BSONDocument {#16054
      flag::STD_PROP_LIST: false
      flag::ARRAY_AS_PROPS: true
      iteratorClass: "ArrayIterator"
      storage: array:3 [
        "type" => "simple"
        "$ref" => "products"
        "$id" => MongoDB\BSON\ObjectID {#16017}
      ]
    }
    "promoAllowCredits" => true
    "pt" => "simple"
    "returnPolicy" => 14
    "seller" => MongoDB\Model\BSONDocument {#16055
      flag::STD_PROP_LIST: false
      flag::ARRAY_AS_PROPS: true
      iteratorClass: "ArrayIterator"
      storage: array:2 [
        "$ref" => "sellers"
        "$id" => MongoDB\BSON\ObjectID {#16025}
      ]
    }
    "shippingDetail" => "Our circles are delicate"
    "shippingPrice" => 4.95
    "shippingPrices" => array:1 [
      0 => MongoDB\Model\BSONDocument {#16056
        flag::STD_PROP_LIST: false
        flag::ARRAY_AS_PROPS: true
        iteratorClass: "ArrayIterator"
        storage: array:3 [
          "zoneId" => 237
          "price" => 6.95
          "secondaryPrice" => 6.95
        ]
      }
    ]
    "slug" => "circle"
    "status" => "inactive"
    "subscription" => false
    "tags" => []
    "taxonomy" => array:1 [
      0 => MongoDB\Model\BSONDocument {#16057
        flag::STD_PROP_LIST: false
        flag::ARRAY_AS_PROPS: true
        iteratorClass: "ArrayIterator"
        storage: array:2 [
          "$ref" => "taxonomy"
          "$id" => MongoDB\BSON\ObjectID {#16026}
        ]
      }
    ]
    "updatedAt" => MongoDB\BSON\UTCDateTime {#16058}
    "voucher" => false
  ]
}

ReadPreference is lost when connection is created

There is an issue with the adapter when passing a custom readPreference.

The value is lost here:

$this->setReadPreferenceFromArray($conn->getReadPreference());

Because getReadPreference return null.

Using the new MondoDB extension directly work as expected. And it worked with the old extension too.

How to reproduce

You have to setup a replicaSet of course.

$url = "mongodb://127.0.0.1:27017,127.0.0.1:27018";
$params = ['username' => 'test', 'password' => 'test', 'db' => 'test', 'readPreference' => 'secondaryPreferred'];

$client = new \MongoClient($url, $params);

// Run a query to init everything
$cursor = $client->selectDB('stuffs')->selectCollection('stuffs')->find();
$cursor->next();

// It return mode 6, which is good
var_dump($client->getClient()->__debugInfo()['manager']->getReadPreference());
// It return the primary host, not good!
var_dump($cursor->info()['port']);

How to quick-fix

I added this line right after the client creation to tell which readPreference I wanted:

$client = new \MongoClient($url, $params);
$client->setReadPreference('secondaryPreferred');

Why not doing a PR?

Because I'm not sure of the best way to fix this behavior, this option can be set in two places:

  • in the server url: 127.0.0.1:27017?readPreference=secondaryPreferred
  • in the client option like in my exemple
    And I didn't found any code doing parameters lookup in this adapter.

I can work on it if a direction is given.

thanks! ๐Ÿป

Minimum required set to get up and running on Heroku fails: Package is not installed: ext-mongo-1.6.12.0

As Heroku is quite fast with adopting PHP 7, I am looking at using this.

After reading #58 and #30 I came up with a short test but even the most basic composer.json fails to install:

{
  "provide": {
    "ext-mongo": "1.6.12"
  },
  "require": {
    "alcaeus/mongo-php-adapter": "dev-master"
  }
}

Results in

composer selfupdate

Updating to version 93501a5e3f8433e982da3518e13896ee4c0e816b.
    Downloading: 100%         
Use composer self-update --rollback to return to version d6d0435c5437111e42a123b06e4071e26ba7cb6e

composer install --ignore-platform-reqs
Loading composer repositories with package information
Installing dependencies (including require-dev)


  [InvalidArgumentException]                    
  Package is not installed: ext-mongo-1.6.12.0  


install [--prefer-source] [--prefer-dist] [--dry-run] [--dev] [--no-dev] [--no-plugins] [--no-custom-installers] [--no-autoloader] [--no-scripts] [--no-progress] [-v|vv|vvv|--verbose] [-o|--optimize-autoloader] [-a|--classmap-authoritative] [--ignore-platform-reqs] [--] [<packages>]...

Also changed replace with provide, but same result...

Any idea where to look to at least get this installed?

Compatibility with Doctrine Mongo ODM

@alcaeus First of all thanks for great job!
I am planning to move one of my existing application to PHP7 and wanted to make sure if mongo-php-adapter is a (sort of) drop in replacement for the legacy driver with MongoDB ODM. Are there any known issues other than you have mentioned in the README.md? Just a bit reluctant.

Nesting level too deep - recursive dependency?

Hello,

this error keep poping up lately, for unknown reason, it might have something to do with upgrading to PHP 7 ?

E_ERROR: Nesting level too deep - recursive dependency? (/var/core/vendor/alcaeus/mongo-php-adapter/lib/Alcaeus/MongoDbAdapter/TypeConverter.php:103)

Compatibility with doctrine odm

Hi,

when used with doctrine odm the function MongoCollection::batchInsert, more precisely the call to $this->collection->insertMany() raises an error because a stdClass is passed instead of arrays

this is a very quick fix done on directly on my server

    $data = (array)array_values((array)TypeConverter::fromLegacy($a))[0];
    $data = [$data];

     $result = $this->collection->insertMany(
        $data,
            //(array) TypeConverter::fromLegacy($a),
            $this->convertWriteConcernOptions($options)
     );

maybe this will help someone

Ensure exceptions are properly handled

All ext-mongodb exceptions must be properly caught and converted to their respective ext-mongo exceptions

Note: it might make sense to add a generic proxy function taking care of exception conversion.

Add classes for batch operations

  • Add and implement MongoWriteBatch
  • Add and implement MongoInsertBatch
  • Add and implement MongoUpdateBatch
  • Add and implement MongoDeleteBatch

Implement GridFS handling

  • Implement missing methods in MongoGridFS
  • Implement missing methods in MongoGridFSCursor
  • Implement missing methods MongoGridFSFile

Undefined property: MongoDB\BSON\UTCDateTime::$sec

A lot of our code uses the sec property on mongo date objects.

e.g

$mydate->sec;

This works fine on the old Mongo PHP driver but using this adapter returns an Undefined property. Is there an alternate solution or fix?

MongoCursor::timeout()

The new mongo driver does not ship with a way to set a cursor timeout. It seems like there is this functionality in the C driver though. There is now a ticket for this: https://jira.mongodb.org/browse/PHPC-576

Once that ticket is resolved, we should be able to set the timeout in the adapter as well.

How to set driverOptions ?

I am testing to connect to a mongod with ssl and uncertified certificate.
How can I set the $driverOptions in "mongo-php-adapter\lib\Mongo\MongoClient.php" constructor ? I don't see any parameters in the bundle to do it.

I'd like to create a stream context as explain at http://php.net/manual/fr/mongo.connecting.ssl.php ... or maybe there is a better way to do ?

Can't query on admin.$cmd.sys.inprog to get currentOp

Hi,

With the old MongoClient we can do

$client = new \MongoClient('mongodb://root:foooBarrrrr@localhost:27017?authSource=admin');
$collection = $client->selectDb('admin')->selectCollection('$cmd.sys.inprog');
$currentOp = $collection->findOne();
$inprog = isset($currentOp['inprog'])?$currentOp['inprog']:array();
var_dump($inprog);

An other solution to do that ?

The exception throw by MongoPhpAdapter :

The application has thrown an exception!

MongoException

Invalid collection name: admin.$cmd.sys.inprog

/vendor/alcaeus/mongo-php-adapter/lib/Alcaeus/MongoDbAdapter/ExceptionConverter.php:83

/vendor/alcaeus/mongo-php-adapter/lib/Mongo/MongoCollection.php(558): Alcaeus\MongoDbAdapter\ExceptionConverter::toLegacy(Object(MongoDB\Driver\Exception\RuntimeException))

Previous Exception(s):

MongoDB\Driver\Exception\RuntimeException

Invalid collection name: admin.$cmd.sys.inprog

/vendor/mongodb/mongodb/src/Operation/Find.php:180
#0 /vendor/alcaeus/mongo-php-adapter/lib/Mongo/MongoCollection.php(558): Alcaeus\MongoDbAdapter\ExceptionConverter::toLegacy(Object(MongoDB\Driver\Exception\RuntimeException))

Error message using $set

The following code snippet works fine with using ext/mongo directly:

            $res = $this->_db->findAndModify(
                array(
                    self::SID => $id,
                    self::LOCK => array('$exists' => $exist_check)
                ),
                array($data),
                array(self::DATA => true),
                array(
                    'update' => array('$set' => $data),
                    'upsert' => !$exists
                )
            );

but throws the following error when using mongo-php-adapter:

MongoResultException: exception: The dollar ($) prefixed field '$set' in '$set' is not valid for storage.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.