Building Data Mapper PHP5

32

description

See all the steps involved to build a fully functional data mapper with object-oriented PHP5 using the power and simplicity of the Standard PHP Library. Based on the early development of a new PHP DataMapper project Vance Lucas started a few months ago as the Model layer for an MVC framework.

Transcript of Building Data Mapper PHP5

Page 1: Building Data Mapper PHP5
Page 2: Building Data Mapper PHP5

“A layer of mappers that moves data between objects and a database while keeping them independent of each other and the mapper itself”

Martin Fowler, Patterns of Enterprise Application Architecture

Page 3: Building Data Mapper PHP5

Object-Relational Mapping (ORM) Objects => Relational Database Relational Database => Objects Think “Translation layer”

Objects have no knowledge of database or SQL

Database has no knowledge of objects Objects have no knowledge of mapper

Page 4: Building Data Mapper PHP5

Allows you to work with native objects in your application

Writing SQL statements for everything in your application can be tedious INSERT, UPDATE especially

Reduce time working on projects

Page 5: Building Data Mapper PHP5

Ultra Portable No dependencies on packages outside PHP5

Use standard naming conventions Zend/PEAR Coding Standards

Simple, clear syntax that fits with PHP Generic Usage

Can work with any table by extending Eliminate the need for custom SQL (in most

cases) Enable full automation wherever possible

Page 6: Building Data Mapper PHP5

Row objects as “dumb” as possible Not tied to the data mapper

Allow custom SQL when needed for flexibility

Support table relations Use adapters for database independence Don’t depend on too much “magic”

No automatic discovery of tables or fields No table or column naming schemes for relations

Page 7: Building Data Mapper PHP5

CodeIgniter DataMapper: http://stensi.com/datamapper/

Page 8: Building Data Mapper PHP5

What objects will we need to start? DataMapper

Result – Individual row object

Start with DataMapper Define basic public interface

Page 9: Building Data Mapper PHP5
Page 10: Building Data Mapper PHP5

What table are we working with? All finders generate SQL

They can use “findBySql” internally get() needs a primary key field defined findFirst() can use find() with a LIMIT clause save() can use insert() or update()

internally insert() and update() both need

fields/values Which fields exist in the table?

Page 11: Building Data Mapper PHP5
Page 12: Building Data Mapper PHP5

Required fields Built-in validation? How do we handle errors?

Field types Cast to specified type or validate

automatically? Table relations

How do we handle table relations? Loading an external mapper – how?

Page 13: Building Data Mapper PHP5
Page 14: Building Data Mapper PHP5
Page 15: Building Data Mapper PHP5

Finders must return FALSE or iterate Results must be able to be in foreach() loop

Relations accessible by set field alias Implementation defined ‘contacts’ $user->contacts should have the related

fields Relations must also return FALSE or iterate

as well as be able to be count()-ed

Page 16: Building Data Mapper PHP5

Eager Loadin

gAlways loads

relations with row

Lazy Loadin

gLoads

relations only when

asked

Page 17: Building Data Mapper PHP5

Wait… How? $user->contacts can’t be an array $user object does not know about mapper

Can’t pull in relations dynamically from mapperwith “__get” magic method

Are we stuck with eager loading?

Page 18: Building Data Mapper PHP5

Relation Object as a placeholder empty until called

Relation Object uses SPL interfaces IteratorAggregate, Countable

foreach() – can iterate count($user->contacts) will work

Use SPL functions to fetch results upon request

Page 19: Building Data Mapper PHP5
Page 20: Building Data Mapper PHP5

$user->contacts foreach() calls ‘getIterator()’

(IteratorAggregate) Calls findAllRelation(), returns ResultSet object

count() calls ‘count()’ (Countable) Calls findAllRelation(), returns count of found

rows

findAllRelation() calls findAll(), caches result findAll() gets related rows from related mapper

with given foreign keys as conditions

Page 21: Building Data Mapper PHP5
Page 22: Building Data Mapper PHP5
Page 23: Building Data Mapper PHP5

Adapters Adapter Interface One Initial adapter to test with

Adapter_PDO_MySQL

Relations Relation Interface Relation_HasMany

Page 24: Building Data Mapper PHP5

PHPDataMapper _Database

_Adapter _PDO

_Mysql

_Exception _Model

_Relation _HasMany

_ResultSet _Result

Page 25: Building Data Mapper PHP5

Why not a generic ‘stdClass’ or an array? A Result object lets us:

Keep track of changed fields for update() Use object syntax – $row->name;

Suppress undefined property errors with __get() Use array syntax – $row[‘name’];

SPL ArrayAccess interface Suppress undefined index errors with offsetGet()

Use getter functions - $row->getName(); Automatic functions for all fields with __call()

Page 26: Building Data Mapper PHP5
Page 27: Building Data Mapper PHP5
Page 28: Building Data Mapper PHP5
Page 29: Building Data Mapper PHP5

Simple syntax to get almost any record All results returned are “live” objects

Can be altered and saved at any time No writing SQL code for mundane

operations Promotes good programming style

Easier to always use mapper object than write SQL queries all over the place

Page 30: Building Data Mapper PHP5

Project Page on my blog www.vancelucas.com/phpdatamapper

Open-Source Project MIT License On Google Code

Martin Fowler’s “P of EAA” http://martinfowler.com/eaaCatalog/

Page 31: Building Data Mapper PHP5

Vance Lucas, 23 Blog: www.vancelucas.com Email: [email protected]

Making websites since age 12 Started learning PHP when PHP3 was new

Oklahoma Baptist University – Shawee Bachelor of Business Administration

Currently work at Back40Design, Inc. www.back40design.com

Page 32: Building Data Mapper PHP5