Loading…

 

PHP 7 and MongoDB

Share: 

My current project has been involving PHP 7 and using MongoDB instead of SQL.

I've decided to write up an article on how to use mongo with PHP 7 as it is a tad different from how you use Mongo with PHP 5.

first, you'll need to install the mongoDB extension, if you haven't already.

pecl mongodb

You will need the MongoDB client, this you can get from composer.

composer require mongodb/mongodb

I won't get into too much details on the driver as the documentation does a well enough job.

I wanted a way to create a simple crud setup and didn't want to install a full blown ORM library, so I made a lightweight setup to do what I needed.

I first created an interface that let me set some rules as to what each entity had to obey.

namespace App\Entities;

use MongoDB\Model\BSONDocument;

interface IModel
{
    /**
     * Maps Mongo document to Model Object
     * @param array|BSONDocument $document
     */
    public function map(BSONDocument $document) : void;

    /**
     * Converts object to array
     * @return array
     */
    public function toArray() : array;
}

My entity at most needed two methods, a way to build my entity into something Mongo can understand and a way to convert to an array as PHP is very array happy.

I now have my rules set, time to create an entity class. Those familiar with MongoDB know that they technically provide you with an id field, but I wanted something nicer than the timestamp value so I'm using a GUID instead. You don't have to use a GUID, so for the sake of this article, I'm going to just use the id field mongo already provides

Let's create a user class that'll be our entity for touching the user collection.

namespace App\Entities;

use MongoDB\BSON\Serializable;
use MongoDB\BSON\UTCDateTime;
use MongoDB\Model\BSONDocument;

class User implements Serializable, IModel
{
    /**
     * @var string
     */
    public $id;

    /**
     * @var \DateTime
     */
    public $createdOn;

    /**
     * @var \DateTime
     */
    public $updatedOn;

    /**
     * @var string
     */
    public $email;

    /**
     * @var string
     */
    public $firstName;

    /**
     * @var string
     */
    public $lastName;

    /**
     * @return array
     */
    public function bsonSerialize() : array
    {
        return [
            'CreatedOn' => new UTCDateTime($this->createdOn),
            'UpdatedOn' => new UTCDateTime($this->updatedOn),
            'Email' => $this->email,
            'FirstName' => $this->firstName,
            'LastName' => $this->lastName,
        ];
    }

    /**
     * Maps Mongo document to Model Object
     * @param array|BSONDocument $document
     */
    public function map(BSONDocument $document) : void
    {
        $this->id = $document['_id'];
        $this->createdOn = $document['CreatedOn']->toDateTime();
        $this->updatedOn = $document['UpdatedOn']->toDateTime();
        $this->email = $document['Email'];
        $this->firstName = $document['Firstname'];
        $this->lastName = $document['Lastname'];
    }

    /**
     * Converts object to array
     * @return array
     */
    public function toArray() : array
    {
        return [
            'Id' => $this->guid,
            'CreatedOn' => $this->createdOn,
            'UpdatedOn' => $this->updatedOn,
            'Email' => $this->email,
            'FirstName' => $this->firstName,
            'LastName' => $this->lastName,
        ];
    }
}

We now have our entity object, let's use it to create a new user.

require 'vendor/autoload.php';

use App\Entities\Users;

$mongo = new MongoDB\Client('mongodb://localhost:27017');

$collection = $mongo->selectCollection('demo', 'Users');

$dt = new \DateTime('now', new DateTimeZone('UTC'))

$user = new Users();
$user->createdOn = $dt;
$user->updatedOn = $dt;
$user->email = '[email protected]';
$user->firstName = 'Bob';
$user->lastName = 'Thomas';

$result = $collection->insertOne($user);

echo 'Inserted with Object ID: '. $result->getInsertedId();

This should create the user Bob Thomas and this will give you the ID mongo created.

Next, let's read this user info from mongo.

require 'vendor/autoload.php';

use App\Entities\Users;

$mongo = new MongoDB\Client('mongodb://localhost:27017');

$collection = $mongo->selectCollection('demo', 'Users');

$user = new Users();

$query = [
    '_id' => '59bc8323c8976b127855abad'
];

$document = $collection->findOne($query);

if (null === $document)
{
    echo "Nothing was found.\n";
}
else
{
    $user->map($document);
    print_r($user);
}

This will provide us with our user bob.

Bob got a new email so we have to update his email.

require 'vendor/autoload.php';

use App\Entities\Users;

$mongo = new MongoDB\Client('mongodb://localhost:27017');

$collection = $mongo->selectCollection('demo', 'Users');

$user = new Users();

$query = [
    '_id' => '59bc8323c8976b127855abad'
];

$document = $collection->findOne($query);

if (null === $document)
{
    echo "Nothing was found.\n";
}
else
{
    $user->map($document);
    $user->updatedOn = new \DateTime('now', new DateTimeZone('UTC'));
    $user->email = '[email protected]';
    
    $collection->updateOne(['_id' => $user->id], ['$set' => $user]);
}

Bob's email has changed successfully.

Finally, we need to be able to delete bob if he decides to leave.

require 'vendor/autoload.php';

$mongo = new MongoDB\Client('mongodb://localhost:27017');

$collection = $mongo->selectCollection('demo', 'Users');

$collection->deleteOne(['_id' => '59bc8323c8976b127855abad']);

That's all there is to it. You have a pretty simple orm-ish setup without the heavy library.

contact me and let know if I can improve this process or if you got something out of this article.