Are there any plans to add support for the new PHP7 driver? See https://www.mongodb.com/blog/post/call-feedback-new-php-and-hhvm-drivers.
Background
In PHP 5.*, there was a PHP extension called 'mongo'. This is what is being used in the 7.x-* version of the Drupal mongodb module.
In PHP 7.*, there is an extension called 'mongodb' instead of the old extension. The API also has changed, so it would require code changes
in the Drupal mongodb module.
See also http://stackoverflow.com/questions/34486808/installing-the-php-7-mongodb...
Status
Support for the PHP 7 mongodb extension was added in 8.x-2.x version of the Drupal mongodb module.
The Drupal 7 version of the module still only supports the old mongo extension for PHP 5.*.
| Comment | File | Size | Author |
|---|---|---|---|
| #24 | mongodb-7.x-1.x-2644482-mongophpadapter.patch | 4.21 KB | donquixote |
Comments
Comment #2
fgmYes, but only for the 8.x versions. I discussed this with jmikola (the main driver author, who wrote that post) when he came to France some weeks ago, and he advised against redoing our module on top of the new driver for existing versions, but rather use the new driver, for php7, as the foundation of our 8.x versions. He also suggested that we would probably be better off using just the driver lower layer (C extension), not the user-space layer, since we are essentially building a user-space driver of our own targeted to our needs.
Comment #3
Paul B commentedMeanwhile I got the site working on my dev with the pure php Mongofill library (https://github.com/mongofill/mongofill).
It seems to be working.
Comment #4
fgmYou mean on D7 or D8 ? Because D7 itself doesn't support PHP7 already, and the D8 version of the module is not supposed to be working at all on D8.0.1.
Comment #5
Paul B commentedI meant on D7. I didn't notice any problems running D7 on PHP7. Meanwhile we've decided to stick to 5.6 for now though.
Comment #6
fgmTagging for Milan code sprint
Comment #7
fgmCommitted to the 8.x-2.x branch yesterday: https://github.com/FGM/mongodb/commit/a895cde4ec21628a70c127645788ac7f94...
We can reopen this if someone actually wants this on 8.x-1.x.
Comment #8
fgmFixed in 8.x-2.x, not 8.x-1.x.
Comment #10
donquixote commentedI think over time more people will want to use Drupal 7 with PHP 7.
For me this is currently occuring because I installed a new Linux (Mint 18.1), where PHP 7 is the default you get from the repositories.
I thought I can either downgrade PHP to 5.6, or I can see if I can get Drupal 7 to work with PHP 7. I chose the latter, for now.
(I guess I could also use docker containers or something.. but then I would have to reorganize a lot of stuff on my local dev machine)
The mongodb module for Drupal 7 fails the requirements check on PHP 7, because the 'mongo' extension does not exist in PHP 7.
Instead, it is now called 'mongodb' extension, and has some classes changed.
http://stackoverflow.com/questions/34486808/installing-the-php-7-mongodb...
(which you already know, I suppose. Just saying it for other readers.)
Comment #11
donquixote commentedComment #12
donquixote commented@fgm
I updated the issue summary based on my limited knowledge. Feel free to correct any mistake.
Comment #13
donquixote commentedIf support for the new driver is not added in PHP 7, we should add least prevent it from crashing.
Steps to reproduce a crash:
- Install mongodb and some submodules (e.g. mongodb_watchdog) on a machine with PHP 5.* and 'mongo' extension.
- Copy the site's code + database to a machine with PHP 7.* and 'mongodb' extension. Or update the existing machine to use PHP 7 and mongodb extension.
-> profit! (class 'Mongo' not found in function mongodb())
With this crash going on, it is not even possible to disable the module.
I suppose this only happens if something does trigger mongodb(). In my case it was the watchdog.
So here is what could be done:
- check if class Mongo exists, throw an exception otherwise.
- catch exceptions in strategic places in code. Typically at the point of integration. E.g. in mongodb_watchdog_watchdog().
Comment #14
Paul B commentedHave you tried installing the mongo-php-adapter mentioned on that page?
Comment #15
fgmCould you submit a patch for this ? D7 is quite "legacy" these days, so I'm not totally convinced to spend time on this in when projects tend to be launched on 8.3 core anyway.
Reopening and retagging for D7 since this is what this issue is now about. No longer about DDD Milan, either.
Comment #16
majorrobot commentedI'll add my voice for support of this. The sites and clients I work with won't be migrating to Drupal 8 any time soon, and the old PHP Mongo driver is getting left in the dust. I would imagine at some point the old driver won't be compatible with newer versions of Mongo (though I've had luck with versions up to 3.2).
I'll add this won't just be helpful for PHP 7, but should also be helpful for PHP 5, since the newer mongodb driver works with both.
I'd be happy to help out with patches, as well.
Comment #17
fgmI'll be glad to review any patches to D7 components except for field storage and blocks, which I never touched anyway, so feel free to submit them. Patches should have tests.
Comment #18
donquixote commentedI have often added mongodb to existing D7 projects for performance.
So this does not only apply to newly launched projects.
This does not mean you (fgm) are obliged to anything, it just means your assumption about the need might be inaccurate.
Comment #19
jbrandl07 commentedI have tried following the instructions from the link in #14 but I'm getting the Currently using Mongodb Not found error when I try to enable the module. Using php7.1
Comment #20
fgm@donquixote @majorrobot: yes, adding MongoDB to D7 is indeed currently way more common than including it to a D8 project, no doubt about that. That's why I have no objection of any kind to reviewing and committing D7 patches if anyone want to submit them. It's just that I haven't had a "new site" D7 project since 2014: only D8, so I don't plan on doing these patches myself.
Comment #21
fgm@jbrandl07: it is not necessarily related to your issue but AFAIK PHP 7.1 is not entirely compatible with Drupal 8.0/8.1/8.2 and probably 8.3. Supported versions are 5.5.x (x >= 9), 5.6.x, and 7.0.x only: there are issues with the breaking changes in the assert() system with 7.1.
Comment #22
donquixote commentedI modified (in my local version of the module) the hook_requirements() to stop complaining if the old library is missing.
And wrote a separate module that requires the mongo-php-adapter with composer_manager.
The next problem I run into:
MongoDb::getCollectionNames() seems to have a different signature depending where you look, or depending which version of PHP or of the extension or whatever.
public array MongoDB::getCollectionNames ([ array $options = array() ] ).public function getCollectionNames($includeSystemCollections = false) {}, with boolean parameter.This results in
TypeError: Argument 1 passed to MongoDB::getCollectionNames() must be of the type array, boolean given, called in /.../sites/all/modules/contrib/mongodb/mongodb_cache/mongodb_cache_module.php on line 47 in MongoDB->getCollectionNames() (line 167 of /.../sites/all/vendor/alcaeus/mongo-php-adapter/lib/Mongo/MongoDB.php).
Comment #23
donquixote commentedUnfortunately I don't find documentation on the old signature, other than in PhpStorm. 3v4l.org is no help either, because it does not support extensions.
But omitting the parameter should be good enough.
With the old signature it defaults to
getCollectionNames($includeSystemCollections = false).With the new signature it defaults to
getCollectionNames($options = ['includeSystemCollections' => false, ..]).Comment #24
donquixote commentedThis patch contains the changes I did to the module on my localhost.
It does not contain additional tests. I don't expect it to be committed as is, just want to share my progress so others can continue from there.
I originally created mongophpadapter as a separate module, but I think it is useful to ship it as a submodule with the main module package.
What this patch does:
- Add an (optional) submodule mongophpadapter that tells composer_manager to download the mongo-php-adapter library.
- Change hook_requirements() to accept the replacement for the old ext-mongo library, and give detailed feedback if something is missing.
- Omit the explicit parameter in the call to MongoDB::getCollectionNames().
How to use:
- On PHP 7.x with ext-mongodb extension.
- Enable mongodb module and mongophpextension modules. The latter will ask you to download composer_manager, and will then install the mongo-php-adapter library from composer.
- Enable other submodules of mongodb as usual, and/or configure them in settings.php.
Comment #25
donquixote commentedComment #26
donquixote commentedIt does not work that way. Not that easy.
We need to launch composer_manager in settings.php.
I tried this by calling composer_manager_register_autoloader() in settings.php. But this indirectly triggers db_merge() via variable_set(). Which blows up because the database is not initialized yet. Too bad!
Comment #27
donquixote commentedOk, not such a problem after all.
In settings.php:
The if() is for the case where
drush composer-manager installhas not been executed yet, and the vendor/* stuff does not exist yet.Comment #28
donquixote commentedBtw why can I not mark a patch for testing with 7.x-1.x?
Comment #29
fgmFor the record, composer_manager should not be necessary to use the module, at least when not using the new extension adapter. If it has to be used for that adapter library, then so be it (although I tend to prefer adding a project-level composer.json file even on D7 and handle the dependencies there manually instead of requiring an additional module), but it should not make the module required if that library is not used.
You cannot trigger tests on d.o. because the module needs MongoDB which is not provided by DrupalCI.
Comment #30
Paul B commentedAccording to http://php.net/manual/en/mongodb.getcollectionnames.php#refsect1-mongodb... it was changed to an array in version 1.6, so if the module is calling it with FALSE then it's using an
outdated API.
I can't find any calls to getCollectionNames() in the Drupal 7 module.I see it's called in the 7.x-1.x-dev version. I think that should be a separate issue.
Comment #31
donquixote commentedIn the patch, composer_manager is only required by the submodule 'mongophpadapter'.
This needs better documentation, like a README.md, obviously.
So far composer_manager has always done the job for me, with several modules. If a lot of modules have composer dependencies, I imagine it quickly becomes unmanageable to keep your projects's composer.json up to date manually.
The d.o. tests would confirm that the patch applies and that Drupal installs properly. Which of course has nothing to do with the core purpose of the module. So I don't have a clear opinion. Maybe not having the tests on d.o. prevents the false comfort of a "green" patch where only some basics are tested. And reduces stress on the testing infrastructure.
Comment #32
fgmAbout tests: yes, that was my logic back when I enabled CI on the module a few years ago. But then only a few unit tests were able to pass because most actually depended on having a mongo server available, so at some point it got turned back off.
Comment #33
Anonymous (not verified) commentedThe performance using the alcaeus/mongo-php-adapter on top of the new mongodb driver+mongodb-php-library is also considerably worse than either the legacy driver or the new mongodb driver+mongodb-php-library combination. Perhaps 3-4 times worse!
https://github.com/alcaeus/mongo-php-adapter/issues/124
Comment #34
Paul B commentedI've run the same benchmark, for me it's only twice as slow.
The same benchmark in Perl or Python is ten times slower than the adapter version in PHP7, so I'm not sure it's that slow.
Comment #35
Anonymous (not verified) commentedBut why not rewrite the module to conditionally use the new extension+library directly, forgoing the adapter? That's what I did for my own purposes, & it works just fine. I only use a couple of the submodules, so I only rewrote those, but I'm sure it's applicable to all.
Comment #36
fgm@rhclayto : if you have a working version that works as well as the existing one on the legacy version and also works with PHP 7 and your IP policy enables you to publish it, you could submit the patch here for review.
Comment #37
hazaComment #38
Paul B commented@rhclayto : how should a submodule get to the mongodb client? Through mongodb()->getConnection()->getClient() ?
Comment #39
pribeh commented@rhclayto, would you be willing to share your code?
Comment #40
fgmBumping to major, as PHP 5.6 is getting EOL-ed this year, so this is probably the most pressing issue for 7.x. Asked @rhclayto for his patch in private message too.
Comment #41
fgmFWIW the mongofill project mentioned by @PaulB on #3 has now been archived with mutliple bugs since 2016, so it seems the only option is the alcaeus adapter found by @donquixote, which appears to still be maintained: https://github.com/alcaeus/mongo-php-adapter/
Comment #42
fgmI've converted @donquixote's patch in #24 to a PR: https://github.com/fgm/mongodb/pull/39
For some reason, xautoload 7.x-5.7 doesn't succesfully autoload the alcaeus classes, even when registering the composerDir(), so I just relied the Composer autoloader, explaining how to do it in the README.
Comment #43
donquixote commentedI think now that we work on github and can do pull requests instead of patches, we should split the changes into smaller commits.
I opened PR https://github.com/fgm/mongodb/pull/40 as a starting point for cherry-pick and rebase.
Atm this is just what I found on my local version of the module, from last time I worked on it.
Comment #44
donquixote commented#2985089: MongoDb::getCollectionNames() parameter: boolean or array? is the first part of the PR split into a separate issue for transparency's sake.
Comment #45
donquixote commentedFrom github PR discussion, which we decided to continue back here on drupal.org for visibility:
To conclude my own summary of "ways to integrate Composer dependencies":
I think there are a few different strategies out there for composer integration in D7. The choice is made per project / website.
This approach assumes a composer.json in each module that wants to declare Composer dependencies. Such a composer.json typically contains 3rd party dependencies, but no dependencies on Drupal module packages.
I don't know if it is possible to manually add additional package dependencies this way.
This approach assumes a composer.json in each module package (which may contain more than one module) that wants to declare Composer dependencies. Such composer.json should also contain other Drupal modules that are required for download.
It is still possible to manually require additional packages, that are not explicitly required by any module or package.
This approach assumes no composer.json in the modules, but it means that a site builder / developer needs to require the correct packages in a suitable version manually each time they install or update a module.
This means we have different approaches with different requirements or assumptions on module-provided composer.json files.
Ideally, the module should work with all of those approaches.
In our case, the composer.json for approach 1. and 2. would be mostly the same, if we want to always require mongo-php-adapter.
This is what the PR does by adding a composer.json, https://github.com/fgm/mongodb/pull/39/files#diff-b5d0ee8c97c7abd7e3fa29...
However, I should ask: Do we always need to require this library?
If someone uses the old ext-mongo extension, they don't need the mongo-php-adapter library, right?
It does not really hurt either.. but then we should change the text in the requirements perhaps.
Currently in the PR it says this:
Comment #46
fgmIt seems the current logic in the patch is a bit off: it now checks the server version only when using the legacy mongo extension.
The server version check is independent of the extension: findAndModify was only implemented in mongodb 1.3, because a lot of the code won't work without it, so that needs to be checked in all extension cases, although this is very outdated now that 4.0 is out.
Regarding autoloading, and considering users of the legacy mongo extensions don't need it, I think that we should not add it as a module dependency, but just ensure the alcaeus classes are autoloadable in hook_requirements if the requirements check concludes to a current mongodb extension deployment. The classes in the module itself are not autoloaded anyway, and I'd rather not touch this code at all.
Since the requirements check is getting a bit hairy, it would be nice to refactor it to a separate "service" with easily testable individual checks and a simple main entrypoint, as is done in 8.x-2.x for the watchdog requirements: https://github.com/fgm/mongodb/blob/8.x-2.x/modules/mongodb_watchdog/src...
Comment #47
kswamy commented@fgm. Would like to confirm my understanding so far.
1. I get that we need to split hook_requirements() to call 2 parts. One containing the checks done in PR https://github.com/fgm/mongodb/pull/40/files and another doing the server version check currently done in https://github.com/fgm/mongodb/blob/7.x-1.x/mongodb.install
2. As per your above comments I see that you are looking to make this into separate services rather than just functions. So should I use the Services module in Drupal 7.x to rather split this into 2 services as given in point 1 and call them in hook_requirements() or do you just mean that it is enough for both the requirements to be just separate functions?
Am asking the question in point 2 since I do not clearly get the requirement for writing this as service as this code is going to be used inside Drupal itself in hook_requirements(). But in case you have any other plan kindly briefly explain on same.
Sorry for the delay. But I hope it is not too late.
Comment #48
fgm1. Indeed.
2. No, Services module is completely unrelated to services for dependency injection in the D8/Symfony sense: Services module about exposing web services, not about dependency injection. The closest equivalent to D8 services was at one point the
service_containermodule, but it is now deprecated and replaced by thebackportmodule and its dependencies, but we don't really need either : services are just configurable code that gets instantiated from its dependencies and uses these injected dependencies and configuration to perform its purpose ; it does not depend on having a service container (e.g. the Symfony DIC, or Pimple, or some other PSR-11 container) ; these containers are just a way to provide access to the services and make them configurable more easily.Comment #49
kswamy commented@fgm Created PR https://github.com/fgm/mongodb/pull/54 to start with. Could you be more specific and give an example on the things we would need to make configurable in this code so I can follow the same ?
Comment #50
fgmReview sent. Regarding the PR process, you should probably create a branch named like 2644482-php7 on your fork and do the PR from that branch to 7.x : it will be easier for you to continue following other 7.x issues if your 7.x matches the upstream 7.x instead of having extra commits.
Comment #51
kswamy commented@fgm I have done as you requested. I hope this is what you had in mind. Anyway feel free to let me know on further review comments.
https://github.com/fgm/mongodb/pull/55
Closed old PR since I have done this on a separate branch as you suggested
Comment #52
fgmReview send. It's getting closer, indeed.
Comment #53
kswamy commented@fgm Updated PR #55
Comment #54
jarrodirwin commentedHey guys, where are we at with this? What's still needed?
As Drupal 7.61 now fully supports PHP 7.2 and due to Ubuntu 14.04 going EOL in the coming months I see a lot of Drupal 7 projects being moved to 18.04 with PHP 7 - One I'm doing right now requires MongoDB and thus this module...
Would be great to get the D7 version of this module running on the php 7 mongodb extension.
Comment #55
fgm@jarrodirwin : have you tried using that branch for your site, to validate if it works for you ?
Comment #56
jarrodirwin commented@fgm ahh right, there is a github feature branch for this. Sorry, missed that.
Yep, can confirm that using the D7 code on the feature branch with a MongoDB 4.0.5, PHP7.2 (Ubuntu 18.04), the new mongodb PHP extension and the mongo-php-adapter package added via composer works fine.
Is there any reason this is being handled as a separate feature branch off github instead of the standard Drupal.org way of supplying patches in this issue queue?
What's needed to be able to get this feature branch merged in?
Comment #57
fgmYes, the project uses Drupal issue queue for tracking because it's best to find issues in the longer term, but github PR's instead of patches for two reasons:
What is needed: mostly returns on experience like yours, and reviews on the PRs : can you review the latest PR by kswamy ?
Comment #58
thung commentedHi,
I confirm that the patch works with the following configuration :
PHP 7.0.14-1
MongoDB Extension 1.24
Mongo DB 2.6.7
Comment #60
fgmMerged to 7.x-1.x HEAD. Thanks donquixote for the patch, and all who tested it.
Comment #61
fgm