2011-07-12 67 views
1

我目睹了一些關於最近項目中PHP異常處理的奇怪行爲。案例如下。PHP:命名空間類,類加載和異常導致奇怪的行爲

在我的應用程序中,我使用命名空間。所有類都在單獨的源代碼文件中。與這個特殊情況相關的代碼分佈在3個類中。

「最外層」類是調度程序(或路由器),它將調度調用包裝在try-catch塊內。調度的請求調用第三個類中的方法,該方法運行代碼(包裝在try-catch塊中),這會導致異常。

因爲我在發生錯誤的類中省略了use Exception;語句,拋出的異常一路回到最外層(調度程序),它被抓到 - 導致我抓我的頭爲什麼catch圍繞導致錯誤的代碼不起作用。

對我來說這似乎很奇怪。從邏輯上講,PHP應該在這種情況下(IMO)拋出一個Class not found異常/錯誤,導致我在代碼中發生實際錯誤,而不是儘可能長時間地「活着」。

這應該作爲錯誤提交還是這種預期行爲?

編輯:代碼示例

文件:​​

<?php 
namespace hello\world; 

class classA { 
    protected $b; 

    public function __construct() { 
     $this->b = new \hello\world\classB(); 
    } 

    public function doSomething() { 
     try { 
      $this->b->throwException(); 
     } catch (Exception $e) { 

     } 
    } 
} 

文件:class-b.php

<?php 
namespace hello\world; 

class classB 
{ 
    public function throwException() { 
     throw new \Exception("bar closed"); 
    } 
} 

文件:run.php

<?php 
include 'class-a.php'; 
include 'class-b.php'; 

$a = new \hello\world\classA(); 

$a->doSomething(); 

ClassB的throw S IN ClassB::doSomething()一個\Exception,爲此ClassA具有catch -clause,但由於ClassA沒有聲明use Exceptioncatch (\Exception),所述catch不匹配和執行與Uncaught exception誤差結束。但在我看來,這應該會導致Class not found錯誤。

我可能會期望過多的寬容的PHP編譯器,但它有助於追蹤應該很容易被編譯器發現的愚蠢錯誤。

如果run.php$a->doSomething()try..catch子句環繞,Exception將(或至少可以)在那裏被捕獲,因爲它滑下的堆棧。

+0

請附上一個小代碼示例 – erenon

+1

同樣在評論中描述:http://www.php.net/manual/en/ language.exceptions.php#99702 –

回答

3

PHP的異常捕獲機制不會驗證您捕獲的類實際上是否存在。

它在函數中使用typehinting時表現出相同的行爲,所以我懷疑它只是將異常/函數類型提示轉換爲字符串或東西,並將其與相關對象的類型進行比較。

這是否是一個錯誤是值得懷疑的。我個人認爲它應該被歸類爲一個bug,但是PHP有各種各樣的怪異行爲:D

+0

事實上,如果我在課堂上忽略了正確的「使用」,但如果使用typehinting,我會得到「class not found」錯誤。也許我也會在這種情況下,如果我沒有把「超級捕捉」放在堆棧中。可能要做更多的研究。 –

+0

這是預期的行爲。由於這些類可能尚未加載。 – Xerkus

+0

我的懷疑是不正確的。刪除「super-catch」不會導致「未找到類」。顯然,'throw'結構得到了特殊的處理。去搞清楚。 –