2016-02-23 64 views
3

PHP有其神奇的方法__call__callStatic,它允許截取對不存在的方法的調用。我正在尋找一種方法來攔截對不存在的函數(位於名稱空間內而不是類型內)的調用。是否可以截取對不存在函數的調用?

可以做(PHP7)嗎?

有一段時間我考慮把函數放在代理類中,但命名空間可以跨越幾個文件,如果我沒有弄錯,PHP沒有部分類,因此這種方法是沒有用的。

更新:每個命名空間問題有多個文件。

比方說,我有文件A.php和B.php,都使用相同的名稱空間,比如Text。考慮將所有函數都放到代理類中。現在我有文件C.php,我打電話給Text\indexOf(...)。但是我不知道這是Text\proxyA::indexOf還是Text\proxyB::indexOf,因爲我擁有的所有信息都是名稱空間的名稱 - Text - 和函數名稱。所以從來電方我烤了。

+0

如果通過「截取」您的意思是「通過返回我自己選擇的值來正常解析調用」,那麼不,這是不可能的。但我真的好奇 - 用例會是什麼? – Jon

+0

@Jon,通過攔截我的意思是什麼'__callStatic'只有一個區別 - 目標是命名空間不是一個類型。目的,我正在處理類似於C++中的模板,我會攔截一個函數調用,取消名稱的調用,並調用函數工廠生成(然後調用)該函數的專用版本(我使用PHP作爲後端語言:http://aboutskila.wordpress.com/)。 – greenoldman

+1

那麼,如果你需要這個功能,那你爲什麼要編譯來直接調用函數呢?你可以編譯爲'resolve_function_call('mangled_name',['argument','list'])'並解決問題。或者甚至用專門爲此目的創建的類型上的靜態方法調用替換裸函數調用,這會使用__callStatic攔截它們。 – Jon

回答

3

由於PHP7的你可以趕上未定義的函數調用:

try { 
    idontexist(); 
} catch (\Error $e) { 
    echo $e->getMessage(); 
} 

有沒有辦法以同樣的方式,通過自定義錯誤處理程序使用此爲__call當然除了。

演示:https://3v4l.org/j4WRB

+0

謝謝,但在實踐中它不是真的可行 - 因爲你必須在try-catch中包裝每個**函數調用,所以你必須真正關注異常和堆棧 - 它可能會如果你調用現有的函數,但是這個函數調用你忘記包裝的不存在的函數。 – greenoldman

+0

你沒有錯,但不幸的是,這就是你需要處理的一切。 – rjdown

2

隨着PHP7 +你能趕上調用​​未定義功能:

try { 
    not_exist(); 
} catch (\Error $e) { 
    echo 'ERROR: ' . $e->getMessage(); 
} 

然後可以使用set_exception_handler趕上,如果沒有它在try/catch塊是:

set_exception_handler(function($e) { 
    echo '<BR>ERROR: ' . $e->getMessage(); 
}); 

not_exist(); 

請注意,您需要使用set_exception_handler而不是set_error_handler

+0

謝謝,但是您仍然需要編寫try-catch,並且使用假'catch'子句來避免捕獲異常。由於例外是昂貴的機制,因此這不會爲以前的答案添加任何新的內容。 – greenoldman

+0

爲什麼你還需要寫catch?什麼是假冒的? – nbrogi

+0

「如果在try/catch塊中未捕獲到異常,則設置默認異常處理程序。」這意味着try-catch必須首先存在(否則程序崩潰),所以我必須只有try-catch才能捕獲該異常。 – greenoldman

相關問題