2010-02-06 48 views
47

Tôi có mã này. Có thể cho một constructor đối tượng User bằng cách nào đó thất bại để $this->LoggedUser được gán giá trị NULL và đối tượng được giải phóng sau khi hàm tạo trả về?PHP constructor để trả về một NULL

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

Great câu hỏi đầu tiên bằng cách này. –

+0

Tôi đã nhìn thấy một CMS phổ biến nhất định trả về FALSE trong một hàm tạo. Có chuyện gì thế?!?! – loungerdork

+1

Chỉ cần nghĩ rằng tôi sẽ kêu vang ở đây vì tài liệu hướng dẫn. Kể từ ngày cho đến nay trở lại, có thể là CMS bạn đang thấy được xây dựng cho PHP4. PHP4 được sử dụng để cho phép rất nhiều điều xấu, không phải là ít nhất trong số đó cho phép người dùng ghi đè $ this trong constructor được đặt tên (ví dụ $ this = false). – techdude

Trả lời

62

Giả sử bạn đang sử dụng PHP 5, bạn có thể ném một ngoại lệ trong các nhà xây dựng:

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) {} 
} 

Để rõ ràng, bạn có thể bọc này trong tĩnh phương thức nhà máy:

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']); 

Ngoài ra, một số phiên bản của PHP 4 cho phép bạn đặt $ this thành NUL L bên trong các nhà xây dựng nhưng tôi không nghĩ rằng đã từng bị chính thức xử phạt và 'tính năng' cuối cùng đã được gỡ bỏ.

+4

+1 IMO, đây là cách OO đúng để chỉ ra sự thất bại trong việc xây dựng một đối tượng. –

+1

Nó phụ thuộc vào bản chất của sự thất bại. Nếu đó là một ngoại lệ, vâng. Nếu một tham số cho hàm tạo không đáp ứng một tiêu chí, trong tâm trí của tôi là không. –

+5

Pekka, tôi không chắc loại "thông số xấu" nào sẽ không là ngoại lệ? Nếu bạn không thể tạo một đối tượng hợp lệ với một tập hợp các tham số nhất định chắc chắn là ngoại lệ, và nên ném một ngoại lệ? Bạn có thể đưa ra một ví dụ để làm rõ sự khác biệt mà bạn đang nghĩ tới không? (Tôi thấy bạn làm trong câu trả lời dưới đây, điều đó sẽ hữu ích ở đây, nhưng tôi không thể chỉnh sửa bình luận của bạn!) –

11

AFAIK không thể thực hiện được, new sẽ luôn trả về phiên bản của đối tượng.

Những gì tôi thường làm gì để làm việc xung quanh này là:

  • Thêm một ->valid cờ boolean đến đối tượng đó sẽ xác định xem một đối tượng đã được nạp thành công hay không. Các nhà xây dựng sau đó sẽ đặt cờ

  • Tạo một hàm wrapper mà thực hiện lệnh new, trả về đối tượng mới về sự thành công, hoặc thất bại phá hủy nó và trả về false

-

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

Tôi muốn được nghe về các phương pháp thay thế, nhưng tôi không biết bất kỳ điều gì.

+0

Cảm ơn bạn đã làm rõ. Vì vậy, về cơ bản tôi có thể gỡ bỏ lệnh mới trong thử ...bắt và sau đó tăng một ngoại lệ trong một constructor? – Tibor

+1

Câu hỏi hay! Tôi nghĩ rằng bạn * có thể *, nhưng nó không thực sự đúng với tôi. Nếu tôi tạo ra một chiếc xe đối tượng với mô hình "Ford" nó có thể chỉ đơn giản là không có chiếc xe của mô hình đó là trong cơ sở dữ liệu. Đó không phải là những gì * ngoại trừ * được thiết kế cho. Đó là điều kiện mong đợi hơn. Tôi muốn được quan tâm để xem những gì khác câu trả lời đi lên, những gì được xem như là "đúng" cách để xử lý này. –

+0

điều này đang làm điều theo cách bẩn thỉu, kiểm tra câu trả lời của @ jaz303 – minhajul

3

Khi một hàm tạo không thành công vì một số lý do không xác định, nó sẽ không trả về giá trị NULL hoặc FALSE nhưng nó ném một ngoại lệ. Như với tất cả mọi thứ với PHP5. Nếu bạn không xử lý ngoại lệ thì tập lệnh sẽ ngừng thực thi với lỗi Ngoại lệ không bắt buộc.

+1

Khi nào một hàm tạo ném một ngoại lệ? Khi nó trả về false? Hoặc bạn có nghĩa là, một nhà xây dựng nên ném một ngoại lệ nếu một điều kiện nhất định không thể được đáp ứng'? –

+1

Nhà xây dựng của bạn nên ném ngoại lệ. – Tom

5

Hãy xem xét theo cách này. Khi bạn sử dụng new, bạn sẽ nhận được một đối tượng mới. Giai đoạn. Những gì bạn đang làm là bạn có một chức năng tìm kiếm một người dùng hiện có và trả về nó khi tìm thấy. Điều tốt nhất để thể hiện điều này có lẽ là một hàm lớp tĩnh như User :: findUser(). Điều này cũng có thể mở rộng khi bạn đang phát triển các lớp của bạn từ một lớp cơ sở.

+0

Điều đó nghe có vẻ hợp lý nhất. Tôi chỉ mới bắt đầu lập trình OO bằng PHP nên tôi không hoàn toàn chắc chắn cách xử lý mọi thứ theo cách 'thích hợp'. – Tibor

3

có lẽ một cái gì đó như thế này:

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

Một nhà máy có thể có ích ở đây:

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