Solar Models vs. Zend Framework Models

By | January 7, 2010

Today, Michelangelo van Dam posted this narrative relating his experience with Zend Framework models:

http://www.dragonbe.com/2010/01/zend-framework-data-models.html

I read the article, and wondered how hard it would be to replicate his narrative using the Solar Framework model system. Turns out it’s pretty easy: there’s a lot of work that Solar does for you.

  1. Download a Solar system, move it to your localhost directory and make sure that the tmp and sqlite directories are accessible to the web server.

    $ wget http://svn.solarphp.com/system/download/solar-system-1.0.0beta2.tgz
    $ tar -zxf solar-system-1.0.0beta2.tgz
    $ cp -r solar/* /var/www/htdocs # or your localhost directory
    $ cd /var/www/htdocs         # or your localhost directory
    $ chmod -R 777 tmp sqlite
    
  2. Create tables and data in sqlite/example.sq3. There are two changes from Michelangelo’s code: the table names are plural, and rename the column type_id to address_type_id. (These are easy enough to change in the model class definitions, but I’d like to minimize the amount of customization for this example.)

    CREATE TABLE "users" (
        "id" integer primary key autoincrement,
        "username" varchar(255) not null,
        "password" varchar(255) not null
    );
    
    
    CREATE TABLE "contacts" (
        "id" integer primary key autoincrement,
        "user_id" integer not null,
        "email" varchar(255) not null,
        "phone" varchar(255) null,
        "fax" varchar(255) null
    );
    
    
    CREATE TABLE "addresses" (
        "id" integer primary key autoincrement,
        "address_type_id" integer not null default 1,
        "user_id" integer not null,
        "address1" varchar(255) not null,
        "address2" varchar(255) null,
        "city" varchar(255) not null,
        "state" varchar(255) null,
        "zip" varchar(255) not null,
        "country" varchar(255) not null
    );
    
    
    CREATE TABLE "address_types" (
        "id" integer primary key autoincrement,
        "type" varchar(255) not null
    );
    
    
    -- Data for users table --
    INSERT INTO "users"
        VALUES (1, 'testuser1', 'test123');
    INSERT INTO "users"
        VALUES (2, 'testuser2', 'test234');
    
    
    -- Data for contacts table --
    INSERT INTO "contacts"
        VALUES (1, 1, 'test1@example.com', '1-800-555-1234', '1-800-555-1230');
    INSERT INTO "contacts"
        VALUES (2, 2, 'test2@example.com', '1-800-555-2234', '1-800-555-2230');
    
    
    -- Data for addresses table --
    INSERT INTO "addresses"
        VALUES (1, 1, 1, '1 Test Home', '', 'Testtown', 'ZF', '1234', 'PHP');
    INSERT INTO "addresses"
        VALUES (2, 1, 2, '2 Test Home', '', 'Testtown', 'ZF', '1234', 'PHP');
    INSERT INTO "addresses"
        VALUES (3, 2, 2, 'Test Corp, LTD', '4 Test Ave', 'Testtown', 'ZF', '1234', 'PHP');
    
    
    -- Data for address_types table --
    INSERT INTO "address_types"
        VALUES (1, 'Home address');
    INSERT INTO "address_types"
        VALUES (2, 'Billing address');
    
  3. Make sure the SQLite database is accessible to the web server.

    $ chmod 777 sqlite/example.sq3
    
  4. Make a vendor space for the controllers, models, suppory libraries, etc. For this example the vendor will be named Example.

    $ ./script/solar make-vendor Example
    
  5. Edit the system configuration in config.php. Change the front-controller class prefixes and model catalog class prefixes, and tell the SQLite adapter which file name to use.

    // front controller
    $config['Solar_Controller_Front'] = array(
        'classes' = array('Example_App'),
        // ... the rest of the front-controller array ...
    );
    
    
    // model catalog
    $config['Solar_Sql_Model_Catalog']['classes'] = 'Example_Model';
    
    
    // add sqlite config
    $config['Solar_Sql_Adapter_Sqlite'] = array(
        'name' => "$system/sqlite/example.sq3",
    );
    
  6. Make the model classes. Note that this avoids a ton of effort that Zend Framework requires: Michelangelo had to hand-create table, model, and mapper classes for each of the following single-line commands.

    $ ./script/solar make-model Example_Model_Users
    $ ./script/solar make-model Example_Model_Contacts
    $ ./script/solar make-model Example_Model_Addresses
    $ ./script/solar make-model Example_Model_AddressTypes
    
  7. Edit the model classes to express what the related models are:

    /** source/example/Example/Model/Users.php */
    protected function _setup()
    {
        // chain to parent
        parent::_setup();
    
    
        // relateds
        $this->_hasOne('contact');
        $this->_hasMany('addresses');
    }
    
    
    /** source/example/Example/Model/Contacts.php */
    protected function _setup()
    {
        // chain to parent
        parent::_setup();
    
    
        // relateds
        $this->_belongsTo('user');
    }
    
    
    /** source/example/Example/Model/AddressTypes.php */
    protected function _setup()
    {
        // chain to parent
        parent::_setup();
    
    
        // relateds
        $this->_hasMany('addresses');
    }
    
    
    /** source/example/Example/Model/Addresses.php */
    protected function _setup()
    {
        // chain to parent
        parent::_setup();
    
    
        // relateds
        $this->_belongsTo('address_type');
        $this->_belongsTo('user');
    }
    
    
  8. Make a skeleton app (i.e., a controller with its associated actions and views):

    $ ./script/solar make-app Example_App_Accounts
    
  9. Edit the controller action to fetch user account data:

    /** source/example/Example/App/Accounts.php */
    public $list;
    public function actionIndex()
    {
        // get a model catalog
        $model = Solar_Registry::get('model_catalog');
    
    
        // populate $this->list with all users.
        // eager-fetch the contact record and addresses collection.
        $this->list = $model->users->fetchAll(array(
            'eager' => array(
                'contact',
                'addresses',
            ),
        ));
    }
    
  10. Edit the view for the index action. This could be a view and a partial, but let’s keep it straightforward for now.

    /** source/example/Example/App/Accounts/View/index.php */
    <table>
        <tr>
            <th>Username</th>
            <th>E-Mail</th>
            <th>Phone</th>
            <th>Fax</th>
            <th># addresses</th>
        </tr>
    
    
        <?php foreach ($this->list as $user): ?>
    
    
        <tr>
            <td><?php echo $this->escape($user->username); ?></td>
            <td><?php echo $this->escape($user->contact->email); ?></td>
            <td><?php echo $this->escape($user->contact->phone); ?></td>
            <td><?php echo $this->escape($user->contact->fax); ?></td>
            <td><?php echo count($user->addresses); ?></td>
        </tr>
    
    
        <?php endforeach; ?>
    
    
    </table>
    
    

You’re done. Browse to http://localhost/index.php/accounts/index to see the results of your handiwork.

Total elapsed time from when I read Michelangelo’s article to come up with the Solar conversion and write this article: under two hours.

Solar makes model creation and interaction very easy and very powerful. Maybe your next project should use Solar instead of Zend Framework?

13 thoughts on “Solar Models vs. Zend Framework Models

  1. Michelangelo van Dam

    Hey Paul,

    Wow, very impressive article, especially the fact that you managed to pull it off in less then 2 hours.

    But you’ve probably given me a nice incentive I could use to improve my own code, but I’m sure going to check out Solar.

    Anyways, thank you for referring to article and using my example to make an excellent point. But do mind me saying that my code is written as a source for improvement and not to be considered as a quality standard.

    I’ll let you (and the world) know about my own experiences with Solar, maybe you’ve got me as a new user :-D

    Reply
  2. Pingback: Solar Models vs. Zend Framework Models -HackIX

  3. Ray Kolbe

    Michelangelo,

    I can say that Solar models are much easier to work with than Zend’s. A big part of that is because all the hard work is done for you in Solar.

    I have been working with Solar and Zend for sometime and wish that Zend had more of the Solar convention.

    –Ray

    P.S. I need to get back to working on my blog entries hehe.

    Reply
  4. Bryan

    But none of these compare to using Doctrine with Zend. I’m using Doctrine 1.2 with ZF 1.9 right now on production projects and experimenting with Doctrine 2.0 with the others.

    If you really want easy to create models, go with Doctrine. I’m building my base model classes by hand and not YAML because I want more control but the way Doctrine handles building the schema in the backend is great not only for development but testing as well.

    Reply
  5. pmjones Post author

    Bryan — I’d be interested to see a step-by-step translation of the example from Michelangelo for Doctrine + Zend so we can have a good comparison of the work involved.

    Reply
  6. Michelangelo van Dam

    @pmjones, @bryan,

    I’d like the idea since I’ve heard so much about Doctrine with Zend Framework and I too would like to see it based on my example to have a good comparison and most importantly a good understanding on how it all relates to each other.

    I’m looking forward to see some articles about this concept and I will in my turn investigate both tracks: Solar and ZF + Doctrine.

    Reply
  7. Pingback: abcphp.com

  8. pmjones Post author

    Hi Michelangelo,

    Re: “my code is written as a source for improvement and not to be considered as a quality standard” — yeah, that makes sense, and I took it as such. :-) Even so, all the ZF model code that I see tends to look like that; e.g., the Zend quick-start guide does mostly the same thing (models, mappers, etc).

    Your (Michelangelo’s) article was of particular interest to me because it includes relationship data, and because you do such a good job of narrating your experience and showing the results (with full code download, no less). I thought it was a good example of what a real ZF codebase looks like when you begin to do non-trivial modelling. So, thanks for having written it in the first place. :-)

    Reply
  9. Pingback: Paul Jones’ Blog: Solar Models vs. Zend Framework Models | Webs Developer

  10. Pingback: Paul M. Jones » Blog Archive » Solar Models vs. Zend Framework Models | Future of Solar Panels

  11. Pingback: Zend Framework Blog » Blog Archive » Aus den Zend Framework Blogs

Leave a Reply

Your email address will not be published. Required fields are marked *