2013-05-03 90 views
3

在我正在構建的框架中,我正在努力讓我的代碼更加可測試,因爲我之前沉迷於MVC + Singleton模式,並且擁有靜態類豐盛的類。從那時起,我開始更多地瞭解單元測試和TDD,因此它促使我重新考慮了很多代碼。部分這種重新分解促使我嘗試在PHP中正確使用Extension類,即不僅拋出Exception類,而且拋出更相關的異常。PHP幹投擲InvalidArgumentException

我有下面的類:

<?php 

namespace Framework; 

class Uri { 

    public static function new_from_http() { 

     $uri = ''; 

     if (isset($_SERVER['REQUEST_URI'])) { 
      $uri = $_SERVER['REQUEST_URI']; 
     } elseif (isset($_SERVER['PATH_INFO'])) { 
      $uri = $_SERVER['PATH_INFO']; 
     } 

     return static::new_from_string($uri); 
    } 

    public static function new_from_string($string) { 

     return new static(explode('/', $string)); 
    } 

    protected $uri = []; 

    public function __construct(array $uri) { 

     $this->uri = array_values(array_filter($uri)); 
    } 

    public function get_segment($offset, $default = null) { 

     if (!is_int($offset)) { 
      throw new \InvalidArgumentException(
       sprintf('%s requires argument 1 to be an integer, %s given.', 
        __METHOD__, 
        gettype() 
       ) 
      ); 
     } 

     return isset($this->uri[$offset - 1]) 
      ? $this->uri[$offset - 1] 
      : $default; 
    } 
} 

那一切都很好,正如你所看到的,get_segment方法需要一個整數,否則它拋出一個InvalidArgumentException。麻煩的是,我想創建一些需要整數作爲參數的更多方法,我不想在任何地方剪切和粘貼該代碼。整合所有這些類型的參數檢查的最佳選擇是什麼,以便我可以在不同的類和方法中使用它們,同時保持消息之間的一致性。

我的一個想法是異常類的框架命名空間下延伸,並具有構造採取不同的參數,如:

namespace Framework; 

class InvalidArgumentException extends \InvalidArgumentException { 

    public function __construct($method, $argument, $value) { 

     parent::__construct(
      sprintf('%s requires argument 1 to be an integer, %s given.', 
       $method, 
       gettype($value) 
      ) 
     ); 
    } 
} 

這將是所謂的喜歡:

if (!is_int($arg)) { 

    throw new \Framework\InvalidArgumentException(__METHOD__, 1, $arg); 
} 

可能也可以改進,\Framework\InvalidArgumentException可以通過回溯得到__METHOD__值。

我有什麼其他選擇,什麼是最好的?

回答

2

我會將/InvalidArgumentException擴展爲NonIntegerException,否則做基本相同的事情。這種方式如果你想要求strings,arrays或任何其他類型,你可以創建新的例外,你不必瘋狂的邏輯來確定使用哪個消息。