View
116
Download
0
Category
Preview:
DESCRIPTION
Zend Framework and Doctrine Putting the M in Zend. A Few Notes…. On the presentation: For the so inclined, the “model object” referred to is equivalent to the DDD domain object (I think). On Me: Isaac Foster ( isaac.z.foster@gmail.com ) Zend Framework Certified - PowerPoint PPT Presentation
Citation preview
Zend Framework and Doctrine Putting the M in Zend
A Few Notes…
• On the presentation:– For the so inclined, the “model object” referred to
is equivalent to the DDD domain object (I think).• On Me:– Isaac Foster (isaac.z.foster@gmail.com)– Zend Framework Certified– Currently working for Tabula Digita.
Your Honor, I Intend to Prove…
• That Doctrine’s value added over Zend_Db is the framework it provides for business logic.
• Other features make it a complete, powerful tool.
First TLA: MVC
• Model – Behavior and data of the application.• View – Display information.• Controller – Takes inputs
from the user, invokes the model and chooses the view.
The M in MVC• Model objects hold business data and logic.• Model != DB:– True, data that a model acts on is often persisted in a db.– Db code in the model layer, not necessarily model object.– Model object should focus on what makes it special.
your models -->
Separate Business and Persistence Logic
• DBAL (Database Abstraction Layer)– One API to rule them all.
• ORM (Object Relational Mapper)– Put the object in, get the object out.
• ↑Consistency, ↑Reliability, ↑Reuse, ↑Ease…• It’s a Good Thing
Snoop shares histhoughts on the activerecord pattern.
Frameworks and Libraries Help us Achieve These (and other) Goals
and one of those frameworks is…
Zend Framework
• MVC Framework + Components• Great View and Controller framework:
IOC lets you focus on the ACTION, not the request, response, router, dispatcher …
• Components Zend_Acl for authorization. Zend_Auth for authentication Zend_Session for session management
… what about M?
The M in Z-E-N-D?
• Zend_Db wraps db driver for DBAL. • Zend_Db_Table wraps a table, gives some
structure to a model, ORM-ish.• Zend_DB_Table_Row wraps row, active record
features.
The M in Z-E-N-D?
• Provides:– Protection from SQL Injection– Query Construction API– Transactions– Profiler– Cache
So What’s the Problem?
Definitely Zend_Db, not Zend_Model• Not much from a business logic perspective:– Little help you stay DRY with business logic.–Not much in the way of model life-cycle hooks
(preSave, postSave, preDelete, etc).• Still thinking about db’s, tables, and table
references, not models and relationships.
Doctrine is… DBAL + ORM + Active Record + Model Framework
• Provides framework for business logic…– Plugins hook into events, core code
untouched.– Reuse code and structure with behaviors.– Configure validation and rules.– Doctrine model IOC ≈ ZF controllers IOC
• Think more about models, not tables.
Doctrine
• Will create your database tables.• Migration tools.• Performance tools and configurations.• Utilities– Command line interface– Pagination
Let’s Take It For a Spin
A Problem To Solve…
• Need to keep track of Users– Auto incremented id.– Email property must be valid email address.– Password must be hashed.– Want to send a confirmation email to new users
after they register.
A Doctrine Solution
A Harder Problem…
• Exercise 1st Amendment right to blog– Need to update blog post, track previous versions.– Want to attach images to a post.• Store them on Amazon S3
– Update author’s numPosts field after blogging.– Don’t feel like creating tables manually.
A Doctrine Solution
Doctrine Basics
Guideposts
• Doctrine_Connection ≈ Zend_Db• Doctrine_Table ≈ Zend_Db_Table_Abstract• Doctrine_Record ≈ Zend_Db_Table_Row_Abstract
Doctrine Core Classes
• Doctrine_Manager– Manages connections, knows available drivers.– Handles application wide options.
• Doctrine_Core– Manages autoloading.– Methods to create tables, export database, etc.
Connections
• Connect to a database:
• MySql, MsSql, Oracle, Postgre, DB2, Sqlite.
Bootstrapping
• Connections and autoloading in bootstrap.– Doctrine autoloader for models.– Zend Autoloader for Doctrine library files.
Defining Models: Goal
• Model creation should be like Lego building.– Configure when possible, code if necessary.• Let framework do the easy stuff.• Leverage framework for harder stuff.
Defining Models
• Each model has a Doctrine_Table.– Structure and meta-info stored there.
• setTableDefinition and setUp create the table:– hasColumn → add properties – hasOne → add one-to-one relationships– hasMany → add one-to-many and many-to-many
• Model can be defined in code or YAML config.
A More Detailed Problem…
• Need a Blog model with:– Unique integer key.– Title (non null, less than 150 chars)
– Text (non null).– Flag for whether it is published (default false).– Foreign key for relating to the author.
• DETAILS, REQUIREMENTS, RULES!! WHAT TO DO!!
Defining Models: Properties
Doctrine_Record::hasColumn()
• Adds properties to your model.– Blog has a title property, content property, etc.
• hasColumn($name, $type [,$length, $options])– name – “propertyName” or “columnName as propertyName”
– type - int, string, boolean, float, many more.– length – max length– options – options
Property Options
• default – sets default value.• primary – if the primary key.• autoincrement – if autoincrementing id.• notnull – enforce the value not be null.• email – enforce the value be a valid email.• Other validator indicators
More Details…
• Blog also needs:– An Author.– Images attached to it for upload and display.
• WHAT TO DO!!
Defining Models: Relationships
Doctrine_Record ::hasOne()
• Defines one-to-one associations between your model and another.
• hasOne($associationClass [, $options])– associationClass –either “associationClass” or
“associationClass as associationName”– options – the association options
Doctrine_Record::hasMany()
• Add one-to-many, many-to-many associations.• A Blog has Comments (1-to-many).
• A User can be in many Groups and a Group can have many Users (many-to-many).
• hasMany($associationClass [, $options])– name – “associationClass” or “associationClass as
associationName”– options – association options
More Problem Specs…
• When…– The blog is created:
• An email should be sent to all editors informing them they need to proof read it.
– The blog is published:• An email should be sent to the mailing list informing them of the
new post.• A Facebook story should be published doing the same.• A Tweet should be sent with the fist 140 characters.
– The blog is saved (inserted or updated).• All image objects associated with it must be uploaded to Amazon
S3
Note That…
• Stuff happens when other stuff happens.– On X, do Y.
• Not Blog’s responsibility to email, Facebook, Tweet, or upload to S3.– Probably shouldn’t be hardcoded into Blog class.
• COMPLEXITY!! AND YOU WANT ARCHITECTURAL PURITY!!! LAAAAMMMEE!!!
Plugins (Listeners)
• As Zend front controller plugins hook into preDispatch, postDispatch, etc, events…
• …so Doctrine record plugins hook into:– pre/post Insert/Update/Save/Delete, others.
• Also plugins for connections. Hook into:– pre/post connect/transactionBeing/fetch/exec, others.
Plugins (Listeners)
• IOC: add logic to a model or connection without touching the core code.
• Log and profile all SQL queries (connection hooks).
• Send an email to a user when they sign up (model hooks).
• Register as many as you need.• Similar to JS DOM events.
Step One: Create the Plugins
Step Two: Add the Plugins
Doctrine_Record::addListener()
• Add a plugin to run when something happens.• addListener($listener, $listenerName = null)– listener the plugin to add.– listenerName name of the plugin, useful for
removing later.
More Problem Specs…
• The Blog must…– Keep track of when it was created and last updated.
• Timestamps should be set automatically, not explicitly by consumer code.
– Keep track of previous versions.• Provide revert and get versions methods.• Versioning happens automatically, not in consumer code.
– Be flaggable.• Provide a flag method.• Automatically increment the Blog’s flag count.
Notice That…
• These behaviors are generic:– Probably want them elsewhere, but in different
combinations, with different configurations.– Implementation not special to Blog.
• Define base classes for each and extend…• …But no multiple inheritance in PHP.• I’VE HAD ALL I CAN STANDS, AND I CAN’T
STANDS NO MORE!
Mix-in With Templates
• Avoid single inheritance issues. – Don’t choose between extending Flaggable, Taggable,
Locateable, Versionable, just mix-in all of them!– Stay DRY.
• Inversion of (model definition) control.– Add properties, relationships, plugins,… and
methods!• Encapsulate generic behavior in one place.• Add as many as you want.
Defining Models: BehaviorsStep One: Find a Template…
• In “path/to/Doctrine/Template”
• Community contributed at http://trac.doctrine-project.org/browser/extensions?rev=7461
Defining Models: Behaviors…or Make Your Own
Defining Models: BehaviorsStep Two: Tell Your Model to “actAs” the Template
Doctrine_Record::actAs()
• Adds a template to your model.• actAs($template[, $options])– $template – template name or instance.– $options – configuration options
Defining Models: Summary
• Model creation should be like Lego building.– Snap on properties and relationships.– Snap in listeners that get called at hook points.– Snap on behavior with templates.
Querying Models
• Query your model with:– Doctrine_Table finder methods• Doctrine_Table::find() – by primary key• Doctrine_Table::findAll()• Doctrine_Table::findBy() – by specified key• Others
– Doctrine Query Language• SQL like syntax• Translation to native SQL handled by Doctrine• Similar to various Zend_Db statement classes
Querying: Finders and DQL
Please Sir, I Want Some More!
More!! You Want More!
• Will create tables in DB for you.– Doctrine_Core::createTablesFromModels($path)– Doctrine_Core::createTablesFromArray($models)– Command line.
• Caching– Memcached, APC, DB
• Migration tools.• Performance tools.• Pagination, other utilities.
Questions?
Appendix: Other Resources
• Zend Casts (great for other stuff too)– http://www.zendcasts.com/category/screencasts
/databases/doctrine-databases/• Doctrine 1.2 Documentation
– http://www.doctrine-project.org/projects/orm/1.2/docs/manual/introduction/en
• Matthew Weier O'Phinney’s Blog– http://
weierophinney.net/matthew/archives/220-Autoloading-Doctrine-and-Doctrine-entities-from-Zend-Framework.html
• Google it!
Recommended