So, you want to give Doctrine a try with symfony 1.1 eh? First we will need to setup a new symfony 1.1 project and install the sfDoctrinePlugin for 1.1. Execute the following commands below and continue reading:
$ mkdir symfony1.1Doctrine $ cd symfony1.1Doctrine $ /path/to/symfony generate:project symfony1.1Doctrine $ svn co http://svn.symfony-project.com/plugins/sfDoctrinePlugin/trunk plugins/sfDoctrinePlugin $ php symfony cc
Now, type the following command to list all the new commands that
sfDoctrinePlugin provides. You will notice that it gives you all the same commands as
sfPropelPlugin and lots more!
$ php symfony list doctrine Available tasks for the "doctrine" namespace: :build-all Generates Doctrine model, SQL and initializes the database (doctrine-build-all) :build-all-load Generates Doctrine model, SQL, initializes database, and load data (doctrine-build-all-load) :build-all-reload Generates Doctrine model, SQL, initializes database, and load data (doctrine-build-all-reload) :build-all-reload-test-all Generates Doctrine model, SQL, initializes database, load data and run all test suites (doctrine-build-all-reload-test-all) :build-db Creates database for current model (doctrine-build-db) :build-forms Creates form classes for the current model (doctrine-build-forms) :build-model Creates classes for the current model (doctrine-build-model) :build-schema Creates a schema.xml from an existing database (doctrine-build-schema) :build-sql Creates SQL for the current model (doctrine-build-sql) :data-dump Dumps data to the fixtures directory (doctrine-dump-data) :data-load Loads data from fixtures directory (doctrine-load-data) :dql Execute a DQL query and view the results (doctrine-dql) :drop-db Drops database for current model (doctrine-drop-db) :generate-crud Generates a Doctrine CRUD module (doctrine-generate-crud) :generate-migration Generate migration class (doctrine-generate-migration) :generate-migrations-db Generate migration classes from existing database connections (doctrine-generate-migrations-db, doctrine-gen-migrations-from-db) :generate-migrations-models Generate migration classes from an existing set of models (doctrine-generate-migrations-models, doctrine-gen-migrations-from-models) :init-admin Initializes a Doctrine admin module (doctrine-init-admin) :insert-sql Inserts SQL for current model (doctrine-insert-sql) :migrate Migrates database to current/specified version (doctrine-migrate) :rebuild-db Creates database for current model (doctrine-rebuild-db)
sfDoctrinePlugin currently requires that at least one application be setup, so lets just instantiate a
frontend application now.
$ php symfony generate:app frontend
Now lets setup our database configuration in
config/databases.yml. Open the file in your favorite editor and place the YAML below inside. For this test we are simply using a SQLite database. Doctrine is able to create the SQLite database at the
config/doctrine.db path for you which we will do once we setup our schema and some data fixtures.
all: doctrine: class: sfDoctrineDatabase param: dsn: sqlite:///< ?php echo dirname(__FILE__); ?>/doctrine.db
Now that we have our database configured, lets define our YAML schema files in
config/doctrine/schema.yml. In this example we are setting up a simple
BlogPost model which
--- BlogPost: actAs: Sluggable: fields: [title] Timestampable: columns: title: string(255) body: clob author: string(255) relations: Tags: class: Tag refClass: BlogPostTag foreignAlias: BlogPosts BlogPostTag: columns: blog_post_id: type: integer primary: true tag_id: type: integer primary: true Tag: actAs: [Timestampable] columns: name: string(255)
Now that we have our Doctrine schema defined, lets create some test data fixtures in
data/fixtures/data.yml. Open the file in your favorite editor and paste the below YAML in to the file.
--- BlogPost: BlogPost_1: title: symfony + Doctrine body: symfony and Doctrine are great! author: Jonathan H. Wage Tags: [symfony, doctrine, php] Tag: symfony: name: symfony doctrine: name: doctrine php: name: php
Ok, now for the fun stuff. We have our schema, and we have some data fixtures, so lets run one single Doctrine command and create your database, generate your models, create tables and load the data fixtures.
$ php symfony doctrine-build-all-reload frontend >> doctrine Are you sure you wish to drop your databases? (y/n) y >> doctrine Successfully dropped database f...1.1Doctrine/config/doctrine.db" >> doctrine Successfully created database f...1.1Doctrine/config/doctrine.db" >> doctrine Generated models successfully >> doctrine Created tables successfully >> doctrine Data was successfully loaded
doctrine.db SQLite database is created, all the tables for your schema were created, and the data fixtures were populated in to the tables. Now lets do a little playing around with the data to see how we can use the Doctrine Query Language to retrieve data.
$ php symfony doctrine:dql frontend "FROM BlogPost p, p.Tags t" >> doctrine executing: "FROM BlogPost p, p.Tags t" () >> doctrine - >> doctrine id: 1 >> doctrine title: symfony + Doctrine >> doctrine body: symfony and Doctrine are great! >> doctrine author: Jonathan H. Wage >> doctrine slug: symfony-doctrine >> doctrine created_at: 2008-06-16 12:28:57 >> doctrine updated_at: 2008-06-16 12:28:57 >> doctrine Tags: >> doctrine - >> doctrine id: 1 >> doctrine name: symfony >> doctrine created_at: 2008-06-16 12:28:57 >> doctrine updated_at: 2008-06-16 12:28:57 >> doctrine - >> doctrine id: 2 >> doctrine name: doctrine >> doctrine created_at: 2008-06-16 12:28:57 >> doctrine updated_at: 2008-06-16 12:28:57 >> doctrine - >> doctrine id: 3 >> doctrine name: php >> doctrine created_at: 2008-06-16 12:28:57 >> doctrine updated_at: 2008-06-16 12:28:57
Now, lets do a little explaning of the data that was returned. As you can see the models have a created_at, updated_at and slug column which were not defined in the schema files. These columns are added by the behaviors attached to the schema information under the actAs setting. The
updated_at column are automatically set
onUpdate, and the slug column is a url friendly string that is created from the value of the name column. Doctrine has a few behaviors that are included in core such as
Timestampable, but the behavior system is built to allow anyone to easily write behaviors for their models to re-use over and over.
Now we have our data model all setup and populated with some test fixtures so lets generate an admin generator to manage the blog posts and tags.
$ php symfony doctrine:init-admin frontend blog_posts BlogPost $ php symfony doctrine:init-admin frontend tags Tag
>The admin generator templates for
sfDoctrinePlugin have not yet been fully updated for symfony 1.1 as they still require the
compat_10 option to be turned on in
apps/frontend/config/settings.yml. They will be 100% updated before the official release of symfony 1.1 stable.
Now go open up your web browser and check out the
frontend application and the
tags modules. It should be located at a url like the following:
$ http://localhost/symfony1.1Doctrine/web/frontend_dev.php/blog_posts $ http://localhost/symfony1.1Doctrine/web/frontend_dev.php/tags
Now, with a little configuration of the blog post admin generator, we can control the associated blog post tags by checking checkboxes when editing a blog post. Open
apps/frontend/modules/blog_posts/config/generator.yml and replace the contents with the YAML from below.
generator: class: sfDoctrineAdminGenerator param: model_class: BlogPost theme: default list: display: [=title, author] object_actions: _edit: - _delete: - edit: display: [author, title, body, Tags] fields: author: type: input_tag title: type: input_tag body: type: textarea_tag params: size=50x10 Tags: type: doctrine_admin_check_list params: through_class=BlogPostTag
Now refresh the blog post list and you will see it is cleaned up a little bit. Edit a blog post by clicking the edit icon or the title and you can see below you can check the tags associated to the blog post.
All of the features you get in Propel work 99% the same way with Doctrine, so it should be fairly easy to get the hang of if you are coming from propel. sfDoctrinePlugin implements all the same functionality as sfPropelPlugin as well as several additional features which sfPropelPlugin is not capable of. Below you can find some more information on the major features that Doctrine supports:
- Behaviors - Easily create reusable behaviors for your Doctrine models.
- Migrations - Deploy database schema changes to your production environment through a programmatic interface.
- Doctrine Query Language - Build your database queries through a fluent OO interface
- Validators - Turn on column validators for both database and code level validation.
- Hierarchical Data - Turn your models in to nested sets easily with the flip of a switch.
- Caching - Tune performance by caching your DQL query parsing and the result sets of queries.
If this short tutorial sparked your interest in Doctrine you can check out some other Doctrine resources below to learn more about Doctrine: