In this talk we will see how to use MongoDB in Symfony2 projects to speed up the development of web applications. We will give an introduction of MongoDB as a NoSQL database server and look at the options on how to work with it from Symfony2 and PHP applications.
1. Pablo Godel @pgodel - MidwestPHP 2013
March 2nd 2013 - St. Paul, MN
https://joind.in/8211
Sunday, March 3, 13
2. Who Am I?
⁃ Born in Argentina, living in the US since 1999
⁃ PHP & Symfony developer
⁃ Founder of the original PHP mailing list in spanish
⁃ Master of the parrilla
Sunday, March 3, 13
5. ServerGrove!
⁃ Founded ServerGrove Networks in 2005
⁃ Provider of web hosting specialized in PHP,
Symfony, ZendFramework, and others
⁃ Mongohosting.com!
⁃ Servers in Miami, FL and Dublin, Ireland
Sunday, March 3, 13
6. Community is our teacher
⁃ Very active open source supporter through code
contributions and usergroups/conference sponsoring
Sunday, March 3, 13
7. Agenda
- Introduction to MongoDB
- PHP and MongoDB
- PHP Libraries
- Introduction to Symfony2
- Symfony2 and MongoDB
Sunday, March 3, 13
9. Mongo
Mongo as in "humongous". Used to describe
something extremely large or important.
Sunday, March 3, 13
10. MongoDB is a scalable, high-performance,
open source NoSQL database.
- Document Oriented DB
- Written in C++
- Available for *nux (Linux, Solaris, etc),
Windows and OS X
- Lots of Drivers (PHP, Java, Python, Ruby...)
Sunday, March 3, 13
11. Features
- Flexible JSON-style documents
- Full Indexing
- Complex Queries / Map Reduce
- Aggregation Framework
- GridFS (store files natively)
- Multiple Replication Options
- Sharding
- Simple Installation / Zero Config
Sunday, March 3, 13
12. Document Oriented
Coming from SQL?
Database => Database
Table => Collection
Row => Document
Sunday, March 3, 13
19. GridFS
- Files are divided in chunks
and stored over multiple documents
- Transparent API
$grid->storeFile("/path/to/somefile.txt",
array("metadata" => array("date" => new MongoDate())));
Sunday, March 3, 13
20. Replication
Source: http://www.mongodb.org/display/DOCS/Replication
Sunday, March 3, 13
21. Shards
Source: http://www.mongodb.org/display/DOCS/Introduction
Sunday, March 3, 13
22. Simple Installation/Zero Config
OS X
wget http://fastdl.mongodb.org/osx/mongodb-osx-x86_64-2.2.3.tgz
tar zxvf mongodb-osx-x86_64-2.2.3.tgz
cd mongodb-osx-x86_64-2.2.3
./mongod
Sunday, March 3, 13
23. Simple Installation/Zero Config
CentOS Linux
/etc/yum.repos.d/10gen.repo
[10gen]
name=10gen Repository
baseurl=http://downloads-distro.mongodb.org/repo/redhat/os/x86_64
gpgcheck=0
$ yum install -y mongo-10gen-server
$ service mongod start
Sunday, March 3, 13
24. Why is MongoDB good
for Rapid Development
of Web Apps?
Sunday, March 3, 13
25. Rapid Development
Schema-less / Document Oriented
FLEXIBILITY
by exfordy
Sunday, March 3, 13
26. Rapid Development
Schema-less / Document Oriented
EASIER
MIGRATIONS
by exfordy
Sunday, March 3, 13
33. PECL driver
Linux
pecl install mongo
echo “extension=mongo.so >> /path/php.ini”
OS X
http://php-osx.liip.ch/
Windows
https://github.com/mongodb/mongo-php-driver/downloads
Sunday, March 3, 13
34. Attention
Mongo 1.2.x
$m = new Mongo();
Mongo 1.3.x
$m = new MongoClient();
Sunday, March 3, 13
35. Usage
<?php
// connect
$m = new MongoClient();
// select a database
$db = $m->comedy;
// select a collection (analogous to a relational database's table)
$collection = $db->cartoons;
// add a record
$obj = array( "title" => "Calvin and Hobbes", "author" => "Bill Watte
rson" );
$collection->insert($obj);
// add another record, with a different "shape"
$obj = array( "title" => "XKCD", "online" => true );
$collection->insert($obj);
// find everything in the collection
$cursor = $collection->find();
// iterate through the results
foreach ($cursor as $obj) {
echo $obj["title"] . "n";
}
?>
Sunday, March 3, 13
36. Storing Files
<?php
// save a file
$id = $grid->storeFile("game.tgz");
$game = $grid->findOne();
// add a downloads counter
$game->file['downloads'] = 0;
$grid->save($game->file);
// increment the counter
$grid-
>update(array("_id" => $id), array('$inc' => array("downloads
" => 1)));
?>
Sunday, March 3, 13
37. SQL to Mongo Queries
SQL to Mongo Mapping Chart
This is a PHP-specific version of the » SQL to Mongo mapping chart in the main docs.
SQL Statement
Mongo Query Language Statement
CREATE TABLE USERS (a Number, b Number)
Implicit or use MongoDB::createCollection().
INSERT INTO USERS VALUES(1,1)
$db->users->insert(array("a" => 1, "b" => 1));
SELECT a,b FROM users
$db->users->find(array(), array("a" => 1, "b" => 1));
SELECT * FROM users WHERE age=33
$db->users->find(array("age" => 33));
SELECT a,b FROM users WHERE age=33
$db->users->find(array("age" => 33), array("a" => 1, "b" => 1));
SELECT a,b FROM users WHERE age=33 ORDER BY name
$db->users->find(array("age" => 33), array("a" => 1, "b" => 1))->sort(array("name" => 1));
SELECT * FROM users WHERE age>33
$db->users->find(array("age" => array('$gt' => 33)));
SELECT * FROM users WHERE age<33
$db->users->find(array("age" => array('$lt' => 33)));
SELECT * FROM users WHERE name LIKE "%Joe%"
$db->users->find(array("name" => new MongoRegex("/Joe/")));
SELECT * FROM users WHERE name LIKE "Joe%"
$db->users->find(array("name" => new MongoRegex("/^Joe/")));
SELECT * FROM users WHERE age>33 AND age<=40
$db->users->find(array("age" => array('$gt' => 33, '$lte' => 40)));
SELECT * FROM users ORDER BY name DESC
http://php.net/manual/en/
mongo.sqltomongo.php
Sunday, March 3, 13
39. PHP Libraries
- Doctrine ODM
Doctrine MongoDB Object Document Mapper is built for PHP
5.3.2+ and provides transparent persistence for PHP objects.
- Mandango
Mandango is a simple, poweful and ultrafast Object Document
Mapper (ODM) for PHP and MongoDB.
- many more...
Sunday, March 3, 13
40. Doctrine MongoDB ODM
http://doctrine-project.org
Doctrine MongoDB Object Document Mapper is
built for PHP 5.3.2+ and provides transparent
persistence for PHP objects.
Sunday, March 3, 13
43. Doctrine MongoDB ODM
<?php
// create user
$user = new User();
$user->setName('Bulat S.');
$user->setEmail('email@example.com');
// tell Doctrine 2 to save $user on the next flush()
$dm->persist($user);
// create blog post
$post = new BlogPost();
$post->setTitle('My First Blog Post');
$post->setBody('MongoDB + Doctrine 2 ODM = awesomeness!');
$post->setCreatedAt(new DateTime());
$user->addPost($post);
// store everything to MongoDB
$dm->flush();
Sunday, March 3, 13
44. Doctrine MongoDB ODM
Array
(
[_id] => 4bec5869fdc212081d000000
[title] => My First Blog Post
[body] => MongoDB + Doctrine 2 ODM = awesomeness!
[createdAt] => MongoDate Object
(
[sec] => 1273723200
[usec] => 0
)
)
Sunday, March 3, 13
49. Doctrine MongoDB ODM
// store file
$image = new Image();
$image->setName('Test image');
$image->setFile('/path/to/image.png');
$dm->persist($image);
$dm->flush();
// retrieve and return file to client
$image = $dm->createQueryBuilder('DocumentsImage')
->field('name')->equals('Test image')
->getQuery()
->getSingleResult();
header('Content-type: image/png;');
echo $image->getFile()->getBytes();
Sunday, March 3, 13
50. Tips: Doctrine MongoDB ODM
// Eager ID creation
public function __construct()
{
$this->id = (string) new MongoId();
}
Sunday, March 3, 13
51. Tips: Doctrine MongoDB ODM
// Creation date
public function __construct()
{
$this->id = (string) new MongoId();
$this->createdDt = new DateTime();
}
Sunday, March 3, 13
52. Tips: Doctrine MongoDB ODM
// ArrayCollections
public function __construct()
{
$this->id = (string) new MongoId();
$this->createdDt = new DateTime();
$this->entries = new ArrayCollection();
}
Sunday, March 3, 13
54. Symfony is a PHP Web Development Framework.
Sunday, March 3, 13
55. “First, Symfony2 is a reusable set of standalone, decoupled,
and cohesive PHP components that solve common web
development problems.
Then, based on these components, Symfony2 is also a
full-stack web framework.”
http://fabien.potencier.org/article/49/what-is-symfony2
Sunday, March 3, 13
57. Symfony 2 Components
• DependencyInjection • Serializer
• EventDispatcher • Validator
• HttpFoundation • Security
• DomCrawler • Routing
• ClassLoader • Console
• CssSelector • Process
• HttpKernel • Config
• BrowserKit • Finder
• Templating • Locale
• Translation • Yaml
• Serializer • Form
• More...
All of them at GitHub: http://github.com/symfony
Sunday, March 3, 13
58. Symfony 2 Components
Components Documentation
http://symfony.com/doc/current/components/index.html
Blog post series about creating a framework based on
the Symfony2 Components
http://fabien.potencier.org/
Sunday, March 3, 13
59. Symfony 2 Highlights
• Rewritten from scratch for PHP 5.3
• Based on the HTTP specification
• Very stable and solid API
• Extensible through the creation of Bundles (replacement for
sf1 plugins)
• Flexible configuration using YAML, XML, annotations or
PHP
• All configuration is compiled to PHP code and cached
• Lots of unit tests
• Source code audited by independent security firm thanks to
donations of the Symfony Community
Sunday, March 3, 13
60. Symfony 2 Highlights
• Extensible Configuration with Service Container/
Dependency Injection
• Complete redesign of Forms support
• Validations
• Extensible Security with Authentication/Authorization
• Advanced and powerful templating through Twig
• Routes configured with YAML, XML or Annotations
• ESI Caching support out of the box
• Assets management with Assetic
• Translations
• Environments
Sunday, March 3, 13
61. Symfony 2 Highlights: Community
• 698 developers contributed to Symfony2
• 7000+ pull requests
• 969 1901 bundles at knpbundles.com
• Very active IRC and mailing lists support
channels
• Community Gamification through
SensioLabs Connect
• Symfony2 Ecosystem
Sunday, March 3, 13
63. Symfony 2 Getting Started
http://symfony.com/download
Sunday, March 3, 13
64. Symfony 2 Getting Started
tar zxf Symfony_Standard_Vendors_2.2.0.tgz
or
unzip Symfony_Standard_Vendors_2.2.0.zip
Sunday, March 3, 13
65. Symfony 2 Getting Started with Composer
$ curl -s https://getcomposer.org/installer | php
$ php composer.phar create-project
symfony/framework-standard-edition path/ 2.2.0
http://getcomposer.org/
Sunday, March 3, 13
66. Symfony 2 Getting Started
Distributions
A Symfony distribution is made up of Symfony2
components, a selection of bundles,
a directory structure, a default configuration.
http://symfony.com/distributions
Sunday, March 3, 13
67. Symfony 2 Getting Started
Symfony Standard Distribution
• Directory structure
• Default configuration
• Bundles
⁃ DoctrineBundle
⁃ JMSSecurityExtraBundle
⁃ SensioDistributionBundle
⁃ SensioFrameworkExtraBundle
⁃ SensioGeneratorBundle
⁃ AsseticBundle
http://symfony.com/distributions
Sunday, March 3, 13
85. Symfony 2 Templating / Twig
Comments: {# comments are not rendered #}
{# multi-line comments!
{{ var }}
#}
Output variables: {{ var }}
{{ var | upper }}
{{ var | raw }}
{{ object.property }}
{{ true ? ‘yes’ : ‘no’ }}
http://twig.sensiolabs.org/
Sunday, March 3, 13
86. Symfony 2 Templating / Twig
Blocks: {% set var = ‘hello’ %}
{% set foo = var ~ ’ and goodbye’ %}
{% if foo is ‘bar’ %}
...
{% else %}
...
{% endif %}
http://twig.sensiolabs.org/
Sunday, March 3, 13
87. Symfony 2 Templating / Twig
Blocks: {% for key, val in list %}
{{ loop.index }}. {{ val }}
{% else %}
No keys.
{% endfor %}
http://twig.sensiolabs.org/
Sunday, March 3, 13
89. Awesome Twig Presentations
Twig, The Flexible, Fast and Secure Template Language
for PHP - Fabien Potencier
http://www.slideshare.net/fabpot/twig-the-flexible-fast-and-securetemplate-
language-for-php
Being Dangerous with Twig - Ryan Weaver
http://slideshare.net/weaverryan/being-dangerous-with-twig-symfony-
live-paris
Twig avanzado - Javier Eguiluz
http://www.slideshare.net/javier.eguiluz/twig-avanzado-sf2vigo (Spanish)
Sunday, March 3, 13
105. Symfony 2 Defining Documents
// src/Acme/StoreBundle/Document/Product.php
namespace AcmeStoreBundleDocument;
use DoctrineODMMongoDBMappingAnnotations as MongoDB;
/**
* @MongoDBDocument(collection="product")
*/
class Product
{
/**
* @MongoDBId
*/
protected $id;
/**
* @MongoDBString @MongoDBIndex(unique=true, order="asc")
*/
protected $name;
Sunday, March 3, 13
106. Symfony 2 Using Documents
// src/Acme/StoreBundle/Controller/DefaultController.php
use AcmeStoreBundleDocumentProduct;
use SymfonyComponentHttpFoundationResponse;
// ...
public function createAction()
{
$product = new Product();
$product->setName('A Foo Bar');
$product->setPrice('19.99');
$dm = $this->get('doctrine_mongodb')->getManager();
$dm->persist($product);
$dm->flush();
return new Response('Created product id '.$product->getId());
}
Sunday, March 3, 13
107. Symfony 2 Forms
Since Documents are Plain PHP Objects integrating it with Symfony Forms is straightforward.
public function createAction()
{
$dm = $this->get('doctrine_mongodb')->getManager();
$form = $this->createForm(new RegistrationType(), new
Registration());
$form->bindRequest($this->getRequest());
if ($form->isValid()) {
$registration = $form->getData();
$dm->persist($registration->getUser());
$dm->flush();
return $this->redirect(...);
}
http://symfony.com/doc/master/bundles/DoctrineMongoDBBundle/form.html
Sunday, March 3, 13
108. Symfony 2 ODM Commands
Symfony2 Commands
doctrine
doctrine:mongodb:cache:clear-metadata Clear all metadata cache for a document manager.
doctrine:mongodb:fixtures:load Load data fixtures to your database.
doctrine:mongodb:generate:documents Generate document classes and method stubs from
your mapping information.
doctrine:mongodb:generate:hydrators Generates hydrator classes for document classes.
doctrine:mongodb:generate:proxies Generates proxy classes for document classes.
doctrine:mongodb:generate:repositories Generate repository classes from your mapping
information.
doctrine:mongodb:mapping:info Show basic information about all mapped
documents.
doctrine:mongodb:query Query mongodb and inspect the outputted results
from your document classes.
doctrine:mongodb:schema:create Allows you to create databases, collections and
indexes for your documents
doctrine:mongodb:schema:drop Allows you to drop databases, collections and
indexes for your documents
Sunday, March 3, 13
109. TIP: Storing Symfony Sessions in MongoDB
app/config/config.yml
Sunday, March 3, 13
110. TIP: Mixing Doctrine ODM & ORM
Order Product
Entity (ORM) Document (ODM)
http://docs.doctrine-project.org/projects/doctrine-
mongodb-odm/en/latest/cookbook/blending-orm-and-
mongodb-odm.html
Sunday, March 3, 13
111. TIP: Persisting objects with ODM or ORM
<?php
namespace DoctrineBlog;
/** @Entity(repositoryClass="DoctrineBlogORMBlogPostRepository")
*/
class BlogPost
{
/** @Id @Column(type="integer") */
private $id;
/** @Column(type="string") */
private $title;
/** @Column(type="text") */
private $body;
// ...
}
Sunday, March 3, 13
112. TIP: Persisting objects with ODM or ORM
<?php
namespace Documents;
/** @Document(repositoryClass="DoctrineBlogODMMongoDB
BlogPostRepository") */
class BlogPost
{
/** @Id */
private $id;
/** @Field(type="string") */
private $title;
/** @Field(type="string") */
private $body;
// ...
}
Sunday, March 3, 13
113. Symfony 2 Bundles using MongoDB
- SonataDoctrineMongoDBAdminBundle
- IsmaAmbrosiGeneratorBundle
- TranslationEditorBundle
- ServerGroveLiveChat
Sunday, March 3, 13