Neil J.
Passions: Musique (rock et surtout Métal)Informatique
Vampires
Graphisme
Photographie
Sports: Basket Ball
Volley Ball
Badminton
Blog:
findBy{$Field} with Zend_Db_Table
A quick post to show how one can easily implement a findByField wrapper in Zend_Db_Table :
/**
* Implements a simple findByField wrapper
*/
public function __call ( $method , $args ) {
if ( preg_match ( '/^findBy([a-zA-Z0-9]+)$/' , $method , $parts ) ) {
$field = strtolower ( preg_replace ( '/([a-z])([A-Z])/' , '$1_$2' , $parts [ 1 ] ) ) ;
if ( ! in_array ( $field , $this ->_cols ) ) {
throw new Zend_Db_Table_Exception ( sprintf ( ' \' %s \' field not in row' , $field ) ) ;
} else {
$db = $this -> getAdapter ( ) ;
$where = $db -> quoteInto ( $db -> quoteIdentifier ( $field ) . ' = ?' , $args [ 0 ] ) ;
return $this -> fetchAll ( $where ) ;
}
}
}
What it does is basically trapping any non-existant method call and check if the corresponding field exists, after converting CamelCasing to underscore_notation (eg: FooBar becomes foo_bar ).
Zend_Db_Table and tables relationships
When developping a database tied application, you eventually come to a point where you get (at least) two tables with a parent/child relationship, such as for example a User table referenced by, say, a Post table (each post belonging to a specific user). That's basically the point where you need Zend_Db_Table relationships mechanism . the drawback of this mechanism is that, as far as I know, it does not produce joined queries to retrieve the parent data, but fires a query for each parent row. Thus instead of just using Zend_Db Relationships, I developped a simple yet effective auto-join mechanism that I called, in great simplicity, parent mapping . It supports multiple joins from multiple tables, remote fields specification and prefixing.
It is included in my db table class and you can see the interesting part of the code below for your convenience (Ignore the 3 first lines of the function as it is used for something else in my version of the framework). /**
* Holds the parent mapping for join in fetchAll
*
*
* array(
* 'remote_table' => array(
* 'remote' => 'id'
* 'local' => 'remote_id',
* 'fields' => array('foo', 'bar', 'prefix' => 'remote_'),
* ),
* );
*
*
* @var array
*/
protected $_parentMap = array ( ) ;
/**
* Honors the parent mapping from self::_parentMap
*
* @param string|array $where
* @param string|array $order
* @param integer $count
* @param integer $offset
* @return Zend_Db_Table_Rowset
*/
public function fetchAll ( $where = null , $order = null , $count = null , $offset = null ) {
if ( ! is_array ( $this ->_cols ) ) {
return parent:: fetchAll ( $where , $order , $count , $offset ) ;
} else {
$db = $this -> getAdapter ( ) ;
$select = $db -> select ( ) ;
$select -> from ( $this ->_name, $this ->_cols, $this ->_schema )
-> order ( $order )
-> limit ( $offset , $count ) ;
if ( ! is_null ( $where ) ) {
$select -> where ( $where ) ;
}
if ( ! empty ( $this ->_parentMap ) ) {
foreach ( $this ->_parentMap as $parentTable => $specs ) {
$fields = array ( ) ;
if ( isset ( $specs [ 'fields' ] [ 'prefix' ] ) ) {
$prefix = $specs [ 'fields' ] [ 'prefix' ] ;
unset ( $specs [ 'fields' ] [ 'prefix' ] ) ;
foreach ( $specs [ 'fields' ] as $key => $field ) {
if ( is_int ( $key ) ) {
$key = $prefix . $field ;
}
$fields [ $key ] = $field ;
}
} else {
$fields = $specs [ 'fields' ] ;
}
$select -> join (
$parentTable ,
sprintf ( '%s.%s = %s.%s' ,
$db -> quoteIdentifier ( $this ->_name ) ,
$db -> quoteIdentifier ( $specs [ 'local' ] ) ,
$db -> quoteIdentifier ( $parentTable ) ,
$db -> quoteIdentifier ( $specs [ 'remote' ] )
) ,
$fields
) ;
}
}
$stmt = $db -> query ( $select ) ;
return $this ->_makeRowset ( $stmt ) ;
}
}
Stripping the logic: the Transfer Object
Sometimes you have to pass an object data to another object, or to another layer of your application (who said controller/view ?), while ensuring that the receiving entity will not be able to run business code encapsulated in your class. In the Zend Framework, several objects provide a toArray method, but that is not always sufficient as sometimes you'd like to keep with the $object->varname syntax.
That is where the Transfer Object arrives. While the preceding definition is not exact (that's not the real purpose of the Transfert Object in the J2EE spirit), This is the most common use that PHP Developers can make of it nowadays I think. So I came up with a very light implementation of a concept which I hope can prove useful for any folks getting by there.
See also:
Martin Fowler's Value Object and Data Transfer Object
The Transfert Object as a Core J2EE Pattern
Some bookmarks
- http://www.rashitoul.net
Site officiel du Jeu Battle For Rashitoul. - http://scribble.com/dghq/gothlyric/
toi aussi fonde un groupe de musique gothique et fais toi des paroles :) - http://www.eklipse-forumz.net/alsace/
Photos d'une cascade en Alsace - http://patate.ressource-toi.org/~rst2...
le geek test en français. - http://www.eklipse-forumz.net/dotnode...
photos de la dotparty du 6 novembre.
Some photos
et il a enlevé un peu le bas après :p |
l'objet de fantasmes et de discordes. |











