SlideShare a Scribd company logo
1 of 3
Cool Object Building With PHP
  February 24, 2009 at 1:16 am

  At work I write mostly PHP code and work among some very respected
  developers in the PHP community. One thing that bothers me about the PHP
  world is how most people think in terms of arrays instead of in terms of objects.
  This is understandable considering Object OrientedPHP didn't really come around
  until PHP 5 so using arrays is probably an old habit that is hard to get rid of, but
  that is no excuse. Arrays have their uses, but I think more often than not an
  object can be used instead.

  One of the core problems most PHP developers run into is finding a way to map
  records in the database to PHP objects. This is understandable considering your
  database model is often very different from your object model, and at the
  moment PHP does not offer any great solutions that I know of. Basically my
  proposal involves two parts:

1. a DAO (data access object) class
2. a Builder class

  What these classes do is very simple: The DAO contains the SQL to query the
  database and then calls a builder to take the resulting array and assemble an
  object (or a collection of objects) out of it which is then returned.

  This implementation allows for no question about what is being returned and it
  forces you to use more objects in your code which is never a bad thing. Another
  plus is that you can cache the collections directly in memcache and therefore
  when you hit cache your PHP doesn't have to do any work at all with the data.

  This is actually the method I am using on this site so I will demonstrate using real
  world examples, but before I do so I want to point out that much of the
  awesomeness in the example relies on a certain naming pattern for your classes.
  For example I have classes named Blog_Dao, Blog_Comment, Blog_Builder, etc.

  The first code I am going to show you is the base DAO class I am using:

  1 <?php 2 class Dao 3 { 4 /** 5 * @var Db 6 */ 7 protected $_db; 8 9 /** 10 * @var Builder 11
  */ 12 protected $_builder; 13 14 /** 15 * constructor 16 * 17 * sets the database class this dao
  should use 18 * 19 * @return void 20 */ 21 function __construct() 22 { 23 $this->_db = new
  Db(); 24 } 25 26 /** 27 * determines what builder class to use 28 * 29 * @param string $builder
  30 * @return Builder 31 */ 32 protected function _getBuilder($builderName) 33 { 34 // if we have
  already instantiated a builder class 35 if (!is_null($this->_builder)) { 36 return $this->_builder;
  37 } 38 39 // if we have not passed in a specific builder to use 40 if (is_null($builderName)) { 41
  $builderName = str_replace('_Dao', '_Builder', get_class($this)); 42 } 43 44 // make sure the
  builder exists 45 if (!class_exists($builderName)) { 46 throw new Exception($builderName . ' does
  not exist!'); 47 } 48 49 // instantiate the builder 50 $this->_builder = new $builderName; 51 52
  return $this->_builder; 53 } 54 55 /** 56 * calls the builder to build a collection of the stuff
returned from the 57 * dao! 58 * 59 * @param mixed $records 60 * @param string $builder
name of class to use for building 61 * @return Collection 62 */ 63 protected function
_buildCollection($records, $builder = null) 64 { 65 // if the database doesn't have any records 66
if ($records === false) { 67 return false; 68 } 69 70 $collection = new Collection(); 71 foreach
($records as $record) { 72 $collection->append($this->_buildOne($record, $builder)); 73 } 74
return $collection; 75 } 76 77 /** 78 * calls the builder and builds a single object 79 * 80 *
@param mixed 81 * @param string $builder 82 * @return Object 83 */ 84 protected function
_buildOne($record, $builder = null) 85 { 86 // if the database doesn't have any record 87 if
($record === false) { 88 return false; 89 } 90 91 $builder = $this->_getBuilder($builder); 92
return $builder->assemble($record); 93 } 94 } 95

The first thing you will probably notice is that $builder is optional! This means you
only need to pass in a builder class if the builder is in some wacky place it
shouldn't be. So the Blog_Comment_Dao class will default to the
Blog_Comment_Builder which makes sense and it forces good use of objects
cause it means everything you create a dao for is an object and that DAO should
only return things related to that object. Another point of note is the Collection
object. This is simply a child of ArrayObject to allow easier access to ArrayObject
methods.

Anyway now it is time to see this in action! Here is actual code from this site to
get all comments related to a given blog post taken from the Blog_Comment_Dao
which extends the base Dao class:

39 /** 40 * retrieves all comments for a given blog 41 * 42 * @param int $blogId 43 * @return
Collection 44 */ 45 public function get($blogId) 46 { 47 $query = '/* ' . __METHOD__ . ' */' . 48
"SELECT bc.id id, 49 bc.name name, 50 bc.website website, 51 bc.email email, 52 bc.body body,
53 bc.posted_on posted_on 54 FROM blog_comment bc 55 WHERE bc.blog_id = :blog_id"; 56 57
$sth = $this->_db->prepare($query); 58 $sth->bindValue(':blog_id', $blogId); 59 $sth-
>execute(); 60 $records = $sth->fetchAllAssoc(); 61 62 return $this->_buildCollection($records);
63 }

Look how pretty that is! Now let's take a look at the Blog_Comment_Builder class
to see how simple that is as well:

1 <?php 2 class Blog_Comment_Builder 3 { 4 /** 5 * creates a comment object from database
record 6 * 7 * @param array 8 * @return Blog_Comment 9 */ 10 public function assemble(array
$record) 11 { 12 $comment = new Blog_Comment(); 13 $comment->name = $record['name'];
14 $comment->website = $record['website']; 15 $comment->email = $record['email']; 16
$comment->body = $record['body']; 17 $comment->postedOn = new
Date($record['posted_on']); 18 return $comment; 19 } 20 } 21

Something to note here is that these are not public properties. They are all
protected, but each domain object extends a Domain_Object class that has magic
__set() and __get() methods so you don't have to write setters and getters for
every single property in every single class! For more on that check out this
post by Matthew Purdon.

You can see that properties of objects can still be other objects such as the Date
class here. In the case where you are showing a bunch of Users on your site and
each one has a bunch of other classes associated it with it you probably wouldn't
want to use the other class's builders because then you end up running queries in
loops which is never a good thing. Instead you can handle that logic in the
User_Builder cause at the end of the day even if there are other classes involved
the Builder is just returning one object from one database record.

An obvious downfall here, of course, is that every object needs to have its own
Builder class even though the builder seems like something that could happen
automatically if there was better ORM support in PHP or any for that matter. This
is something that PHP developers are used to, however, because no matter what
framework you use, you still end up having to write tons of code to do even
simple operations. Hopefully this will make your life easier.

More Related Content

What's hot

Exercises of java tutoring -version1
Exercises of java tutoring -version1Exercises of java tutoring -version1
Exercises of java tutoring -version1Uday Sharma
 
Grain final border one
Grain final border oneGrain final border one
Grain final border oneAshish Gupta
 
Basic Oops concept of PHP
Basic Oops concept of PHPBasic Oops concept of PHP
Basic Oops concept of PHPRohan Sharma
 
Scalable JavaScript Design Patterns
Scalable JavaScript Design PatternsScalable JavaScript Design Patterns
Scalable JavaScript Design PatternsAddy Osmani
 
Creational pattern 2
Creational pattern 2Creational pattern 2
Creational pattern 2Naga Muruga
 
JavaScript Growing Up
JavaScript Growing UpJavaScript Growing Up
JavaScript Growing UpDavid Padbury
 
JavaScript - From Birth To Closure
JavaScript - From Birth To ClosureJavaScript - From Birth To Closure
JavaScript - From Birth To ClosureRobert Nyman
 
Powerful JavaScript Tips and Best Practices
Powerful JavaScript Tips and Best PracticesPowerful JavaScript Tips and Best Practices
Powerful JavaScript Tips and Best PracticesDragos Ionita
 
Memory management in Objective C
Memory management in Objective CMemory management in Objective C
Memory management in Objective CNeha Gupta
 
iOS Memory Management Basics
iOS Memory Management BasicsiOS Memory Management Basics
iOS Memory Management BasicsBilue
 
2012 oct-12 - java script inheritance
2012 oct-12 - java script inheritance2012 oct-12 - java script inheritance
2012 oct-12 - java script inheritancepedro.carvalho
 
Advanced javascript
Advanced javascriptAdvanced javascript
Advanced javascriptDoeun KOCH
 
The Naked Bundle - Symfony Barcelona
The Naked Bundle - Symfony BarcelonaThe Naked Bundle - Symfony Barcelona
The Naked Bundle - Symfony BarcelonaMatthias Noback
 
Web Security - Hands-on
Web Security - Hands-onWeb Security - Hands-on
Web Security - Hands-onAndrea Valenza
 
From YUI3 to K2
From YUI3 to K2From YUI3 to K2
From YUI3 to K2kaven yan
 
Professional JavaScript Development - Creating Reusable Code
Professional JavaScript Development -  Creating Reusable CodeProfessional JavaScript Development -  Creating Reusable Code
Professional JavaScript Development - Creating Reusable CodeWildan Maulana
 

What's hot (20)

Exercises of java tutoring -version1
Exercises of java tutoring -version1Exercises of java tutoring -version1
Exercises of java tutoring -version1
 
Grain final border one
Grain final border oneGrain final border one
Grain final border one
 
Basic Oops concept of PHP
Basic Oops concept of PHPBasic Oops concept of PHP
Basic Oops concept of PHP
 
Scalable JavaScript Design Patterns
Scalable JavaScript Design PatternsScalable JavaScript Design Patterns
Scalable JavaScript Design Patterns
 
Creational pattern 2
Creational pattern 2Creational pattern 2
Creational pattern 2
 
JavaScript Growing Up
JavaScript Growing UpJavaScript Growing Up
JavaScript Growing Up
 
JavaScript - From Birth To Closure
JavaScript - From Birth To ClosureJavaScript - From Birth To Closure
JavaScript - From Birth To Closure
 
JavaScript Patterns
JavaScript PatternsJavaScript Patterns
JavaScript Patterns
 
Powerful JavaScript Tips and Best Practices
Powerful JavaScript Tips and Best PracticesPowerful JavaScript Tips and Best Practices
Powerful JavaScript Tips and Best Practices
 
Objective C Memory Management
Objective C Memory ManagementObjective C Memory Management
Objective C Memory Management
 
Memory management in Objective C
Memory management in Objective CMemory management in Objective C
Memory management in Objective C
 
iOS Memory Management Basics
iOS Memory Management BasicsiOS Memory Management Basics
iOS Memory Management Basics
 
Introduction to jOOQ
Introduction to jOOQIntroduction to jOOQ
Introduction to jOOQ
 
2012 oct-12 - java script inheritance
2012 oct-12 - java script inheritance2012 oct-12 - java script inheritance
2012 oct-12 - java script inheritance
 
Javascript Best Practices
Javascript Best PracticesJavascript Best Practices
Javascript Best Practices
 
Advanced javascript
Advanced javascriptAdvanced javascript
Advanced javascript
 
The Naked Bundle - Symfony Barcelona
The Naked Bundle - Symfony BarcelonaThe Naked Bundle - Symfony Barcelona
The Naked Bundle - Symfony Barcelona
 
Web Security - Hands-on
Web Security - Hands-onWeb Security - Hands-on
Web Security - Hands-on
 
From YUI3 to K2
From YUI3 to K2From YUI3 to K2
From YUI3 to K2
 
Professional JavaScript Development - Creating Reusable Code
Professional JavaScript Development -  Creating Reusable CodeProfessional JavaScript Development -  Creating Reusable Code
Professional JavaScript Development - Creating Reusable Code
 

Viewers also liked

VMware如何使用,最好用的虚拟机,VMware有哪些功能?关于虚拟机V...
VMware如何使用,最好用的虚拟机,VMware有哪些功能?关于虚拟机V...VMware如何使用,最好用的虚拟机,VMware有哪些功能?关于虚拟机V...
VMware如何使用,最好用的虚拟机,VMware有哪些功能?关于虚拟机V...wensheng wei
 
Java JNI 编程进阶
Java JNI 编程进阶     Java JNI 编程进阶
Java JNI 编程进阶 wensheng wei
 
Subversion快速入门教程
Subversion快速入门教程Subversion快速入门教程
Subversion快速入门教程wensheng wei
 
非常时期,如何用
非常时期,如何用非常时期,如何用
非常时期,如何用wensheng wei
 
Top 10 Web Vulnerability Scanners
Top 10 Web Vulnerability ScannersTop 10 Web Vulnerability Scanners
Top 10 Web Vulnerability Scannerswensheng wei
 
Java正则表达式详解
Java正则表达式详解Java正则表达式详解
Java正则表达式详解wensheng wei
 
Apache配置文件说明
Apache配置文件说明Apache配置文件说明
Apache配置文件说明wensheng wei
 
必备的 Java 参考资源列表
必备的 Java 参考资源列表必备的 Java 参考资源列表
必备的 Java 参考资源列表wensheng wei
 
Windows 系统45个小技巧
Windows 系统45个小技巧Windows 系统45个小技巧
Windows 系统45个小技巧wensheng wei
 
揭秘全球最大网站Facebook背后的那些软件
揭秘全球最大网站Facebook背后的那些软件揭秘全球最大网站Facebook背后的那些软件
揭秘全球最大网站Facebook背后的那些软件wensheng wei
 
Samba Optimization and Speed Tuning f...
Samba Optimization and Speed Tuning f...Samba Optimization and Speed Tuning f...
Samba Optimization and Speed Tuning f...wensheng wei
 
CentOS5 apache2 mysql5 php5 Zend
CentOS5 apache2 mysql5 php5 ZendCentOS5 apache2 mysql5 php5 Zend
CentOS5 apache2 mysql5 php5 Zendwensheng wei
 

Viewers also liked (15)

issue35 zh-CN
issue35 zh-CNissue35 zh-CN
issue35 zh-CN
 
VMware如何使用,最好用的虚拟机,VMware有哪些功能?关于虚拟机V...
VMware如何使用,最好用的虚拟机,VMware有哪些功能?关于虚拟机V...VMware如何使用,最好用的虚拟机,VMware有哪些功能?关于虚拟机V...
VMware如何使用,最好用的虚拟机,VMware有哪些功能?关于虚拟机V...
 
Java JNI 编程进阶
Java JNI 编程进阶     Java JNI 编程进阶
Java JNI 编程进阶
 
Subversion快速入门教程
Subversion快速入门教程Subversion快速入门教程
Subversion快速入门教程
 
非常时期,如何用
非常时期,如何用非常时期,如何用
非常时期,如何用
 
Top 10 Web Vulnerability Scanners
Top 10 Web Vulnerability ScannersTop 10 Web Vulnerability Scanners
Top 10 Web Vulnerability Scanners
 
Java正则表达式详解
Java正则表达式详解Java正则表达式详解
Java正则表达式详解
 
Apache配置文件说明
Apache配置文件说明Apache配置文件说明
Apache配置文件说明
 
必备的 Java 参考资源列表
必备的 Java 参考资源列表必备的 Java 参考资源列表
必备的 Java 参考资源列表
 
光盘刻录
光盘刻录光盘刻录
光盘刻录
 
Windows 系统45个小技巧
Windows 系统45个小技巧Windows 系统45个小技巧
Windows 系统45个小技巧
 
耳朵拉长
耳朵拉长耳朵拉长
耳朵拉长
 
揭秘全球最大网站Facebook背后的那些软件
揭秘全球最大网站Facebook背后的那些软件揭秘全球最大网站Facebook背后的那些软件
揭秘全球最大网站Facebook背后的那些软件
 
Samba Optimization and Speed Tuning f...
Samba Optimization and Speed Tuning f...Samba Optimization and Speed Tuning f...
Samba Optimization and Speed Tuning f...
 
CentOS5 apache2 mysql5 php5 Zend
CentOS5 apache2 mysql5 php5 ZendCentOS5 apache2 mysql5 php5 Zend
CentOS5 apache2 mysql5 php5 Zend
 

Similar to Cool Object Building With PHP

Wade not in unknown waters. Part one.
Wade not in unknown waters. Part one.Wade not in unknown waters. Part one.
Wade not in unknown waters. Part one.PVS-Studio
 
Oops concepts in php
Oops concepts in phpOops concepts in php
Oops concepts in phpCPD INDIA
 
Zend framework 03 - singleton factory data mapper caching logging
Zend framework 03 - singleton factory data mapper caching loggingZend framework 03 - singleton factory data mapper caching logging
Zend framework 03 - singleton factory data mapper caching loggingTricode (part of Dept)
 
Data Migrations in the App Engine Datastore
Data Migrations in the App Engine DatastoreData Migrations in the App Engine Datastore
Data Migrations in the App Engine DatastoreRyan Morlok
 
oop_in_php_tutorial_for_killerphp.com
oop_in_php_tutorial_for_killerphp.comoop_in_php_tutorial_for_killerphp.com
oop_in_php_tutorial_for_killerphp.comtutorialsruby
 
oop_in_php_tutorial_for_killerphp.com
oop_in_php_tutorial_for_killerphp.comoop_in_php_tutorial_for_killerphp.com
oop_in_php_tutorial_for_killerphp.comtutorialsruby
 
Oop in php_tutorial_for_killerphp.com
Oop in php_tutorial_for_killerphp.comOop in php_tutorial_for_killerphp.com
Oop in php_tutorial_for_killerphp.comayandoesnotemail
 
Dependency injection in Drupal 8
Dependency injection in Drupal 8Dependency injection in Drupal 8
Dependency injection in Drupal 8Alexei Gorobets
 
This upload requires better support for ODP format
This upload requires better support for ODP formatThis upload requires better support for ODP format
This upload requires better support for ODP formatForest Mars
 
Ejb3 Struts Tutorial En
Ejb3 Struts Tutorial EnEjb3 Struts Tutorial En
Ejb3 Struts Tutorial EnAnkur Dongre
 
Ejb3 Struts Tutorial En
Ejb3 Struts Tutorial EnEjb3 Struts Tutorial En
Ejb3 Struts Tutorial EnAnkur Dongre
 
Drupal Best Practices
Drupal Best PracticesDrupal Best Practices
Drupal Best Practicesmanugoel2003
 
PHP OOP Lecture - 03.pptx
PHP OOP Lecture - 03.pptxPHP OOP Lecture - 03.pptx
PHP OOP Lecture - 03.pptxAtikur Rahman
 

Similar to Cool Object Building With PHP (20)

Oops in php
Oops in phpOops in php
Oops in php
 
Wade not in unknown waters. Part one.
Wade not in unknown waters. Part one.Wade not in unknown waters. Part one.
Wade not in unknown waters. Part one.
 
Oops concepts in php
Oops concepts in phpOops concepts in php
Oops concepts in php
 
Dependency injectionpreso
Dependency injectionpresoDependency injectionpreso
Dependency injectionpreso
 
Zend framework 03 - singleton factory data mapper caching logging
Zend framework 03 - singleton factory data mapper caching loggingZend framework 03 - singleton factory data mapper caching logging
Zend framework 03 - singleton factory data mapper caching logging
 
Data Migrations in the App Engine Datastore
Data Migrations in the App Engine DatastoreData Migrations in the App Engine Datastore
Data Migrations in the App Engine Datastore
 
oop_in_php_tutorial_for_killerphp.com
oop_in_php_tutorial_for_killerphp.comoop_in_php_tutorial_for_killerphp.com
oop_in_php_tutorial_for_killerphp.com
 
oop_in_php_tutorial_for_killerphp.com
oop_in_php_tutorial_for_killerphp.comoop_in_php_tutorial_for_killerphp.com
oop_in_php_tutorial_for_killerphp.com
 
Oop in php_tutorial_for_killerphp.com
Oop in php_tutorial_for_killerphp.comOop in php_tutorial_for_killerphp.com
Oop in php_tutorial_for_killerphp.com
 
Oop in php tutorial
Oop in php tutorialOop in php tutorial
Oop in php tutorial
 
Oops in PHP
Oops in PHPOops in PHP
Oops in PHP
 
Oop's in php
Oop's in php Oop's in php
Oop's in php
 
Dependency injection in Drupal 8
Dependency injection in Drupal 8Dependency injection in Drupal 8
Dependency injection in Drupal 8
 
Intro to Rails 4
Intro to Rails 4Intro to Rails 4
Intro to Rails 4
 
This upload requires better support for ODP format
This upload requires better support for ODP formatThis upload requires better support for ODP format
This upload requires better support for ODP format
 
Ejb3 Struts Tutorial En
Ejb3 Struts Tutorial EnEjb3 Struts Tutorial En
Ejb3 Struts Tutorial En
 
Ejb3 Struts Tutorial En
Ejb3 Struts Tutorial EnEjb3 Struts Tutorial En
Ejb3 Struts Tutorial En
 
Drupal Best Practices
Drupal Best PracticesDrupal Best Practices
Drupal Best Practices
 
PHP OOP Lecture - 03.pptx
PHP OOP Lecture - 03.pptxPHP OOP Lecture - 03.pptx
PHP OOP Lecture - 03.pptx
 
Dependency Injection
Dependency InjectionDependency Injection
Dependency Injection
 

More from wensheng wei

你会柔软地想起这个校园
你会柔软地想起这个校园你会柔软地想起这个校园
你会柔软地想起这个校园wensheng wei
 
几米语录(1)
几米语录(1)几米语录(1)
几米语录(1)wensheng wei
 
Installation of Subversion on Ubuntu,...
Installation of Subversion on Ubuntu,...Installation of Subversion on Ubuntu,...
Installation of Subversion on Ubuntu,...wensheng wei
 
高级PHP应用程序漏洞审核技术
高级PHP应用程序漏洞审核技术高级PHP应用程序漏洞审核技术
高级PHP应用程序漏洞审核技术wensheng wei
 
存储过程编写经验和优化措施
存储过程编写经验和优化措施存储过程编写经验和优化措施
存储过程编写经验和优化措施wensheng wei
 
Happiness is a Journey
Happiness is a JourneyHappiness is a Journey
Happiness is a Journeywensheng wei
 
Linux Shortcuts and Commands:
Linux Shortcuts and Commands:Linux Shortcuts and Commands:
Linux Shortcuts and Commands:wensheng wei
 
Linux Security Quick Reference Guide
Linux Security Quick Reference GuideLinux Security Quick Reference Guide
Linux Security Quick Reference Guidewensheng wei
 
Android模拟器SD Card映像文件使用方法
Android模拟器SD Card映像文件使用方法Android模拟器SD Card映像文件使用方法
Android模拟器SD Card映像文件使用方法wensheng wei
 
如何硬盘安装ubuntu8.10
如何硬盘安装ubuntu8.10如何硬盘安装ubuntu8.10
如何硬盘安装ubuntu8.10wensheng wei
 
数据库设计方法、规范与技巧
数据库设计方法、规范与技巧数据库设计方法、规范与技巧
数据库设计方法、规范与技巧wensheng wei
 
mysql的字符串函数
mysql的字符串函数mysql的字符串函数
mysql的字符串函数wensheng wei
 
入门-Java运行环境变量的图文教程
入门-Java运行环境变量的图文教程入门-Java运行环境变量的图文教程
入门-Java运行环境变量的图文教程wensheng wei
 
LINUX Admin Quick Reference
LINUX Admin Quick ReferenceLINUX Admin Quick Reference
LINUX Admin Quick Referencewensheng wei
 
上海实习有感
上海实习有感上海实习有感
上海实习有感wensheng wei
 
100 Essential Web Development Tools
100 Essential Web Development Tools100 Essential Web Development Tools
100 Essential Web Development Toolswensheng wei
 

More from wensheng wei (20)

你会柔软地想起这个校园
你会柔软地想起这个校园你会柔软地想起这个校园
你会柔软地想起这个校园
 
几米语录(1)
几米语录(1)几米语录(1)
几米语录(1)
 
我的简历
我的简历我的简历
我的简历
 
Installation of Subversion on Ubuntu,...
Installation of Subversion on Ubuntu,...Installation of Subversion on Ubuntu,...
Installation of Subversion on Ubuntu,...
 
高级PHP应用程序漏洞审核技术
高级PHP应用程序漏洞审核技术高级PHP应用程序漏洞审核技术
高级PHP应用程序漏洞审核技术
 
存储过程编写经验和优化措施
存储过程编写经验和优化措施存储过程编写经验和优化措施
存储过程编写经验和优化措施
 
Happiness is a Journey
Happiness is a JourneyHappiness is a Journey
Happiness is a Journey
 
Linux Shortcuts and Commands:
Linux Shortcuts and Commands:Linux Shortcuts and Commands:
Linux Shortcuts and Commands:
 
Linux Security Quick Reference Guide
Linux Security Quick Reference GuideLinux Security Quick Reference Guide
Linux Security Quick Reference Guide
 
Android模拟器SD Card映像文件使用方法
Android模拟器SD Card映像文件使用方法Android模拟器SD Card映像文件使用方法
Android模拟器SD Card映像文件使用方法
 
Subversion FAQ
Subversion FAQSubversion FAQ
Subversion FAQ
 
如何硬盘安装ubuntu8.10
如何硬盘安装ubuntu8.10如何硬盘安装ubuntu8.10
如何硬盘安装ubuntu8.10
 
ubunturef
ubunturefubunturef
ubunturef
 
数据库设计方法、规范与技巧
数据库设计方法、规范与技巧数据库设计方法、规范与技巧
数据库设计方法、规范与技巧
 
mysql的字符串函数
mysql的字符串函数mysql的字符串函数
mysql的字符串函数
 
入门-Java运行环境变量的图文教程
入门-Java运行环境变量的图文教程入门-Java运行环境变量的图文教程
入门-Java运行环境变量的图文教程
 
Java学习路径
Java学习路径Java学习路径
Java学习路径
 
LINUX Admin Quick Reference
LINUX Admin Quick ReferenceLINUX Admin Quick Reference
LINUX Admin Quick Reference
 
上海实习有感
上海实习有感上海实习有感
上海实习有感
 
100 Essential Web Development Tools
100 Essential Web Development Tools100 Essential Web Development Tools
100 Essential Web Development Tools
 

Recently uploaded

A Framework for Development in the AI Age
A Framework for Development in the AI AgeA Framework for Development in the AI Age
A Framework for Development in the AI AgeCprime
 
Why device, WIFI, and ISP insights are crucial to supporting remote Microsoft...
Why device, WIFI, and ISP insights are crucial to supporting remote Microsoft...Why device, WIFI, and ISP insights are crucial to supporting remote Microsoft...
Why device, WIFI, and ISP insights are crucial to supporting remote Microsoft...panagenda
 
Take control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test SuiteTake control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test SuiteDianaGray10
 
Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24
Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24
Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24Mark Goldstein
 
What is DBT - The Ultimate Data Build Tool.pdf
What is DBT - The Ultimate Data Build Tool.pdfWhat is DBT - The Ultimate Data Build Tool.pdf
What is DBT - The Ultimate Data Build Tool.pdfMounikaPolabathina
 
Decarbonising Buildings: Making a net-zero built environment a reality
Decarbonising Buildings: Making a net-zero built environment a realityDecarbonising Buildings: Making a net-zero built environment a reality
Decarbonising Buildings: Making a net-zero built environment a realityIES VE
 
Assure Ecommerce and Retail Operations Uptime with ThousandEyes
Assure Ecommerce and Retail Operations Uptime with ThousandEyesAssure Ecommerce and Retail Operations Uptime with ThousandEyes
Assure Ecommerce and Retail Operations Uptime with ThousandEyesThousandEyes
 
Potential of AI (Generative AI) in Business: Learnings and Insights
Potential of AI (Generative AI) in Business: Learnings and InsightsPotential of AI (Generative AI) in Business: Learnings and Insights
Potential of AI (Generative AI) in Business: Learnings and InsightsRavi Sanghani
 
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptx
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptxPasskey Providers and Enabling Portability: FIDO Paris Seminar.pptx
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptxLoriGlavin3
 
Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...
Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...
Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...Alkin Tezuysal
 
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptxThe Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptxLoriGlavin3
 
How to write a Business Continuity Plan
How to write a Business Continuity PlanHow to write a Business Continuity Plan
How to write a Business Continuity PlanDatabarracks
 
Data governance with Unity Catalog Presentation
Data governance with Unity Catalog PresentationData governance with Unity Catalog Presentation
Data governance with Unity Catalog PresentationKnoldus Inc.
 
[Webinar] SpiraTest - Setting New Standards in Quality Assurance
[Webinar] SpiraTest - Setting New Standards in Quality Assurance[Webinar] SpiraTest - Setting New Standards in Quality Assurance
[Webinar] SpiraTest - Setting New Standards in Quality AssuranceInflectra
 
TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024Lonnie McRorey
 
Generative Artificial Intelligence: How generative AI works.pdf
Generative Artificial Intelligence: How generative AI works.pdfGenerative Artificial Intelligence: How generative AI works.pdf
Generative Artificial Intelligence: How generative AI works.pdfIngrid Airi González
 
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024BookNet Canada
 
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptxUse of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptxLoriGlavin3
 
From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .Alan Dix
 
Genislab builds better products and faster go-to-market with Lean project man...
Genislab builds better products and faster go-to-market with Lean project man...Genislab builds better products and faster go-to-market with Lean project man...
Genislab builds better products and faster go-to-market with Lean project man...Farhan Tariq
 

Recently uploaded (20)

A Framework for Development in the AI Age
A Framework for Development in the AI AgeA Framework for Development in the AI Age
A Framework for Development in the AI Age
 
Why device, WIFI, and ISP insights are crucial to supporting remote Microsoft...
Why device, WIFI, and ISP insights are crucial to supporting remote Microsoft...Why device, WIFI, and ISP insights are crucial to supporting remote Microsoft...
Why device, WIFI, and ISP insights are crucial to supporting remote Microsoft...
 
Take control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test SuiteTake control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test Suite
 
Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24
Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24
Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24
 
What is DBT - The Ultimate Data Build Tool.pdf
What is DBT - The Ultimate Data Build Tool.pdfWhat is DBT - The Ultimate Data Build Tool.pdf
What is DBT - The Ultimate Data Build Tool.pdf
 
Decarbonising Buildings: Making a net-zero built environment a reality
Decarbonising Buildings: Making a net-zero built environment a realityDecarbonising Buildings: Making a net-zero built environment a reality
Decarbonising Buildings: Making a net-zero built environment a reality
 
Assure Ecommerce and Retail Operations Uptime with ThousandEyes
Assure Ecommerce and Retail Operations Uptime with ThousandEyesAssure Ecommerce and Retail Operations Uptime with ThousandEyes
Assure Ecommerce and Retail Operations Uptime with ThousandEyes
 
Potential of AI (Generative AI) in Business: Learnings and Insights
Potential of AI (Generative AI) in Business: Learnings and InsightsPotential of AI (Generative AI) in Business: Learnings and Insights
Potential of AI (Generative AI) in Business: Learnings and Insights
 
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptx
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptxPasskey Providers and Enabling Portability: FIDO Paris Seminar.pptx
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptx
 
Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...
Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...
Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...
 
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptxThe Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
 
How to write a Business Continuity Plan
How to write a Business Continuity PlanHow to write a Business Continuity Plan
How to write a Business Continuity Plan
 
Data governance with Unity Catalog Presentation
Data governance with Unity Catalog PresentationData governance with Unity Catalog Presentation
Data governance with Unity Catalog Presentation
 
[Webinar] SpiraTest - Setting New Standards in Quality Assurance
[Webinar] SpiraTest - Setting New Standards in Quality Assurance[Webinar] SpiraTest - Setting New Standards in Quality Assurance
[Webinar] SpiraTest - Setting New Standards in Quality Assurance
 
TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024
 
Generative Artificial Intelligence: How generative AI works.pdf
Generative Artificial Intelligence: How generative AI works.pdfGenerative Artificial Intelligence: How generative AI works.pdf
Generative Artificial Intelligence: How generative AI works.pdf
 
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
 
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptxUse of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
 
From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .
 
Genislab builds better products and faster go-to-market with Lean project man...
Genislab builds better products and faster go-to-market with Lean project man...Genislab builds better products and faster go-to-market with Lean project man...
Genislab builds better products and faster go-to-market with Lean project man...
 

Cool Object Building With PHP

  • 1. Cool Object Building With PHP February 24, 2009 at 1:16 am At work I write mostly PHP code and work among some very respected developers in the PHP community. One thing that bothers me about the PHP world is how most people think in terms of arrays instead of in terms of objects. This is understandable considering Object OrientedPHP didn't really come around until PHP 5 so using arrays is probably an old habit that is hard to get rid of, but that is no excuse. Arrays have their uses, but I think more often than not an object can be used instead. One of the core problems most PHP developers run into is finding a way to map records in the database to PHP objects. This is understandable considering your database model is often very different from your object model, and at the moment PHP does not offer any great solutions that I know of. Basically my proposal involves two parts: 1. a DAO (data access object) class 2. a Builder class What these classes do is very simple: The DAO contains the SQL to query the database and then calls a builder to take the resulting array and assemble an object (or a collection of objects) out of it which is then returned. This implementation allows for no question about what is being returned and it forces you to use more objects in your code which is never a bad thing. Another plus is that you can cache the collections directly in memcache and therefore when you hit cache your PHP doesn't have to do any work at all with the data. This is actually the method I am using on this site so I will demonstrate using real world examples, but before I do so I want to point out that much of the awesomeness in the example relies on a certain naming pattern for your classes. For example I have classes named Blog_Dao, Blog_Comment, Blog_Builder, etc. The first code I am going to show you is the base DAO class I am using: 1 <?php 2 class Dao 3 { 4 /** 5 * @var Db 6 */ 7 protected $_db; 8 9 /** 10 * @var Builder 11 */ 12 protected $_builder; 13 14 /** 15 * constructor 16 * 17 * sets the database class this dao should use 18 * 19 * @return void 20 */ 21 function __construct() 22 { 23 $this->_db = new Db(); 24 } 25 26 /** 27 * determines what builder class to use 28 * 29 * @param string $builder 30 * @return Builder 31 */ 32 protected function _getBuilder($builderName) 33 { 34 // if we have already instantiated a builder class 35 if (!is_null($this->_builder)) { 36 return $this->_builder; 37 } 38 39 // if we have not passed in a specific builder to use 40 if (is_null($builderName)) { 41 $builderName = str_replace('_Dao', '_Builder', get_class($this)); 42 } 43 44 // make sure the builder exists 45 if (!class_exists($builderName)) { 46 throw new Exception($builderName . ' does not exist!'); 47 } 48 49 // instantiate the builder 50 $this->_builder = new $builderName; 51 52 return $this->_builder; 53 } 54 55 /** 56 * calls the builder to build a collection of the stuff
  • 2. returned from the 57 * dao! 58 * 59 * @param mixed $records 60 * @param string $builder name of class to use for building 61 * @return Collection 62 */ 63 protected function _buildCollection($records, $builder = null) 64 { 65 // if the database doesn't have any records 66 if ($records === false) { 67 return false; 68 } 69 70 $collection = new Collection(); 71 foreach ($records as $record) { 72 $collection->append($this->_buildOne($record, $builder)); 73 } 74 return $collection; 75 } 76 77 /** 78 * calls the builder and builds a single object 79 * 80 * @param mixed 81 * @param string $builder 82 * @return Object 83 */ 84 protected function _buildOne($record, $builder = null) 85 { 86 // if the database doesn't have any record 87 if ($record === false) { 88 return false; 89 } 90 91 $builder = $this->_getBuilder($builder); 92 return $builder->assemble($record); 93 } 94 } 95 The first thing you will probably notice is that $builder is optional! This means you only need to pass in a builder class if the builder is in some wacky place it shouldn't be. So the Blog_Comment_Dao class will default to the Blog_Comment_Builder which makes sense and it forces good use of objects cause it means everything you create a dao for is an object and that DAO should only return things related to that object. Another point of note is the Collection object. This is simply a child of ArrayObject to allow easier access to ArrayObject methods. Anyway now it is time to see this in action! Here is actual code from this site to get all comments related to a given blog post taken from the Blog_Comment_Dao which extends the base Dao class: 39 /** 40 * retrieves all comments for a given blog 41 * 42 * @param int $blogId 43 * @return Collection 44 */ 45 public function get($blogId) 46 { 47 $query = '/* ' . __METHOD__ . ' */' . 48 "SELECT bc.id id, 49 bc.name name, 50 bc.website website, 51 bc.email email, 52 bc.body body, 53 bc.posted_on posted_on 54 FROM blog_comment bc 55 WHERE bc.blog_id = :blog_id"; 56 57 $sth = $this->_db->prepare($query); 58 $sth->bindValue(':blog_id', $blogId); 59 $sth- >execute(); 60 $records = $sth->fetchAllAssoc(); 61 62 return $this->_buildCollection($records); 63 } Look how pretty that is! Now let's take a look at the Blog_Comment_Builder class to see how simple that is as well: 1 <?php 2 class Blog_Comment_Builder 3 { 4 /** 5 * creates a comment object from database record 6 * 7 * @param array 8 * @return Blog_Comment 9 */ 10 public function assemble(array $record) 11 { 12 $comment = new Blog_Comment(); 13 $comment->name = $record['name']; 14 $comment->website = $record['website']; 15 $comment->email = $record['email']; 16 $comment->body = $record['body']; 17 $comment->postedOn = new Date($record['posted_on']); 18 return $comment; 19 } 20 } 21 Something to note here is that these are not public properties. They are all protected, but each domain object extends a Domain_Object class that has magic __set() and __get() methods so you don't have to write setters and getters for every single property in every single class! For more on that check out this post by Matthew Purdon. You can see that properties of objects can still be other objects such as the Date class here. In the case where you are showing a bunch of Users on your site and
  • 3. each one has a bunch of other classes associated it with it you probably wouldn't want to use the other class's builders because then you end up running queries in loops which is never a good thing. Instead you can handle that logic in the User_Builder cause at the end of the day even if there are other classes involved the Builder is just returning one object from one database record. An obvious downfall here, of course, is that every object needs to have its own Builder class even though the builder seems like something that could happen automatically if there was better ORM support in PHP or any for that matter. This is something that PHP developers are used to, however, because no matter what framework you use, you still end up having to write tons of code to do even simple operations. Hopefully this will make your life easier.