2010-12-12 45 views
18

Trong ví dụ sau, nếu lớp không tồn tại, tôi muốn bắt lỗi và tạo ra một lớp Null thay thế.Tại sao PHP không gặp lỗi "Không tìm thấy lớp"?

Nhưng mặc dù các câu lệnh try/catch của tôi, PHP chỉ đơn giản là cho tôi biết Class 'SmartFormasdfasdf' not found.

Làm cách nào để nhận được PHP để bắt lỗi 'không tìm thấy lớp'?

<?php 
class SmartFormLogin extends SmartForm { 
    public function render() { 
     echo '<p>this is the login form</p>'; 
    } 
} 

class SmartFormCodeWrapper extends SmartForm { 
    public function render() { 
     echo '<p>this is the code wrapper form</p>'; 
    } 
} 

class SmartFormNull extends SmartForm { 
    public function render() { 
     echo '<p>the form "' . htmlentities($this->idCode) . '" does not exist</p>'; 
    } 
} 

class SmartForm { 

    protected $idCode; 

    public function __construct($idCode) { 
     $this->idCode = $idCode; 
    } 

    public static function create($smartFormIdCode) { 
     $className = 'SmartForm' . $smartFormIdCode; 
     try { 
      return new $className($smartFormIdCode); 
     } catch (Exception $ex) { 
      return new SmartFormNull($smartformIdCode); 
     } 
    } 
} 

$formLogin = SmartForm::create('Login'); 
$formLogin->render(); 
$formLogin = SmartForm::create('CodeWrapper'); 
$formLogin->render(); 
$formLogin = SmartForm::create('asdfasdf'); 
$formLogin->render(); 
?> 

Giải pháp:

Cảm ơn @Mchl, đây là cách tôi giải quyết nó thì:

public static function create($smartFormIdCode) { 
    $className = 'SmartForm' . $smartFormIdCode; 
    if(class_exists($className)) { 
    return new $className($smartFormIdCode); 
    } else { 
    return new SmartFormNull($smartFormIdCode); 
    } 
} 

Trả lời

36

Bởi vì đó là một lỗi nghiêm trọng. Sử dụng hàm class_exists() để kiểm tra xem lớp có tồn tại không.

Ngoài ra: PHP không phải là Java - trừ khi bạn định nghĩa lại trình xử lý lỗi mặc định, nó sẽ tăng lỗi và không ném ngoại lệ.

+2

Tôi quên , PHP try/get tính năng chỉ giúp bạn xây dựng xử lý ngoại lệ của riêng bạn bằng cách cho phép bạn để ném lỗi của riêng bạn, nhưng không do đó bắt lỗi chính nó như trong C#/Java. –

+1

Xem http://www.php.net/manual/en/class.errorexception.php ví dụ về cách 'viết lại' tất cả (trừ trường hợp tử vong) cho các ngoại lệ. Ngoài ra, như đề nghị khác, kể từ 5,3 bạn có thể muốn sử dụng tự động tải để ném một ngoại lệ khi một tập tin có chứa lớp nhất định không được tìm thấy. – Mchl

+2

@Edward - nó chắc chắn cho phép bạn bắt * ngoại lệ *, nhưng hầu hết mọi thứ có nguồn gốc từ PHP không ném ngoại lệ, chỉ là lỗi. Bạn có thể làm việc xung quanh điều này một cách dễ dàng bằng cách định nghĩa error_handler * của riêng bạn và có ném các ngoại lệ bằng cách sử dụng ErrorException (xem http://au.php.net/errorexception và ví dụ ở đó). Điều này dễ dàng chuyển đổi hệ thống lỗi gốc của PHP thành một hệ thống dựa trên Ngoại lệ hữu ích hoạt động khá độc đáo với việc ném/thử/bắt, v.v. –

5

Bạn cần sử dụng class_exists để xem lớp học có tồn tại hay không trước khi bạn thử và khởi tạo nó.

Ngẫu nhiên, nếu bạn đang sử dụng trình nạp tự động lớp, hãy đảm bảo đặt arg thứ hai thành true.

0

Vì php phát ra lỗi nghiêm trọng khi bạn tạo đối tượng mới của lớp không tồn tại. Để làm cho nó hoạt động, bạn sẽ cần php> = 5.3 và autoload chức năng, nơi bạn nên cố gắng tìm tập tin với định nghĩa lớp hoặc ném ngoại lệ tùy chỉnh của bạn.

+0

a) tự động tải là cách sai để thực hiện - xem http: //au.php.net/manual/en/function.spl-autoload-register.php và b) nó không yêu cầu PHP 5.3 –

+1

Việc ném ngoại lệ trong trình nạp tự động thực sự yêu cầu 5.3. Không có gì 'sai' về nó miễn là bạn biết những gì bạn đang làm (tức là nó là một chút ngớ ngẩn để ném một ngoại lệ khi có nhiều autoloaders trong hàng tự động tải). – Mchl

+0

@El Yobo - bạn có thể xây dựng những gì sai với tính năng tự động tải không?chức năng spl không giống nhau, khác biệt duy nhất là nó cho phép bạn cung cấp nhiều chức năng hơn để chạy trong tìm kiếm tập tin chính xác. Ans như cho b), như Mchl nói, bạn vẫn sẽ cần php 5.3 để làm cho nó ném một ngoại lệ. –

10

Câu hỏi cũ, nhưng trong PHP7 đây là ngoại lệ có thể bắt được. Mặc dù tôi vẫn nghĩ rằng class_exists($class) là một cách rõ ràng hơn để làm điều đó. Tuy nhiên, bạn có thể làm một khối try/catch sử dụng loại \Throwable ngoại lệ mới:

$className = 'SmartForm' . $smartFormIdCode; 
try { 
    return new $className($smartFormIdCode); 
} catch (\Throwable $ex) { 
    return new SmartFormNull($smartformIdCode); 
} 
+1

Ngoài ra, nếu bạn muốn cụ thể hơn với những gì bạn đang bắt, bạn có thể bắt loại \ Error thay thế (thử nghiệm để làm việc trong PHP 7.1). Điều này sẽ làm cho mã của bạn trở nên dễ vỡ hơn khi thay đổi cách ngôn ngữ PHP phát triển, nhưng cũng ít có khả năng bắt được thứ gì đó mà bạn không có ý định bắt giữ. Nếu bạn có các bài kiểm tra tự động tốt, bạn sẽ có thể thoát khỏi phiên bản cụ thể hơn bởi vì các thử nghiệm của bạn sẽ thất bại nếu PHP đột nhiên bắt đầu ném một loại khác cho điều này. –

0

php> = 7.0

php có thể bắt 'lớp không tìm thấy' như Throwable

try { 
     return new $className($smartFormIdCode); 
} catch (\Throwable $ex) { 
     return new SmartFormNull($smartformIdCode); 
} 
Các vấn đề liên quan