What is wrong with PHP

(written by lawrence krubner, however indented passages are often quotes). You can contact lawrence at: lawrence@krubner.com

I’m actually writing about what is wrong with imperative programming in general (compared with what you get from meta-programming). The issue is the verbose nature of the code. Consider: Jonathan Wage is a fantastic programmer, and Doctrine is one of the best open source projects in the whole of the PHP eco-system. So this is the best we can hope for:
The More with symfony book — Advanced Doctrine Usage.

If ceremony in code is bad, then consider how much ceremony there is here:

The Event Listener

The next step to building the behavior is to write a record event listener that will be responsible for keeping the count up to date when we insert new records, delete a record or batch DQL delete records:

class CountCache extends Doctrine_Template
{
// …

public function setTableDefinition()
{
// …

$this->addListener(new CountCacheListener($this->_options));
}
}

Before we go any further we need to define the CountCacheListener class that extends Doctrine_Record_Listener. It accepts an array of options that are simply forwarded to the listener from the template:

// lib/model/count_cache/CountCacheListener.class.php

class CountCacheListener extends Doctrine_Record_Listener
{
protected $_options;

public function __construct(array $options)
{
$this->_options = $options;
}
}

Now we must utilize the following events in order to keep our counts up to date:

postInsert(): Increments the count when a new object is inserted;

postDelete(): Decrements the count when a object is deleted;

preDqlDelete(): Decrements the counts when records are deleted through a DQL delete.

First let’s define the postInsert() method:

class CountCacheListener extends Doctrine_Record_Listener
{
// …

public function postInsert(Doctrine_Event $event)
{
$invoker = $event->getInvoker();
foreach ($this->_options['relations'] as $relation => $options)
{
$table = Doctrine::getTable($options['className']);
$relation = $table->getRelation($options['foreignAlias']);

$table
->createQuery()
->update()
->set($options['columnName'], $options['columnName'].’ + 1′)
->where($relation['local'].’ = ?’, $invoker->$relation['foreign'])
->execute();
}
}
}

The above code will increment the counts by one for all the configured relationships by issuing a DQL UPDATE query when a new object like below is inserted:

$post = new Post();
$post->thread_id = 1;
$post->body = ‘body of the post’;
$post->save();

The Thread with an id of 1 will get the num_posts column incremented by 1.

Source