Skip to Content (c) Skip to Navigation (n) Skip to Search (s)

1.0-beta (rev 75) released!

xPDO is in beta. There are several API improvements, more code reductions and simplifications, and the introduction of SQLite and PostgreSQL driver support are coming very soon. xPDO is being used to develop the next-generation MODx CMF.

Forgotten credits...

I'd like to extend a special thanks to Andrea Giammarchi for his PDO for PHP 4 implementation that inspired me to begin coding this project. If not for PHPClasses.org and the inspiration I found in Andrea's work there, the OpenExpedio project would likely not exist, as I probably would have invested my time in working with PHPDoctrine.

Getting Started with xPDO

Ways to get started with xPDO...

Included in the current xPDO distribution are three classes in a sample package that implement the base class, xPDOObject, and provide metadata definition maps to define their persistent columns and relationships. The classes are Person, Phone, and PersonPhone, representing a simple one to many relationship between people and their various phone numbers and types of phone numbers.

The samples provide a great overview of what it takes to define a simple xPDOObject. But there are many ways to get started with xPDO, depending on what your goals are. Let's start by showing how easily you can hand-code a class that provides complete scaffolding for managing the persistence of that entity.

Defining your classes by hand

Creating a new xPDO class to represent a database table is very easy. In the simplest form, the only code you need to write is...

<?php
class xPDOSample extends xPDOObject {
    function xPDOSample(& $xpdo) {
        $this->__construct($xpdo);
    }
    function __construct(& $xpdo) {
        parent :: __construct($xpdo);
    }
}

Place this code in a file named xpdosample.class.php (xPDO 1.0 requires all lowercase file names to keep compatibility between PHP 4 and 5 a little smoother) in a directory accessible to your PHP application. Creating it in a XPDO_BASE_DIR/om/sample/ directory is a best practice for dealing with packages of related classes and making class loading easy.

Now we need to define the attributes of the object that will be persisted as table columns. To do this, we create a second file, called the map. In the same directory as the class file, create an xpdosample.map.php file, and enter php code that looks like this...

<?php
$xpdo_meta_map['xPDOSample']['table']= 'xpdosample';
$xpdo_meta_map['xPDOSample']['fields']= array (
    'parent' => null,
    'unique_varchar' => '',
    'varchar' => '',
    'text' => null,
    'timestamp' => null,
    'unix_timestamp' => 0,
    'date_time' => null,
    'date' => null,
    'enum' => '',
    'password' => '',
    'integer' => 1,
    'boolean' => 0,
);
$xpdo_meta_map['xPDOSample']['fieldMeta']= array (
    'parent' => array('dbtype' => 'INTEGER', 'phptype' => 'integer', 'null' => 'true', ),
    'unique_varchar' => array('dbtype' => 'VARCHAR', 'precision' => '255', 'phptype' => 'string', 'null' => 'false', 'index' => 'unique', ),
    'varchar' => array('dbtype' => 'VARCHAR', 'precision' => '100', 'phptype' => 'string', 'null' => 'false', ),
    'text' => array('dbtype' => 'TEXT', 'phptype' => 'string', 'null' => 'true', ),
    'timestamp' => array('dbtype' => 'TIMESTAMP', 'phptype' => 'timestamp' ),
    'unix_timestamp' => array('dbtype' => 'INTEGER', 'phptype' => 'timestamp' ),
    'date_time' => array('dbtype' => 'DATETIME', 'phptype' => 'datetime', ),
    'date' => array('dbtype' => 'DATE', 'phptype' => 'date', ),
    'enum' => array('dbtype' => 'ENUM', 'precision' => '\'\', \'T\',\'F\'', 'phptype' => 'string', 'null' => 'false', ),
    'password' => array('dbtype' => 'VARCHAR', 'precision' => '255', 'phptype' => 'password', 'null' => 'false', ),
    'integer' => array('dbtype' => 'INTEGER', 'phptype' => 'integer', 'null' => 'false', ),
    'boolean' => array('dbtype' => 'BINARY', 'phptype' => 'boolean', 'null' => 'false', ),
);
$xpdo_meta_map['xPDOSample']['aggregates']= array (
    'xPDOSample' => array(
        'children' => array('local' => 'id', 'foreign' => 'parent', 'cardinality' => 'many', ), 
        'parent' => array('local' => 'parent', 'foreign' => 'id', 'cardinality' => 'one', ), 
    ),
);
$xpdo_meta_map['xPDOSample']['composites']= array ();
$xpdo_meta_map['xpdosample']= & $xpdo_meta_map['xPDOSample'];

Forward engineering your classes

Reverse engineering an existing database