2013-01-05 20 views
0

我對我創建的OOP PHP代碼有些疑問。迄今爲止,用於檢索在線存儲的不同語言的標題和多個章節。但首先我會顯示代碼,因爲我的懷疑指的是這個。這是我目前正與類:一個方法檢索所有數據或幾個較小的方法檢索每個部分?

<?php 
// Requires PHP 5.4+ 
class Subject 
    { 
    private $DB; 
    private $Language; 
    private $Keyword; 

    public function __construct($DB, $Keyword, $Language) 
    { 
    $this->DB=$DB; 
    $this->Keyword=$Keyword; 
    $this->Language=$Language; 
    } 

    private function query($query, $arg) 
    { 
    $STH = $this->DB->prepare($query); 
    $STH->execute(array_merge((array)$this->Keyword, (array)$arg)); 
    return $STH->fetch()[$this->Language]; // PHP 5.4+ 
    } 

    public function retrieveTitle() 
    { 
    return $this->query("SELECT * FROM subject WHERE keyword = ? ORDER BY date DESC LIMIT 1"); 
    } 

    public function retrieveChapter ($arg) 
    { 
    return $this->query("SELECT * FROM chapters WHERE subject_keyword = ? AND type = ? ORDER BY date DESC LIMIT 1", $arg); 
    } 
?> 

然後我做一些類似的顯示頁面:

if (isset($_GET['a'])) 
    { 
    $Subject=new Subject($DB, $_GET['a'], $User->get('language')); 

    if ($Subject->retrieveTitle()) 
    { 
    echo '<h1 id="Title">'.$Subject->retrieveTitle().'</h1>'; 

    // Index 
    if ($Subject->retrieveTitle()) 
     // ... code for the index 

    // Introduction 
    if ($Subject->retrieveChapter('Introduction')) 
     echo '<h2 id="Introduction">' . $_('Introduction') . '</h2>' . $Subject->retrieveChapter('Introduction'); 

    // ... more non-relevant code. 
    } 
    } 
else 
    // ... whatever 

首先關注的。我不確定這是否是處理這類數據的正確方法。我嘗試將這些方法分開並儘可能小,並且不要重複太多的代碼。這是感覺正確的方式。但是我不明白爲什麼這個類似於前一個的代碼不太理想。注意:這個類有肯定一些拼寫錯誤,並沒有經過測試,它只是在這裏ilustrate的差別,所以請不要使用它(至少不是literaly):

<?php 
// Requires PHP 5.4+ 
class Subject 
    { 
    public $Title; 
    public $Chapters = array(); 

    public function __construct($DB, $Keyword, $Language) 
    { 
    // Retrieve all 
    $STH = $DB->prepare("SELECT * FROM subject WHERE keyword = ? ORDER BY date DESC LIMIT 1"); 
    $STH->execute(array($Keyword)); 
    $this->Title = $STH->fetch()[$Language]; // PHP 5.4+ 

    // Retrieve chapters 
    $ToForeach = ('Introduction','History','1'); 
    $STH = $DB->prepare("SELECT * FROM chapters WHERE subject_keyword = ? AND type = ? ORDER BY date DESC LIMIT 1"); 
    foreach ($ToForeach as $part) 
     { 
     $STH->execute(array($Keyword, $part)); 
     $this->Chapters = $STH->fetch()[$Language]; 
     } 
    } 
    } 
?> 

然後直接訪問屬性(或者甚至在中間構建一些get(),但你明白了)。

那麼,有什麼區別嗎?第一種方法與第二種方法對類的編碼有什麼好處和缺陷?內存使用情況在第一次時應該略小一些,但我認爲在這種情況下,與可讀性相比,這不會成爲一種破壞行爲。

編輯:只是寫問題的方式讓別人明白了使我認爲它在其他方面。第一種方式看起來更容易測試。

第二個問題。如果我想製作一些保存數據的方法,我應該把它放在同一個類中還是放在不同的類中?因爲如果我把它放在一個它捆綁所有主題相關的方法在一個漂亮的獨立類,如果我分開它,我有更多的具有分離角色的專業類。

任何進一步的建議,特別是有關編碼最佳實踐[我可能不會跟隨],也歡迎!

回答

1

這很難以很好的方式回答。所以我只能關注它的一些小部分。對於不重複的代碼,我說你給第一個例子中有相當一些重複的代碼:

class Subject 
{ 
    /** 
    * @var ParametrizedQueryFetchQueryFactory 
    */ 
    private $queryFactory; 

    public function __construct($DB, $Keyword, $Language) { 

     $this->queryFactory = new ParametrizedQueryFetchQueryFactory($DB, $Language, [$Keyword]); 
    } 

    private function query($query, array $args = array()) { 
     return $this->queryFactory->query($query, $args); 
    } 

    public function retrieveTitle() { 

     return $this->query("SELECT * FROM subject WHERE keyword = ? ORDER BY DATE DESC LIMIT 1"); 
    } 

    public function retrieveChapter($part) { 
     return $this->query(
      "SELECT * FROM chapters WHERE subject_keyword = ? AND TYPE = ? ORDER BY DATE DESC LIMIT 1", 
      [$part] 
     ); 
    } 
} 

class ParametrizedQueryFetchQueryFactory 
{ 
    private $db, $returnIndex, $defaultArgs; 

    public function __construct($db, $returnIndex, array $defaultArgs = array()) { 
     $this->db = $db; 
     $this->returnIndex = $returnIndex; 
     $this->defaultArgs = $defaultArgs; 
    } 

    public function query($query, array $args = array()) { 
     $fetcher = new ParametrizedQueryFetch($this->db,$query, $this->returnIndex, $this->defaultArgs); 
     return $fetcher->execute($args); 
    } 
} 

class ParametrizedQueryFetch 
{ 
    private $db, $query, $returnIndex, $defaultArgs; 
    public function __construct($db, $query, $returnIndex, array $defaultArgs = array()) { 
     $this->db = $db; 
     $this->query = $query; 
     $this->returnIndex = $returnIndex; 
     $this->defaultArgs = $defaultArgs; 
    } 

    public function execute(array $args) { 
     $args = array_merge($this->defaultArgs, $args); 
     $stmt = $this->db->prepare($this->query); 
     $stmt->excute($args); 
     return $stmt->fetch()[$this->returnIndex]; 
    } 
} 

而且順便說一句,讓這個PHP 5.3兼容的,你只需要在這裏改變單一的線。

+0

我編輯了我的原始代碼,以避免重複代碼。不過,我真的很驚訝你的代碼有多久,並且花了一段時間才明白它的工作原理。現在我知道了,但我不知道爲什麼。我真的很好奇你的代碼的好處,證明它的時間更長,所以它們是什麼?順便說一句,謝謝你的詳細解答! –

+0

如果您有幾千個這樣的參數化SQL查詢,您可以在您的shell代碼中執行這些查詢,並將代碼提供給數據庫中的數據,那麼添加一些可以處理該情況的工作是有意義的。像在類中運行這些參數化,部分預配置的查詢。就這樣。當然,對於兩個函數來說太冗長了,您也可以將代碼也放入''private function query()'中。這是第一步。 – hakre

相關問題