2010-02-06 117 views
47

我有這段代碼。 User對象構造函數有可能以某種方式失敗,因此$this->LoggedUser被分配了一個NULL值,並且該對象在構造函數返回後被釋放?PHP構造函數返回NULL

$this->LoggedUser = NULL; 
if ($_SESSION['verbiste_user'] != false) 
    $this->LoggedUser = new User($_SESSION['verbiste_user']);  
+7

大順便說一下第一個問題。 – 2010-02-06 21:20:35

+0

我見過一個流行的CMS,它在構造函數中返回FALSE。那是怎麼回事?!?! – loungerdork 2011-10-31 03:17:27

+1

只是覺得我會在這裏爲了文檔的緣故。由於日期還早,因此您所看到的CMS可能是爲PHP4構建的。 PHP4用來允許很多不好的事情,其中​​最重要的是允許用戶在命名構造函數中覆蓋$ this(例如$ this = false)。 – techdude 2014-12-31 22:52:21

回答

62

假設你正在使用PHP 5中,你可以在構造函數中拋出一個異常:

class NotFoundException extends Exception {} 

class User { 
    public function __construct($id) { 
     if (!$this->loadById($id)) { 
      throw new NotFoundException(); 
     } 
    } 
} 

$this->LoggedUser = NULL; 
if ($_SESSION['verbiste_user'] != false) { 
    try { 
     $this->LoggedUser = new User($_SESSION['verbiste_user']); 
    } catch (NotFoundException $e) {} 
} 

爲清楚起見,你可以在一個靜態的這個包裹工廠方法:

class User { 
    public static function load($id) { 
     try { 
      return new User($id); 
     } catch (NotFoundException $unfe) { 
      return null; 
     } 
    } 
    // class body here... 
} 

$this->LoggedUser = NULL; 
if ($_SESSION['verbiste_user'] != false) 
    $this->LoggedUser = User::load($_SESSION['verbiste_user']); 

另外,某些版本的PHP 4允許您將$ this設置爲NUL L在構造函數中,但我認爲從未被正式認可,並且「特徵」最終被刪除。

+4

+1 IMO,這是指示構建對象失敗的正確OO方式。 – 2010-02-06 21:26:20

+1

這取決於失敗的性質。如果這是一個例外,是的。如果構造函數的參數不符合標準,那麼在我看來沒有。 – 2010-02-06 21:35:01

+5

佩卡,我不確定什麼樣的「壞參數」不會是一個例外?如果你不能用一組特定的參數創建一個有效的對象,並且應該拋出異常?你能舉個例子來澄清你所想的區別嗎? (我看到你在下面的答案中做了,這在這裏會很有用,但我不能編輯你的評論!) – 2012-05-14 11:01:01

11

AFAIK這不能完成,new將始終返回對象的一個​​實例。

我最常做的來解決這個:

  • 添加->valid布爾標誌,用於確定對象是否加載成功與否的對象。然後,構造函數將設置標誌

  • 創建了執行new命令的封裝功能,成功返回新的對象,如果失敗,破壞了它,並返回false

-

function get_car($model) 
     { 
     $car = new Car($model); 
     if ($car->valid === true) return $car; else return false; 
    } 

我很想聽聽其他方法,但我不知道。

+0

謝謝澄清。 所以基本上我可以只是試試新的命令...捕獲然後在構造函數中引發異常? – Tibor 2010-02-06 21:13:40

+1

好問題!我認爲你*可以*,但它並不適合我。如果我使用「福特」模型創建對象汽車,則可能只是該數據庫中沒有該型號的汽車。這不是真正的*例外*是爲什麼設計的。這是更多的預期條件。我很想看看還有什麼其他答案出現,什麼被視爲處理這個問題的「正確」方式。 – 2010-02-06 21:16:48

+0

這是在骯髒的方式做事情,檢查@ jaz303的回答 – minhajul 2015-11-19 12:13:37

3

當構造函數由於某些未知原因而失敗時,它不會返回NULL值或FALSE,但會引發異常。與使用PHP5的一切一樣。如果你沒有處理異常,那麼腳本將停止執行,並帶有未捕獲異常錯誤。

+1

什麼時候構造函數拋出異常?當它返回false?或者你的意思是,如果某個條件無法滿足,構造函數應該拋出異常? – 2010-02-06 21:13:38

+1

你的構造函數應該拋出異常。 – Tom 2012-10-04 14:30:57

5

考慮這種方式。當你使用new時,你會得到一個新對象。期。你在做什麼是你有一個功能,搜索現有的用戶,並返回它找到。表達這個最好的東西可能是一個靜態類函數,例如User :: findUser()。當你從基類派生你的類時,這也是可擴展的。

+0

這聽起來最符合邏輯,是的。我剛剛開始使用PHP進行OO編程,因此我不完全確定如何以「正確」方式處理事情。 – Tibor 2010-02-06 21:22:42

3

也許是這樣的:

class CantCreateException extends Exception{ 
} 

class SomeClass { 
    public function __construct() { 
     if (something_bad_happens) { 
      throw (new CantCreateException()); 
     } 
    } 
} 

try{ 
    $obj = new SomeClass(); 
} 
catch(CantCreateException $e){ 
    $obj = null; 
} 
if($obj===null) echo "couldn't create object"; 
//jaz303 stole my idea an wrap it into a static method 
4

一個工廠可能是有用的位置:

class UserFactory 
{ 
    static public function create($id) 
    { 
     return (
      filter_var( 
       $id, 
       FILTER_VALIDATE_INT, 
       [ 'options' => [ 'min_range' => 1, ] ] 
      ) 
       ? new User($id) 
       : null 
     ); 
    } 
}