2010-12-12 25 views
18

次の例では、クラスが存在しない場合、エラーをキャッチして代わりにNullクラスを作成します。PHPが「クラスが見つかりません」というエラーをキャッチしないのはなぜですか?

私のtry/catchステートメントにもかかわらず、PHPは単にClass 'SmartFormasdfasdf' not foundを教えてくれます。

「クラスが見つかりません」というエラーをキャッチするにはどうすればよいですか?

<?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(); 
?> 

ソリューション:

おかげ@Mchl、これは私がそれを解決する方法である:

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

答えて

36

それは致命的なエラーだからです。クラスが存在するかどうかを確認するには、class_exists()関数を使用します。

また、PHPはJavaではありません。デフォルトのエラーハンドラを再定義しない限り、エラーを発生させ、例外をスローしません。

+2

として 'クラスが見つかりません' PHPのtry/get機能は、独自のエラーをスローすることで独自の例外処理を構築するのに役立ちますが、C#/ Javaのようにエラー自体を捕捉することはありません。 –

+1

すべての(致命的なエラーを除く)エラーを例外に「書き換える」方法の例については、http://www.php.net/manual/en/class.errorexception.phpを参照してください。また、5.3より、指定されたクラスを含むファイルが見つからないときにオートローダーを使用して例外をスローすることもできます。 – Mchl

+2

@Edward - 例外的に*例外を捕まえることはできますが、PHPにネイティブなものはほとんどすべて例外をスローしません。独自の* error_handler *を定義し、ErrorExceptionを使用して例外をスローすることで簡単に回避できます(http://au.php.net/errorexceptionとその例を参照)。これは、PHPのネイティブエラーシステムを、スロー/トライ/キャッチなどでうまく動作する便利な例外ベースのシステムに簡単に切り替えます。 –

5

クラスをインスタンス化する前にクラスが存在するかどうかを確認するには、class_existsを使用する必要があります。

なお、クラスオートローダーを使用している場合は、必ず2番目のargをtrueに設定してください。

0

既存のクラスではない新しいオブジェクトを作成するときにphpが致命的なエラーを発生するためです。それを動作させるには、php> = 5.3およびautoload関数が必要です。クラス定義でファイルを探したり、カスタム例外をスローしたりする必要があります。

+0

a)オートロードは間違った方法です - http: //au.php.net/manual/en/function.spl-autoload-register.php b)PHPは不要5.3 –

+1

オートローダーに例外をスローするには実際に5.3が必要です。あなたが何をしているかを知っている限り、それについて何も「間違っている」ことはありません(つまり、自動ロードキューにオートローダがあると例外がスローされます)。 – Mchl

+0

@El Yobo - あなたは自動ロードで何が問題なのか詳しく説明できますか?spl関数は同じですが、違いは正しいファイルを検索するためにもっと多くの関数を提供できるということだけです。 Ansはb)のように、Mchlが言ったように、例外をスローするにはPHP 5.3が必要です。 –

10

古い質問ですが、PHP7ではこれがキャッチ可能な例外です。私はまだclass_exists($class)がもっと明白な方法だと思っていますが。しかし、あなたは新しい\Throwable例外タイプを使用してtry/catchブロックを行うことができます:

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

また、あなたが捕捉しているものをより具体的にするには、代わりに\ Errorタイプをキャッチすることができます(PHP 7.1で動作することがテスト済み)。これは、PHP言語の進化の仕方を変えるためにコードを脆弱にするだけでなく、キャッチしようとしなかったものをキャッチする可能性は低くなります。良い自動化テストをしているなら、PHPが突然このために別の型を投げ始めるとテストが失敗するので、より特定のバージョンを手に入れることができます。 –

0

PHP> = 7.0

PHPキャッチすることができ、私は忘れてしまったThrowable

try { 
     return new $className($smartFormIdCode); 
} catch (\Throwable $ex) { 
     return new SmartFormNull($smartformIdCode); 
} 
関連する問題