Blog entries on January 2006

  • ActiveRecord PHP implementation Part I

    By Nuno Mariz, on 6 January 2006 @ 18:09
    ActiveRecord UML
    This is the first part of an attempt to implement the ActiveRecord design pattern in PHP. This first implementation is very simple but will open doors for more advanced stuff, like foreign keys mapping(automatic or manually) or integration with Model, View and Controller components, in this case with the generation of PHP classes or objects. Approach: A row in a database table or view is wrapped into a class, thus an object instance is tied to a single row in the database. Imagine this table(person):
    +-------------+---------------------+
    | Field       | Type                |
    +-------------+---------------------+
    | id          | bigint(20) unsigned |
    | name        | varchar(100)        |
    | email       | varchar(150)        |
    | last_update | datetime            |
    +-------------+---------------------+
    
    With this records:
    +----+----------+---------------+---------------------+
    | id | name     | email         | last_update         |
    +----+----------+---------------+---------------------+
    |  1 | Nuno     | nuno@xxx.xxx  | 2005-11-06 20:39:08 |
    +----+----------+---------------+---------------------+
    |  2 | Marta    | marta@xxx.xxx | 2005-11-06 20:39:08 |
    +----+----------+---------------+---------------------+
    |  3 | Pedro    | joao@xxx.xxx  | 2005-11-06 20:39:08 |
    +----+----------+---------------+---------------------+
    
    You don't have to define any table structure, just extend de ActiveRecord class and call the parent __construct() method with the table name :
    include_once 'class.ActiveRecord.php';
    
    class Person extends ActiveRecord {
        public function __construct() {
            parent::__construct('person');
        }
    }
    
    To return all rows in the table:
    $persons = new Person();
    
    /**
     * This will print all records
     * $persons->findAll() will return a Recordset
     */
    foreach($persons->findAll() as $person) {
        echo 'id: '.$person->id;
        echo 'name: '.$person->name;
        echo 'email: '.$person->email;
        echo 'last update: '.$person->last_update;
    }
    
    /**
     * Alternatively you can 'walk' the Recordset
     * with next(), prev(), etc. because Recordset
     * implements the Iterator interface
     */
    
    Insert a record:
    $person = new Person();
    $person->name = 'Julia';
    $person->email = 'julia@xxx.xxx';
    $person->insert();
    
    Update a record:
    $personId = $_POST['id'];
    $person = new Person();
    $person->id = $personId;
    $person->name = 'Nuno Mariz';
    $person->update();
    
    UPDATE: With the Pádraic Brady tip for merging the insert() and update() methods to only one save() method, now is possible to:
    // insert
    $person = new Person();
    $person->name = 'Nuno Mariz';
    $person->save();
    
    // or update
    $personId = $_POST['id'];
    $person = new Person();
    $person->find($personId);
    $person->name = 'Nuno Mariz';
    $person->save();
    
    You can view the UML for the implementation. See you in part II...