algoritma optimizasyonu: PHP tek bir SQL deyiminden nesnesi ve alt nesneleri dönen

1 Cevap php

Ben bir nesne yönelimli PHP uygulama var. Ben bir SQL tablosu (Bölümler ve bölüm atanabilir Yazarlar) saklanan basit bir hiyerarşi var.

Ben satırlar aynı bölüme ait olan sergiyi ve Bölüm nesneleri ve Yazar nesnelerin dizileri hem oluşturarak, sonucu ile bir tek sorgu ve sonra döngüde bölümleri ve yazarları almak için aşağıdaki yöntemi yazdı.

Bu çok kıvrımlara yapılabilir gibi Ancak, ben hissediyorum. Birisi yardım edebilir mi?

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 yöntemleri basit SQL satır verilen Bölüm veya Yazar nesne oluşturmak. Gerekirse, ben burada bu yöntemleri gönderebilirsiniz.

EDIT: i bölümüne bir seferde Eşyaları bir yazar ekleme olamaz. Çünkü Bölüm nesne yapılandırılmıştır yolu hepsini bir kerede eklemek gerekir.

1 Cevap

Ben hedefi bu basit ve anlamayı kolaylaştırmak için sanırım. Nasıl bu pseudocode böyle bir şey? :

execute query
chapters = array()
for each result:
    chapter = result['chapter']
    author = result['author']
    if (!isset(chapters[chapter]))
        chapters[chapter] = new Chapter
    chapters[chapter].authors.append(author)

Aksine her bölüm için baştan başlamak, sonra, bir yazarlar dizi oluşturma doldurmamak, onu saklamak yerine, biz (muhtemelen biraz daha yavaş olsa) kodu daha okunabilir ve daha kısa yapabilirsiniz. Kısacası, her sonuç için, bu bölüm bölümler dizide olup olmadığını görmek için bakar. Değilse, onu yaratır. Sonra bölüme yazar ekler.