# 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