Object Relational Mapping in PHP

46,892
-1

Published on

"Object Relational Mapping in PHP"

Presentation given to PHPNW on 05/05/09 by Rob Knight

Published in: Technology
6 Comments
39 Likes
Statistics
Notes
No Downloads
Views
Total Views
46,892
On Slideshare
0
From Embeds
0
Number of Embeds
7
Actions
Shares
0
Downloads
865
Comments
6
Likes
39
Embeds 0
No embeds

No notes for slide





























  • Object Relational Mapping in PHP

    1. 1. Object-Relational Mapping in PHP PHPNW May 2009 Rob Knight - Lead Technical Architect, PRWD http://robknight.org.uk
    2. 2. What is ORM? • Manages the translation of objects into relational databases, and vice-versa • Most modern programming languages, including PHP, have a concept of objects • Most databases, including MySQL, Oracle and Postgresql are relational
    3. 3. Objects • Classes define the blueprint • Classes can inherit from each other • Objects contain data and methods • Object data can include other objects and arrays/lists
    4. 4. A very simple class <?php class Employee extends Person { protected $salary; // floating-point value protected $contractLength; // integer value protected $manager; // reference to another Employee object protected $skills; // array of 'Skill' objects protected $history; // array of 'History' objects protected $id; // unique identifier }
    5. 5. Relational Databases • Basic unit of storage is the table • Tables can only contain simple data types (numbers, strings, binary data) • No concept of arrays or lists • Tables can be related by foreign keys
    6. 6. A simple table id name salary manager_id contract_length 1 Alice 20000.00 2 12 2 Bob 150000.00 NULL NULL 3 Clive 15000.00 5 6 4 Derek 32000.00 2 NULL 5 Edith 45000.00 2 NULL
    7. 7. Advantages of ORM • Everything in PHP • In theory, no need to understand the underlying data storage system • ORM can make it easy to adopt good patterns and good database design • Enables familiar OO concepts for manipulating data
    8. 8. Use of PHP concepts <?php $employee = new Employee(); // use of object-oriented concepts $employee->setName(‘Joe’); $employee->save(); // underlying database could by MySQL, SQLite, Postgres or Oracle $peopleToFire = EmployeeTable::select(‘id’)->where(‘salary < 20000’) ->andWhere(‘relatedToChairman = 0’)->limit(5); $subordinates = EmployeeTable::select(‘*’)->where(‘manager_id = ?’, $manager->id); // automatic variable escaping ?>
    9. 9. Disadvantages of ORM • The extra layer of abstraction can be a performance hit • Can be verbose • OO isn’t always best • Can be inflexible • Sometimes framework-dependent
    10. 10. ORM can be verbose Using Propel $c = new Criteria(); $cton1 = $c->getNewCriterion(ArticlePeer::TITLE, '%FooBar%', Criteria::LIKE); $cton1 = $c->getNewCriterion(ArticlePeer::SUMMARY, '%FooBar%', Criteria::LIKE); $cton1->addOr($cton2); $c->add($cton1); $c->add(ArticlePeer::PUBLISHED_AT, $begin, Criteria::GREATER_THAN); $c->addAnd(ArticlePeer::PUBLISHED_AT, $end, Criteria::LESS_THAN); $article = ArticlePeer::doSelect($c); SQL Query SELECT * FROM article WHERE (title LIKE ‘%FooBar%’ OR summary LIKE ‘%FooBar’) AND published_at > {$begin} AND published_at < {$end}
    11. 11. There are many ORMs • Doctrine <http://www.doctrine-project.org> • Propel<http://propel.phpdb.org> • Zend_Db <http://framework.zend.com/manual/en/zend.db.html> • Kohana ORM <http://docs.kohanaphp.com/libraries/orm> • PDO <http://www.php.net/pdo>
    12. 12. ORM Patterns From ‘Patterns of Enterprise Application Architecture’ - Martin Fowler, 2003 • Table Data Gateway Zend_Db_Table, Propel ‘Peer’ classes • Row Data Gateway Zend_Db_Table_Row • Data Mapper • Active Record Doctrine_Record, Propel classes
    13. 13. Table Data Gateway • One class per table • Basic functions for inserting, updating, deleting data from the table • Can also handle related tables • Data is returned in simple array/POPO form
    14. 14. An example <?php // Using Zend_Db_Table to fetch a record from a table class BlogPostTable extends Zend_Db_Table_Abstract { ... } $table = new BlogPostTable(); $select = $table->select()->where(‘author_id = ?’, $id)->order(‘created DESC’); $row = $table->fetchRow($select); // row is an array, with keys for column names echo $row->title; // prints the title of the blog post ?>
    15. 15. Row Data Gateway • Class for manipulating a single row • Separates finding/searching from manipulation • Database access logic only
    16. 16. An example <?php // create row using table object $table = new BlogPostTable(); $newRow = $table->createRow(); // set values $newRow->title = ‘New Blog Post’; $newRow->body = ‘Lorem ipsum....’; // save the row to the table $newRow->save(); ?>
    17. 17. Active Record • Similar to Row Data Gateway • Classes inherit from a ‘Record’ class • Classes may also implement ‘behaviours’ • Some mixing of data storage code and domain logic
    18. 18. An example <?php class User extends Doctrine_Record { public function setTableDefinition() { $this->hasColumn('username', 'string', 255); $this->hasColumn('password', 'string', 255); } public function authenticate($username, $password) { return ($this->username == $username) && ($this->password == $password); } } $table = Doctrine::getTable(‘User’); $user = $table->find($id); if ($user->authenticate($username, $password)) { print “Authenticated as user id {$id}”; }
    19. 19. Data Mapper • Takes your object model and saves it to database • Mapper is external to your classes • Good separation of concerns, keeps the OO away from the data • Hard to implement as a ‘drop-in’ system
    20. 20. Extras • Schema management • Auto-creation of forms, admin areas • Database creation and migration • Plugins and behaviours
    21. 21. Schemas User: tableName: users columns: id: type: integer(4) primary: true autoincrement: true unsigned: true forename: type: string(50) surname: type: string(50) email: type: string(50) password: type: string(32) actAs: Timestampable: created: name: created type: integer options: unsigned: true
    22. 22. Plugins • Logging • Profiling • Behaviours - timestampable, sluggable and more • Events • Inheritance • Caching
    23. 23. Performance Issues • Joins Complex relationships between objects can lead to inefficient joins between tables • ‘Hydration’ Transforming database rows into full PHP objects can be expensive • Many classes, many files Loading many auto-generated classes can cause performance issues
    24. 24. Alternatives • Object databases • Document databases • Key-value stores • Hybrids
    25. 25. Object and Document Databases • Persevere Stores JavaScript/JSON objects • CouchDB Stores documents in JSON format • Abdera Stores documents using the Atom Publishing Protocol
    26. 26. Key-value stores • SimpleDB • BigTable • Mnesia
    27. 27. JSON: a better fit? employees: [ { name: “Alice”, salary: 35000.00, skills: [ “C++”, “PHP”, “SQL” ] }, { name: “Bob”, salary: 24000.00, skills: [ “Java”, “C#” ] } ] Might JSON object storage be better for PHP?
    28. 28. Conclusions • Choose your ORM library carefully • Experiment • Don’t over-complicate • Maybe ORM is the wrong choice anyway? • Alternatives are starting to become viable
    29. 29. Thanks for listening Any questions? Slides available at http://robknight.org.uk/presentations
    1. A particular slide catching your eye?

      Clipping is a handy way to collect important slides you want to go back to later.

    ×