2012-07-16 20 views
5

首先我知道這個問題已經圍繞不止一次在這裏:E_NOTICE:修復每一個問題真的有用嗎?

但更多的,我解決所有E_NOTICEs(因爲有人說你應該)越我注意到:

  • 我微優化
  • 其實我做更多的代碼,使我的代碼難於十個分量和慢

拿一個例子:

說使用MongoDB的PHP驅動你的,你必須在一個名爲ts內一類變種一個MongoDate對象一個表示數據庫集合中單個行的類。現在你訪問這個變量,如:$obj->ts->sec但PHP拋出一個合適的(E_NOTICE),因爲在這種情況下ts沒有被定義爲一個對象本身,因爲這個特定的行沒有ts字段。所以你認爲這是好的,如果它沒有設置返回null,這是我們期望的行爲,並且我會在解釋器自己的機器人工作之外自己處理它(因爲如果var是功能,則返回1970nullnone-object)。

但現在要修復E_NOTICE作爲另一個開發人員真的希望我,因爲有任何E_NOTICEs是terribad,並且它使代碼變得更慢,不根據錯誤執行它。所以我做的$obj類的新功能叫getTs,我給它3條線路,從字面上做什麼,但檢查ts var是一個MongoDate對象並返回它,如果它是...

爲什麼?在應用程序本身的運行時間內,PHP不能在它的快速解釋器中爲我完成這項工作嗎?我的意思是每一處我不得不爲我的代碼添加無用的凹凸,幾乎空的函數來檢測變量,我實際上只是用PHP自己處理的能力來返回null或檢查他們的instanceof當我真的需要時(當它是至關重要的操作和行爲的功能),並沒有讓我開始在isset() s我已經添加了約300行isset() s,它已經失控。我當然得讓這個getTs功能,因爲你不能做的:

class obj{ 
    public $ts = new MongoDate(); 
} 

我要麼必須存儲__constructor內的ts(這我不是太高興要麼,我使用了很多)或者使用函數來檢測它是否已設置(我現在所做的)。

我的意思我明白爲什麼我應該修正:

  • 未定義瓦爾
  • 分配未設置瓦爾的性質(null增值經銷商)
  • 恆錯誤等

但是,如果你已經測試你的代碼,你知道它是安全的,只會按照你想要的方式工作,修復所有的undefined indexnone-object er RORS?是不是加了一堆isset() s和2行函數來實際對你的代碼進行微優化?

我已經做了一半的網站E_NOTICE兼容,實際上它使用更多的CPU,內存和現在時間後發現......所以真的有什麼處理每一個E_NOTICE錯誤點,而不是僅僅是錯誤的呢?

感謝您的想法,

+0

你不應該。相反,你應該處理異常。但是...歡迎來到PHP! – 2012-07-16 18:34:44

+0

@ IgnacioVazquez-Abrams事實上,PHP應該是一種動態語言,但是修復所有這些'E_NOTICES'我認爲至少有1000個人認爲不要在他們的市場營銷中宣傳動態,但更多的是...... – Sammaye 2012-07-16 18:44:25

+0

你'我們會發現PHP是90%的營銷,9%的努力和1%的瘋狂。 – 2012-07-16 18:46:38

回答

3

無論你是否應該解決這些問題肯定是有爭議的,並且將只取決於你的情況的回報;例如,如果代碼的壽命更長,開發人員更多,則更重要。

通常,假設您的函數將被其他人使用(並被錯誤使用)是最佳實踐,所以你應該做isset /!empty/is_object檢查來解決這個問題。通常情況下,你的代碼會發現它的用途和情況,你從來沒有打算用它。性能方面,每當引發任何類型的錯誤 - 包括E_NOTICE時 - 解釋器都會啓動錯誤處理程序,生成堆棧跟蹤並設置錯誤的格式。關鍵是,無論你是否有他們的報告,錯誤總是執行緩慢;因此,2-3函數調用以避免E_NOTICE仍然會提高您的性能

編輯: 替代品上面的例子

我不一定會創建額外的對象,以避免錯誤;你可以優雅地避開它們。這裏有幾個選項:

1)該函數處理缺少TS:

SpecialClass class { 

    funciton getTs() { 
     return !empty($this->ts) ? $ts->sec : false; 
    } 
} 

2)應對模板/程序丟失TS:

if (!empty($obj->ts->sec)) { 
    //do something 
} 

我特別喜歡empty()因爲你可以用它來代替(isset($var) && ($var or 0 != $var //etc)),保存多個調用/比較,並且不會拋出目標var或屬性的通知。如果你在一個不存在的變量的proplish /成員上調用它,它會拋出一個錯誤。

+0

所以說我有一個20個項目的活動流。在我上面的例子中,每個對象都有一個'MongoDate'對象。在每個父對象'$ obj'中創建一個新對象並且對該變量進行計算比允許PHP調用全局錯誤函數(內置或由用戶預定義)更快,更高效? – Sammaye 2012-07-16 20:16:39

+0

要麼這樣(雖然我會建議如果沒有設置,而不是立即創建一個返回false),或者只是在使用它之前測試返回:即:if(!empty($ obj-> ts)){// do stuff ; }或$ ts =!empty($ obj-> ts)? $ ts-> sec://備用值; – 2012-07-16 20:25:29

+0

Meh決定只是指揮下去做最後。我仍然注意到增加了CPU和內存消耗,即使我所做的所有事情都是根據對象是否存在添加更多的IF語句來作出決策。實際上可能會對此做一個白皮書。這種方法在HTML中非常難看,而PHP應該是一種動態語言......但無論如何,謝謝。 – Sammaye 2012-07-18 07:51:19

6

你當然做用isset()獲得更好的性能做。我做了一些基準測試,不久之前,隱藏錯誤的速度大約慢了10倍。

http://garrettbluma.com/2011/11/14/php-isset-performance/

這就是說,性能通常不是在PHP中的一個關鍵因素。 做什麼親自讓我瘋狂的是無聲錯誤

當解釋者選擇不將某些東西標記爲錯誤(這可能導致不穩定)是一個巨大的問題。 PHP特別是有一種傾向,

  • 警告的事情應該錯誤(例如未能連接到數據庫)和
  • 問題通知有關的事情,應該警告(如嘗試訪問空對象的成員)。

也許我對這種東西只是過分的認同,但我之前被這些沉默的錯誤咬過。 我建議在錯誤報告中始終包含E_NOTICE。

+1

+1尼斯鏈接,我想在一分鐘內對我的網站進行基準測試,當我說處理所有E_NOTICE的速度比讓PHP訪問錯誤對象要慢時,我非常認真。實際上,新代碼只是讓我的服務器崩潰,因爲它實際上是用對象填充整個內存......我所做的只是添加一個函數來定義一個新對象,如果它不存在......唯一區別:\ – Sammaye 2012-07-16 19:27:00

+1

它可能不是一個選項,但看看Xdebug。你可以分析你的代碼並找出時間/內存在哪裏花費最快。 (WinCacheGrind也是一個很好的配置文件查看器。) – 2012-07-16 19:30:31

+0

Aye我將不得不簡要描述一下,理論上我的代碼應該在每次迭代中使用一個內存點,但它不是,prolly一個編碼錯誤,但這仍然只是一個例子,慢很難解釋的地方... – Sammaye 2012-07-16 19:40:01