Да, речь идет именно об этой книге. Читать стоит, но только на английском (русский перевод ужасен) и после «Рефакторинга» Мартина Фаулера и «Test driven development» Кента Бека.
> Нет, тут дело не в том, что я не смог его залатать, а дело в том, что проект изначально был криво
> спроектирован, что впоследствии привело к очень плачевному результату. Очень много моментов таких
> как: мерцание, переполнение памяти, медленная работа и прочее. Попросту невозможно было убрать.
Это все на самом деле вполне решабельно (тесты и инкрементальный рефакторинг со строгим исполнением принципа «разделяй и властвуй»), просто нужно подойти с правильной стороны, тем более что вариант «все переписать» оказался успешным. И есть подозрение, что изначально вполне можно было уложиться в 4 месяца.
Если же говорить о конкретно вашем случае, с использованием только Table Gateway, то я бы делал так:
Пусть нам изначально ставят задачу вывести список юзеров. Нет ничего проще.
class Users extends Zend_Db_Table_Abstract
{
protected $_primary = 'id';
public function getAll()
{
return $this->fetchAll();
}
}
Казалось бы, ну что за идиотизм делать такую функцию, кому она нужна, если можно напрямую вызвать fetchAll???
Но тут начальство ставит нам задачу: выводить список юзеров + количество комментариев каждого юзера.
Все, что нам нужно, слегка модифицировать наш метод:
class User extends Zend_Db_Table_Row_Abstract
{
protected $_commentsCount = 0;
public function init()
{
parent::init();
if (array_key_exists('commentsCount', $this->_data)) {
$this->_commentsCount = (int)$this->_data['commentsCount'];
unset($this->_data['commentsCount']);
}
}
public function getCommentsCount()
{
return $this->_commentsCount;
}
}
class Users extends Zend_Db_Table_Abstract
{
protected $_primary = 'id';
protected $_rowClass = 'User';
public function getAll()
{
$select = $this->select()
->from(array('u' => 'Users'))
->joinLeft(array('c' => 'Comments'), 'c.user_id = u.id', array(
'commentsCount' => new Zend_Db_Expr('COUNT(c.*)')
))
->group('u.id');
return $this->fetchAll($select);
}
}
При таком решении никаких изменений в контроллере не потребуется.
Не нравятся join'ы??? Можно и без них, если правильно настроено кэширование:
class User extends Zend_Db_Table_Row_Abstract
{
protected $_commentsCount;
public function getCommentsCount()
{
if ($this->_commentsCount === null) {
/**
* @var Zend_Db_Table_Abstract $comments
*/
$comments = $this->getTable()->getReference('Comments');
$select = $comments->select()
->columns(array('commentsCount' => new Zend_Db_Expr('COUNT(*)')))
->where('user_id = ?', $this->id);
$row = $comments->fetchRow($select);
$this->_commentsCount = (int)$row->commentsCount;
}
return $this->_commentsCount;
}
}
class Users extends Zend_Db_Table_Abstract
{
protected $_primary = 'id';
protected $_rowClass = 'User';
public function getAll()
{
return $this->fetchAll();
}
}
Тема интересная и нужная, спасибо!
Вот бы еще для любителей бинарных протоколов и не-любителей изобретать их с нуля рассказать про protobuf, msgpack, bson и другие.
Не удержался от совета. Сам писал анализаторы в университете не раз, тоже делал сначала «в лоб». Но изучив предмет «Теория языков программирования и Методы трансляции» понял, что все это сложно и ненадежно. Достаточно просто грамотно нарисовать (на бумаге) граф конечного автомата и построить таблицу переходов по нему. А сама программа, реализующая переходы по таблице невероятно проста. Поэтому если все же соберетесь серьезно вернутся к вопросу, стоит поковырять методы трансляции: Конечные автоматы и регулярные выражения, и если совсем заморочиться — грамматики.
Да, у нас тоже с большими файлами проблемы были.
Из менее удобных, но шустрых, которые я использовал:
— пировский Spreadsheet_Excel_Writer
— phpexcelreader
> Нет, тут дело не в том, что я не смог его залатать, а дело в том, что проект изначально был криво
> спроектирован, что впоследствии привело к очень плачевному результату. Очень много моментов таких
> как: мерцание, переполнение памяти, медленная работа и прочее. Попросту невозможно было убрать.
Это все на самом деле вполне решабельно (тесты и инкрементальный рефакторинг со строгим исполнением принципа «разделяй и властвуй»), просто нужно подойти с правильной стороны, тем более что вариант «все переписать» оказался успешным. И есть подозрение, что изначально вполне можно было уложиться в 4 месяца.
weierophinney.net/matthew/archives/202-Model-Infrastructure.html
weierophinney.net/matthew/archives/201-Applying-ACLs-to-Models.html
weierophinney.net/matthew/archives/200-Using-Zend_Form-in-Your-Models.html
Если же говорить о конкретно вашем случае, с использованием только Table Gateway, то я бы делал так:
Пусть нам изначально ставят задачу вывести список юзеров. Нет ничего проще.
Казалось бы, ну что за идиотизм делать такую функцию, кому она нужна, если можно напрямую вызвать fetchAll???
Но тут начальство ставит нам задачу: выводить список юзеров + количество комментариев каждого юзера.
Все, что нам нужно, слегка модифицировать наш метод:
При таком решении никаких изменений в контроллере не потребуется.
Не нравятся join'ы??? Можно и без них, если правильно настроено кэширование:
Тащемта, кому интересно, есть неплохой ответ на статью: blog.ircmaxell.com/2012/04/php-sucks-but-i-like-it.html
Вот бы еще для любителей бинарных протоколов и не-любителей изобретать их с нуля рассказать про protobuf, msgpack, bson и другие.
Из менее удобных, но шустрых, которые я использовал:
— пировский Spreadsheet_Excel_Writer
— phpexcelreader
Есть много ключевых моментов, про которые никто даже не задумывается
Так что советую прочитать всем, учитывая что книжка на 150 листов) за пару вечеров можно без проблем прочесть
И пример в лоб