gstreamer0.10-ffmpeg
gstreamer0.10-plugins-good
packages.
Yo guys! Time to level-up our project in a big way. I mean, big. This series is all about an incredible library called Dog-trine. Wait, that's not right - it's Doctrine. But anyways, Doctrine is kinda like a dog: a dog fetches a bone, Doctrine fetches data from the database. But Doctrine does not pee in the house. That's part of what makes it awesome.
But back up: is Doctrine part of Symfony? Nope. Symfony doesn't care how or if you talk to a database at all. You could use a direct PDO connection, use Doctrine, or do something else entirely. As usual, you're in control.
If you want to code along - which you should - then download the code from the
screencast page and move into the directory called start
. I already have the start
code downloaded, so I'll go straight to opening up a new terminal and starting the
built-in sever with:
./bin/console server:run
Tip
You may also need to run composer install
and a few other tasks. Check the README
in the download for those details.
Perfect!
Doctrine is an ORM: object relational mapper. In short, that means that every table -
like genus
- will have a corresponding PHP class that we will create. When you query
the genus
table, Doctrine will give you a Genus
object. Every property in the
class maps to a column in the table. Keep this simple idea in mind as we go along:
this mapping between a table and a PHP class is Doctrine's main goal.
Oh, and before we hop in, I want you to remember something very important: all the tools in Symfony are optional, including Doctrine. If Doctrine - or any tool - does more harm than good while solving a problem, skip it and do something simpler. Tools are meant to serve you, not the other way around.
Our sweet app displays information about different ocean-living genuses... but so far, all that info is hardcoded. That's so sad.
Instead, let's create a genus
table in the database and load all of this dynamically
from there. How do you create a database table with Doctrine? You don't! Your job
is to create a class, then Doctrine will create the table based on that class.
It's pretty sweet. Oh, and the whole setup is going to take about 2 minutes and
25 lines of code. Watch.
Create an Entity
directory in AppBundle
and then create a normal class inside
called Genus
:
... lines 1 - 2 | |
namespace AppBundle\Entity; | |
class Genus | |
{ | |
} |
You're going to hear this word - entity - a lot with Doctrine. Entity - it sounds like an alien parasite. Fortunately, it's less scary than that: an entity is just a class that Doctrine will map to a database table.
To do that - Doctrine needs to know two things: what the table should be called and
what columns it needs. To help it out, we're going to use... drumroll... annotations!
Remember, whenever you use an annotation, you need a use
statement for it. This
will look weird, but add a use
for a Column
class and let it auto-complete from
Doctrine\ORM\Mapping
. Remove the Column
part and add as ORM
:
... lines 1 - 2 | |
namespace AppBundle\Entity; | |
use Doctrine\ORM\Mapping as ORM; | |
... lines 6 - 15 |
Tip
You can also configure Doctrine with YAML, XML or PHP, instead of annotations. Check Add Mapping Information to see how to configure it.
Every entity class will have that same use
statement. Next, put your cursor inside
the class and open up the "Code"->"Generate" menu - cmd
+N
on a Mac. Ooh, one of the options
is ORM Class
. Click that... and boom! It adds two annotations - @ORM\Entity
and
@ORM\Table
above the class:
... lines 1 - 6 | |
/** | |
* @ORM\Entity | |
* @ORM\Table(name="genus") | |
*/ | |
class Genus | |
{ | |
} |
Doctrine now knows this class should map to a table called genus
.
But that table won't have any columns yet. Lame. Add two properties to get us rolling:
id
and name
. To tell Doctrine that these should map to columns, open up the
"Code"->"Generate" menu again - or cmd
+N
. This time, select ORM Annotation
and
highlight both properties. And, boom again!
... lines 1 - 6 | |
/** | |
* @ORM\Entity | |
* @ORM\Table(name="genus") | |
*/ | |
class Genus | |
{ | |
/** | |
* @ORM\Id | |
* @ORM\GeneratedValue(strategy="AUTO") | |
* @ORM\Column(type="integer") | |
*/ | |
private $id; | |
/** | |
* @ORM\Column(type="string") | |
*/ | |
private $name; | |
} |
Now we have annotations above each property. The id
columns is special - it will
almost always look exactly like this: it basically says that id
is the primary
key.
After that, you'll have whatever other columns you need. Hey, look at the type
option that's set to string
. That's a Doctrine "type", and it will map to a varchar
in MySQL. There are other Doctrine types for strings, floats and text - we'll talk
about those soon!
And with just 25 lines of code, we're done! In a second, we'll ask Doctrine to create
the genus
table for us and we'll be ready to start saving stuff. Well, let's get
to it!
// composer.json
{
"require": {
"php": ">=5.5.9",
"symfony/symfony": "3.1.*", // v3.1.4
"doctrine/orm": "^2.5", // v2.7.2
"doctrine/doctrine-bundle": "^1.6", // 1.6.4
"doctrine/doctrine-cache-bundle": "^1.2", // 1.3.0
"symfony/swiftmailer-bundle": "^2.3", // v2.3.11
"symfony/monolog-bundle": "^2.8", // 2.11.1
"symfony/polyfill-apcu": "^1.0", // v1.2.0
"sensio/distribution-bundle": "^5.0", // v5.0.22
"sensio/framework-extra-bundle": "^3.0.2", // v3.0.16
"incenteev/composer-parameter-handler": "^2.0", // v2.1.2
"composer/package-versions-deprecated": "^1.11", // 1.11.99
"knplabs/knp-markdown-bundle": "^1.4", // 1.4.2
"doctrine/doctrine-migrations-bundle": "^1.1" // 1.1.1
},
"require-dev": {
"sensio/generator-bundle": "^3.0", // v3.0.7
"symfony/phpunit-bridge": "^3.0", // v3.1.3
"nelmio/alice": "^2.1", // 2.1.4
"doctrine/doctrine-fixtures-bundle": "^2.3" // 2.3.0
}
}