2015-06-19 52 views
2

我很抱歉,如果這已經回答了某個地方,但我還沒有設法找到答案,目前爲止 - 也許我正在尋找錯誤的東西!PHP OO - 我應該如何處理多個類的軟錯誤?

我想弄清楚如何處理我的OO PHP系統中用於生成網頁的錯誤。希望這個例子能解釋我的意思。

想象一下,我有一個Content類,一個Form類和一個FormObject類,它們包含頁面內容,Web窗體和表單域的所有信息。所有類都可以通過DB類運行多個MySQL查詢。 用戶可以在後端創建新的內容或表單。當他們這樣做時,我使用這些類來創建數據並將其存儲在數據庫中。

我也有一個系統類,它用於生成網頁。 System類檢查應在前端顯示的內容,構建適當的Content和Form對象,然後生成HTML並將其輸出到屏幕。

我對嚴重錯誤進行了一些檢查,這些錯誤會阻止代碼進一步發送。但是,問題是我想反饋一些「軟錯誤」到前端。例如,也許System類構建一個Form對象,該對象依次使用FormObject類構建這些字段。 FormObject類查詢數據庫中的字段名稱,但未找到字段名稱。所以DB類返回一個錯誤。我希望能夠將消息反饋給前端,說明未找到字段名稱。

將「軟錯誤」消息返回到System類的最佳方式是什麼,以便它可以輸出到前端? 我知道這個例子相當簡單,但隨着更多的類被添加,並且關鍵的是,更多的級別被添加,問題變得更大。

我認爲這樣做的一種方法是創建一個Error類。系統會創建一個Error對象,並在創建時將它傳遞給每個Content和Form對象。 Form類將傳遞相同的Error對象到FormItem類。每當發現錯誤時,都會通過Error類中的方法進行記錄。然後系統可以訪問原始的Error對象並輸出所有錯誤。然而,隨着系統的增長,更多的類被添加,並且更多的對象被創建,它會變得相當混亂。有沒有更好的辦法?

+0

也許你可以拋出一個異常,然後添加[默認的異常處理(http://php.net/manual/en/function.set-exception-handler.php),將記錄錯誤或向瀏覽器顯示一些內容。 – Mike

+0

謝謝邁克。我不是特別想要輸出到發現錯誤的位置,因爲想法是生成HTML,然後一次輸出。例如,如果我回顯一個錯誤,它將出現在所有HTML之上。我想在HTML中的特定錯誤div中顯示所有軟錯誤。如果我記錄錯誤,我會在哪裏登錄?我可以將它存儲在全局變量中嗎? –

+0

當你需要顯示一小段代碼 – meda

回答

2

您可能需要爲使用

  1. 一些全球所有類都可以訪問(例如一個全局變量或單身),或
  2. 東西是在傳遞給classses的所有實例生產什麼你通話'軟錯誤'

收集此類錯誤。然後,您想使用您收集的任何內容,並以某種方式將其添加到System課程的輸出中。


更具體...

這是使用該解決方案的例子的全球:

global $softErrorMessages = array(); 

class A 
{ 
    function sampleFunctionA() 
    { 
    // [...] 
    // some code setting $result to some valid value 
    // or to false if an error occured 

    if($result === false) // check for validity 
    { 
     global $softErrorMessages; 
     $softErrorMessages[] = "The sample function A caused a soft error"; 
     return; 
    } 

    // [...] 
    // some code requiring a valid $result 
    } 
} 

如果使用這樣的全球性的,你可以很容易從訪問您的System課程,並將其內容放入輸出的正確位置。但是,如果您執行單元測試,則可能不想使用全局變量或類似全局的解決方案(如單例)。因此,這裏是一個爲一個「錯誤收集」的方法:

class ErrorCollector 
{ 
    private $errors = array(); 

    function addError($error) 
    { 
    $this->errors[] = $error; 
    } 

    function getErrors() 
    { 
    return $this->errors; 
    } 
} 

class A 
{ 
    private $errorCollector; 

    function __construct(/* your additional parameters */, ErrorCollector $errorCollector) 
    { 
    // [...] 
    // additional instantiation stuff 

    $this->errorCollector = $errorCollector; 
    } 

    function sampleFunctionA() 
    { 
    // [...] 
    // some code setting $result to some valid value 
    // or to false if an error occured 

    if($result === false) // check for validity 
    { 
     $this->errorCollector->addError("The sample function A caused a soft error"); 
     return; 
    } 

    // [...] 
    // some code requiring a valid $result 
    } 

} 

你會實例化ErrorCollector只有一次,然後將它傳遞給所有其他類實例化。然後你讓你的對象執行他們的職責(並可能將軟錯誤添加到ErrorCollector)。一旦完成,你的類會得到所有的錯誤信息,再次 - 將它們放在你輸出的正確位置。

+1

我會用第二種方法。依賴注入比全局變量好得多。 – Mike

+0

非常感謝您的回覆。這一切都有道理。如果可以的話,我會加倍努力;) 第二種選擇看起來是最安全的,所以我會放棄這一點。 再次感謝您,Ian –

+0

您可以將我的答案標記爲「已接受」。這將有所幫助。 ;) –

0

異常是一種處理錯誤的方便機制。如果DB返回錯誤,則FormObject可能會拋出一些SoftErrorException類的異常。然後在System中捕捉到此異常並將其呈現給前端。

class System { 

    public function showFormAction() { 

     try { 
      $form = ... // create a form 
      $this->renderForm($form); 
     } catch (SoftErrorException $e) { 
      $this->handleSoftError($e); 
     } 

    } 

    public function handleSoftError(SoftErrorException $e) 
    { 
     // Do whatever you want with exceptions: render it 
     // $this->renderErrorPage($e->getMessage()); 
     // or collect them and show after 
     // $this->errors[] = $e; 
    } 



} 
+1

如果我理解正確,這段代碼並不完全符合伊恩的軟錯誤概念:軟錯誤不應該終止單個工作者方法,而應該以某種方式收集以便稍後顯示(這些工作者完成之後功能)。但是,通過拋出異常,您的代碼將終止這些工作方法而不允許它們完成。 –