У меня есть объектно-ориентированное PHP-приложение. У меня есть простая иерархия, хранящаяся в таблице SQL (главы и авторы, которые могут быть назначены главе).
Я написал следующий метод для извлечения глав и авторов в одном запросе, а затем перебрал результат, выяснив, какие строки принадлежат одной и той же главе, и создав объекты и главы, и массивы объектов Author.
Однако я чувствую, что это можно сделать намного аккуратнее. Может кто-нибудь помочь?
function getChaptersWithAuthors($monographId, $rangeInfo = null) {
$result =& $this->retrieveRange(
'SELECT mc.chapter_id, mc.monograph_id, mc.chapter_seq, ma.author_id, ma.monograph_id, mca.primary_contact, mca.seq, ma.first_name, ma.middle_name, ma.last_name, ma.affiliation, ma.country, ma.email, ma.url
FROM monograph_chapters mc
LEFT JOIN monograph_chapter_authors mca ON mc.chapter_id = mca.chapter_id
LEFT JOIN monograph_authors ma ON ma.author_id = mca.author_id
WHERE mc.monograph_id = ?
ORDER BY mc.chapter_seq, mca.seq',
$monographId, $rangeInfo
);
$chapterAuthorDao =& DAORegistry::getDAO('ChapterAuthorDAO');
$chapters = array();
$authors = array();
while (!$result->EOF) {
$row = $result->GetRowAssoc(false);
// initialize $currentChapterId for the first row
if ( !isset($currentChapterId) ) $currentChapterId = $row['chapter_id'];
if ( $row['chapter_id'] != $currentChapterId) {
// we're on a new row. create a chapter from the previous one
$chapter =& $this->_returnFromRow($prevRow);
// set the authors with all the authors found so far
$chapter->setAuthors($authors);
// clear the authors array
unset($authors);
$authors = array();
// add the chapters to the returner
$chapters[$currentChapterId] =& $chapter;
// set the current id for this row
$currentChapterId = $row['chapter_id'];
}
// add every author to the authors array
if ( $row['author_id'] )
$authors[$row['author_id']] =& $chapterAuthorDao->_returnFromRow($row);
// keep a copy of the previous row for creating the chapter once we're on a new chapter row
$prevRow = $row;
$result->MoveNext();
if ( $result->EOF ) {
// The result set is at the end
$chapter =& $this->_returnFromRow($row);
// set the authors with all the authors found so far
$chapter->setAuthors($authors);
unset($authors);
// add the chapters to the returner
$chapters[$currentChapterId] =& $chapter;
}
}
$result->Close();
unset($result);
return $chapters;
}
PS: методы _returnFromRow просто создают объект Chapter или Author с учетом строки SQL. При необходимости я могу опубликовать эти методы здесь.
РЕДАКТИРОВАТЬ: я не могу добавлять элементы по одному автору за один раз в главу. Мне нужно добавить их все сразу из-за структуры объекта Chapter.