Laravel mongodb transactions - php

I need to use transactions on MongoDB in Laravel.
I downloaded the php MongoDB driver 1.6 and copied and pasted php_mongodb.dll into the php/ext folder.
I also installed the php mongo library through
composer require mongodb/mongodb
Now, when I try to use transactions according to this, it doesn't rollback when an error occurs.
$client = new Client($url);
$callback = function (\MongoDB\Driver\Session $session) use ($client) {
$data = [
"name" => "Tommy",
];
$collection = $client->db1->users;
$user = $collection->updateOne(
['mobile' => '*'],
['$set' => $data],
[$session]
);
$data = [
"activate" => 1,
];
$collection = $client->db1->wallets;
$wallet1 = $collection->updateOne(
['_id' => 100],
['set' => $data],
[$session]
);
};
$session = $client->startSession();
$transactionOptions = [
'readConcern' => new \MongoDB\Driver\ReadConcern(\MongoDB\Driver\ReadConcern::LOCAL),
'writeConcern' => new \MongoDB\Driver\WriteConcern(\MongoDB\Driver\WriteConcern::MAJORITY, 1000),
'readPreference' => new \MongoDB\Driver\ReadPreference(\MongoDB\Driver\ReadPreference::RP_PRIMARY),
];
try{
\MongoDB\with_transaction($session, $callback, $transactionOptions);
return true;
}catch (\Exception $e)
{
return false;
}
The session class in MongoDB\Driver\Session is unknown in laravel while this class is for mongodb>=1.4.0. I don't know what is wrong. Can anyone help me?

Related

MongoDB PHP Error: Warning: Undefined property: MongoDB\Driver\Manager

I'm trying to use MongoDB on my local machine using the advice in this stack overflow. I'm using XAMPP on Windows 10, php version 8.01, and MongoDB extension 1.9.0.
It's a very basic script that connects to MongoDB and tries to use one of the databases.
But I am still getting this warning:
Connection to database successfully
Warning: Undefined property: MongoDB\Driver\Manager::$aws_inventories in C:\xampp\htdocs\mongo_connect.php on line 8
This is my code:
<?php
require 'C:\xampp\htdocs\vendor\autoload.php'; // include Composer's autoloader
$DB_CONNECTION_STRING="mongodb://localhost:27017";
// connect to mongodb
$m = new MongoDB\Driver\Manager( $DB_CONNECTION_STRING );
echo "Connection to database successfully";
// select a database
$db = $m->aws_inventories;
?>
How can I get rid of the warning and connect to the DB correctly?
First, you're trying to access a property which doesn't exists in MongoDB\Driver\Manager class object.
Second, $db = $m->aws_inventories; works with MongoDB\Client library.
Here are few example to get collections list or find all/specific document/s or insert/bulk insert, update a document or to perform a distinct query
Get all collections of aws_inventories:
try {
$manager = new MongoDB\Driver\Manager('mongodb://localhost:27017');
$command = new MongoDB\Driver\Command(["listCollections" => 1]);
$cursor = $manager->executeCommand("aws_inventories", $command);
// list of all collections in aws_inventories
$collections = $cursor->toArray();
var_dump($collections);
} catch (\MongoDB\Driver\Exception\Exception $e) {
}
Get all documents from a collection:
try {
$manager = new MongoDB\Driver\Manager('mongodb://localhost:27017');
// setting options and filter
$filter = [];
$options = [];
/*
// or to find specific documents based on a condition and limit records
$filter = [
'service' => 'ec2',
'instance' => 'co',
'type' => 'c5',
'vCPU' => [
'$gt' => 2
]
];
$options = [
'limit' => 10,
'maxTimeMS' => 1000, // to limit the execution time of a query
'sort' => [
'vCPU' => -1
]
];
*/
// constructing the query
$query = new MongoDB\Driver\Query($filter, $options);
$cursor = $manager->executeQuery('aws_inventories.test', $query);
foreach ($cursor as $document) {
var_dump($document);
}
} catch (\MongoDB\Driver\Exception\Exception $e) {
}
To perform distinct query:
try {
$manager = new MongoDB\Driver\Manager('mongodb://localhost:27017');
$query = [
'size' => '2xlarge'
];
$command = new MongoDB\Driver\Command([
'distinct' => 'test', // Collection name
'key' => 'instance', // field for which we want to get distinct values
'query' => $query // criteria to filter documents
]);
$cursor = $manager->executeCommand("aws_inventories", $command);
// to get distinct values as array
$instances = current($cursor->toArray())->values;
var_dump($instances);
} catch (\MongoDB\Driver\Exception\Exception $e) {
}
To insert single/multiple document/s:
try {
$manager = new MongoDB\Driver\Manager('mongodb://localhost:27017');
$bulk = new MongoDB\Driver\BulkWrite;
$bulk->insert([
'service' => 'ec2',
'instance' => 'co',
'type' => 'c5',
'size' => 'large',
'model' => 'c5.large',
'vCPU' => 2,
'memory' => 4,
'storage' => 'ebs-only',
'network_bandwidth' => 10,
'ebs_bandwidth' => 4750
]);
$bulk->insert([
'service' => 'ec2',
'instance' => 'gp',
'type' => 't3',
'size' => 'nano',
'model' => 't3.nano',
'vCPU' => 2,
'memory' => 0.5,
'storage' => 'ebs-only',
'network_bandwidth' => 5
]);
$result = $manager->executeBulkWrite('aws_inventories.test', $bulk);
} catch (\MongoDB\Driver\Exception\Exception $e) {
}
To update existing document/s: (Taken from executeUpdate example)
try {
$manager = new MongoDB\Driver\Manager('mongodb://localhost:27017');
$criteria = [
'service' => 'ec2',
'type' => 'c5'
];
$document = [
'$set' => [
'features' => [
'Powered by the AWS Nitro System, a combination of dedicated hardware and lightweight hypervisor'
]
]
];
$updateOptions = array(
'multi' => true, // false - to update only first matching document, true - update all matching documents
'upsert' => 0
);
$writeConcern = new MongoDB\Driver\WriteConcern(MongoDB\Driver\WriteConcern::MAJORITY, 100);
$result = $manager->executeUpdate('aws_inventories.test', $criteria, $document, $updateOptions, $writeConcern);
printf("Updated %d document(s)\n", $result->getModifiedCount());
printf("Matched %d document(s)\n", $result->getMatchedCount());
printf("Upserted documents: %d\n", $result->getUpsertedCount());
foreach ($result->getUpsertedIds() as $index => $id) {
printf("upsertedId[%d]: ", $index);
var_dump($id);
}
/* If the WriteConcern could not be fulfilled */
if ($writeConcernError = $result->getWriteConcernError()) {
printf("%s (%d): %s\n", $error->getMessage(), $error->getCode(), var_export($error->getInfo(), true));
}
/* If the write could not happen at all */
foreach ($result->getWriteErrors() as $writeError) {
printf("%s (%d)\n", $error->getMessage(), $error->getCode());
}
} catch (\MongoDB\Driver\Exception\Exception $e) {
}
$m->aws_inventories That looks like as the older/deprecated approach. Could you try to follow this tutorial?
https://zetcode.com/db/mongodbphp/
<?php
try {
$mng = new MongoDB\Driver\Manager("mongodb://localhost:27017");
$stats = new MongoDB\Driver\Command(["dbstats" => 1]);
$res = $mng->executeCommand("aws_inventories", $stats);
$stats = current($res->toArray());
print_r($stats);
} catch (MongoDB\Driver\Exception\Exception $e) {
$filename = basename(__FILE__);
echo "The $filename script has experienced an error.\n";
echo "It failed with the following exception:\n";
echo "Exception:", $e->getMessage(), "\n";
echo "In file:", $e->getFile(), "\n";
echo "On line:", $e->getLine(), "\n";
}
?>
This example is adapted from the official doc https://www.php.net/manual/en/mongodb-driver-manager.executequery.php
<?php
require 'vendor/autoload.php';
$manager = new MongoDB\Driver\Manager("mongodb://localhost:27017");
$db = 'test_database';
$col = 'mycol';
$namespace = $db.'.'.$col;
// insert data
$bulk = new MongoDB\Driver\BulkWrite;
$bulk->insert(['x' => 1]);
$bulk->insert(['x' => 2]);
$bulk->insert(['x' => 3]);
$manager->executeBulkWrite($namespace, $bulk);
// query
$query = new MongoDB\Driver\Query(['x' => ['$gt' => 1]], []);
$cursor = $manager->executeQuery($namespace, $query);
foreach ($cursor as $document) {
var_dump($document);
}
As the document suggests, MongoDB\Driver\Manager is a generic abstraction to manage any type of MongoDB connection (standalone server, replica set, or sharded cluster) so the methods will look a bit too complicated for simple CRUD on standalone server.
If you just want to connect to a standalone server, you may want to check MongoDB\Client. Here is the code that do exactly the same thing:
<?php
require 'vendor/autoload.php';
$client = new MongoDB\Client("mongodb://localhost:27017");
$col = $client->test_database->mycol;
// insert data
$col->insertMany([
['x' => 1],
['x' => 2],
['x' => 3],
]);
// query
$docs = $col->find(['x' => ['$gt' => 1]]);
foreach ($docs as $document) {
var_dump($document);
}

"Class 'MongoDB\Driver\Manager' not found" in PHP

I installed MongoDB library with Composer:
composer require jenssegers/mongodb
I got that error: "Class 'MongoDB\Driver\Manager' not found",
I tried many things but problem is not solved,
But finally I noticed that the class file is really not existing in library!
I havent found it anyway...
What am I missing?
Where can I found full package for MongoDB in PHP?
Please be aware of that: similar questions are not mentioning lack of class file.
Usually your code should contain a link to 'vendor/autoload.php' with the correct path to it similar to the following:
$DB_CONNECTION_STRING="mongodb://YourCredentials";
require '../../vendor/autoload.php';
Then if you use MongoDB\Driver\Manager, a modern version of MongoDB driver, you have something such as these CRUD operations in your code:
Create a document in the collection:
$bulkWrite = new MongoDB\Driver\BulkWrite;
$doc=['name' => 'John', age => 33, profession => 'Guess what?'];
$bulk->insert($doc);
$mongoConn->executeBulkWrite('db.col', $bulkWrite);
Read document in the collection by name with a limit:
$filter = ['name' => 'John'];
$options = ['limit' => 2];
$query = new MongoDB\Driver\Query($filter, $options);
$mongoConn->executeQuery('db.MyCollection', $query);
Read document in the collection by MongoDb _id with a limit:
$filter = ['_id' => new MongoDB\BSON\ObjectID( '5bdf54e6d722dc000f0aa6c2' )];
$options = ['limit' => 2];
$query = new MongoDB\Driver\Query($filter, $options);
$mongoConn->executeQuery('db.MyCollection', $query);
Update document in the collection:
$bulkWrite = new MongoDB\Driver\BulkWrite;
$filter = [];
$update = ['$set' => array()];
$options = ['multi' => false, 'upsert' => false];
$bulkWrite->update($filter, $update, $options);
$mongoConn->executeBulkWrite('db.MyCollection', $bulkWrite);
Delete document in the collection - Delete:
$bulkWrite = new MongoDB\Driver\BulkWrite;
$filter = ['name' => 'John', age => 33];
$options = ['limit' => 1];
$bulkWrite->delete($filter, $options);
$mongoConn->executeBulkWrite('db.col', $bulkWrite);

MongoClient Class vs. MongoDB\Driver\Manager Class

I want to get your recommend about my web project. I use PHP and MongoDB but I was confused when I read this sentence from php documentation.
This extension that defines this class is deprecated. Instead, the MongoDB extension should be used. Alternatives to this class include:
MongoDB\Driver\Manager
I already used MongoClient Class for CRUD but after reading that sentence, I tried to migrate MongoClient to MongoDB\Driver\Manager. The connection using MongoDB\Driver\Manager was successed but I couldn't anymore :(
My PHP version is 5.6.29.
Mongo extension version is 1.7.0
MongoDB extension version is 1.2.9
My questions are:
Do I have to use MongoDB\Driver\Manager Class?
Is it better than MongoClient Class?
Here is a good answer about deprecated language features:
What does PHP do with deprecated functions?
And here is a proper usage for php with mongodb:
$manager = new MongoDB\Driver\Manager("mongodb://localhost:27017");
$filter = [];
$options = [
'sort' => ['_id' => 1],
];
$query = new MongoDB\Driver\Query($filter, $options);
$cursor = $manager->executeQuery('db.collection', $query);
foreach ($cursor as $document) {
//...
}
There are are a lot of tutorials for CRUD operation with php and mongodb, for example: MongoDB PHP tutorial
In short: you should not use deprecated feature because of security reasons and because it could get removed from php in the future. So better update your code.
I personally came across with the absence of a link to 'vendor/autoload.php'. It started working after my code looked like the following:
$DB_CONNECTION_STRING="mongodb://YourCredentials";
require '../vendor/autoload.php';
$manager = new MongoDB\Driver\Manager( $DB_CONNECTION_STRING );
Then if you use MongoDB\Driver\Manager, a modern version of MongoDB driver, you implement CRUD operations such as the following:
Create a document in the collection:
$bulkWrite = new MongoDB\Driver\BulkWrite;
$doc = ['name' => 'John', age => 33, profession => 'Guess what?'];
$bulkWrite->insert($doc);
$manager->executeBulkWrite('db.MyCollection', $bulkWrite);
Read document in the collection by name with a limit:
$filter = ['name' => 'John'];
$options = ['limit' => 2];
$query = new MongoDB\Driver\Query($filter, $options);
$manager->executeQuery('db.MyCollection', $query);
Read document in the collection by MongoDb _id with a limit:
$filter = ['_id' => new MongoDB\BSON\ObjectID( '5bdf54e6d722dc000f0aa6c2' )];
$options = ['limit' => 2];
$query = new MongoDB\Driver\Query($filter, $options);
$manager->executeQuery('db.MyCollection', $query);
Update document in the collection: (Read more about options upsert and multi here)
$bulkWrite = new MongoDB\Driver\BulkWrite;
$filter = ['name' => 'John'];
$update = ['$set' => ['name' => 'Smith', age: 35, profession => 'Guess what?']];
$options = ['multi' => false, 'upsert' => false];
$bulkWrite->update($filter, $update, $options);
$manager->executeBulkWrite('db.MyCollection', $bulkWrite);
Delete document in the collection - Delete:
$bulkWrite = new MongoDB\Driver\BulkWrite;
$filter = ['name' => 'John', age => 35];
$options = ['limit' => 1];
$bulkWrite->delete($filter, $options);
$manager->executeBulkWrite('db.MyCollection', $bulkWrite);

Php MongoDB, Fatal error: Class 'MongoDB\Driver\Manager' not found in

image for mongo info
MongoDB shell version v3.4.1
mongodb driver v1.6.14
xampp v3.2.1, Apache/2.4.16 (Win32) OpenSSL/1.0.1p PHP/5.6.12
i m running for first time and getting this problem plz help me.
Fatal error: Class 'MongoDB\Driver\Manager' not found in H:\xampp\htdocs\www\phpmongodb\vendor\mongodb\mongodb\src\Client.php on line 81
I had the same error before I set up the mongodb added the following link to 'vendor/autoload.php'. In many cases you need to check your hosting. It started working after my code looked like the following:
$DB_CONNECTION_STRING="mongodb://YourCredentials";
require '../../vendor/autoload.php';
$manager = new MongoDB\Driver\Manager( $DB_CONNECTION_STRING );
Then if you use MongoDB\Driver\Manager, a modern version of MongoDB driver, you have something looks such as this:
Create a document in the collection:
$bulkWrite = new MongoDB\Driver\BulkWrite;
$doc = ['name' => 'John', age => 33, profession => 'Guess what?'];
$bulkWrite->insert($doc);
$manager->executeBulkWrite('db.MyCollection', $bulkWrite);
Read document in the collection by name with a limit:
$filter = ['name' => 'John'];
$options = ['limit' => 2];
$query = new MongoDB\Driver\Query($filter, $options);
$manager->executeQuery('db.MyCollection', $query);
Read document in the collection by MongoDb _id with a limit:
$filter = ['_id' => new MongoDB\BSON\ObjectID( '5bdf54e6d722dc000f0aa6c2' )];
$options = ['limit' => 2];
$query = new MongoDB\Driver\Query($filter, $options);
$manager->executeQuery('db.MyCollection', $query);
Update document in the collection: (Read more about options upsert and multi here)
$bulkWrite = new MongoDB\Driver\BulkWrite;
$filter = ['name' => 'John'];
$update = ['$set' => ['name' => 'Smith', age: 35, profession => 'Guess what?']];
$options = ['multi' => false, 'upsert' => false];
$bulkWrite->update($filter, $update, $options);
$manager->executeBulkWrite('db.MyCollection', $bulkWrite);
Delete document in the collection - Delete:
$bulkWrite = new MongoDB\Driver\BulkWrite;
$filter = ['name' => 'John', age => 35];
$options = ['limit' => 1];
$bulkWrite->delete($filter, $options);
$manager->executeBulkWrite('db.MyCollection', $bulkWrite);

I want to achieve in laravel 5 the same thing as the cakephp of HttpSocket ()

I want to achieve in laravel 5 the same thing as the cakephp of HttpSocket ().
Within your own site, and I want to get the result of the POST to other sites.
CakePhp source code:
$socket = new HttpSocket();
$url = 'http://other-site.com/pages/';
$option['login'] = array('id'=>'abc','pass'=>'xxxxxxx');
$option['data']['hasOne'] = array('startDate' => '2015-04-16', 'endDate' => '2015-04-17');
$list = unserialize($socket->post($url,$option));
In cakephp, can be achieved by the method described above, but does not know how to do in laravel 5.
Do not anyone understand here?
Guzzle will help you.
Install it via Composer:
composer require guzzlehttp/guzzle
Alternative of your code using Guzzle:
use GuzzleHttp\Client;
$client = new Client();
$response = $client->post(
'http://other-site.com/pages/',
[
'login' => ['id' => 'abc', 'pass' => 'xxxxxxx'],
'data' => ['hasOne' => ['startDate' => '2015-04-16', 'endDate' => '2015-04-17']]
]
);
if ($response->getStatusCode() === 200) {
$list = unserialize($response->getBody());
} else {
// handle error
}

Categories