這篇文章給大家介紹的內容是關於正確註釋@return讓PHPstorm動態返回類,有一定的參考價值,有需要的朋友可以參考一下,希望對你有所幫助。
場景是這樣的,有一個BaseModel(繼承自ActionRecord),所有的其他model都繼承自它,然後其中有一個方法,簡單貼下這個類別的程式碼:
class BaseModel extends ActiveRecord { protected $temp_model; public function getCacheModel() { return $this->temp_model; } }
這個方法的作用是取得在做參數驗證時,從資料庫查出的,快取下來的實例物件。
這時候,問題來了,我在取出這個物件的時候,PHPstorm沒有了提示(如方法提示,屬性提示等),按照一般的情況,只需要在方法前面加上@return註釋就可以了。
/** * @return static */ public function getCacheModel() { return $this->temp_model; }
我們繼續深入研究一下,關於這個static的意思,我特地在PHPDoc上查閱了一下,
static
An object of the class where this value was consumed, if
inherited it will represent the child class. (see late static binding in
the PHP manual).
Google翻譯一下,大意如下:
消耗此值的類別的對象,如果繼承它將表示子類別。
(請參閱PHP手冊中的後期靜態綁定)。
大概意思是就會返回調用這個方法的類,如果是父類方法子類調用,那麼將返回子類。
類似的還有2個
self
An object of the class where this type was used, if inherited it will still represent the class where it was originally defined.
$this
This exact object instance, usually used to denote a fluent interface.
直譯如下,
self:使用此類型的類別的對象,如果繼承它,它仍將表示最初定義它的類別。
大意就是和static差不多,但是父類別方法子類別調用,仍然返回父類別。
$this:這個確切的物件實例,通常用來表示流暢的介面。
和self差不多。
但是到了這裡,我的問題仍然沒有解決,無論我@return的值改成什麼,仍然返回的是BaseModel,儘管我在這個getCacheModel()方法裡列印self::className() 時,出現的是子類別名稱。
所以我們繼續往上面看,我是在controller呼叫的,controller的程式碼如下:
public function actionCommitReward() { $model=$this->goCheck(new TakeRewards(['scenario'=>'commit_reward'])); //获取实际要修改的数据 $reward = $model->getCacheModel(); }
看起來沒有什麼問題,這個時候我們要注意了, $model是由$this->goCheck()呼叫得到的,我們去看一下goCheck方法:
//验证参数是否合法 public function goCheck($model, $dada = '') { $data = $this->postData;//post传入的数据 if ($model->load($data, '') && $model->validate())//数据效验
return $model;
else (new PublicFunction())->returnWayTip('1001', PublicFunction::getModelError($model));//这里理解成抛异常 }
這裡不規範的地方出現了,由於這裡傳入的是model(物件類型),所以PHPstorm並沒法知道我們具體傳入的是什麼類,加上註解後:
/** * @param object $model * @param string $dada * @return model1|model2 */
這樣後,問題「勉強解決」。只是每增加一個表,會需要在@return裡增加表相對應的類別名,而且會有類別本來不應該存在的屬性被提示。
為什麼這裡不能用static?因為這裡是$this調用的,返回controller類,並沒有什麼用,而這個也導致了後面使用$model->getCacheModel()方法時,沒有辦法正常識別應該返回的類別(返回什麼類取決與goCheck的@return註解是什麼)。
當然你可以不寫註釋,那你會發現,所以的提示都沒有了。
這次我才真正意識到了註解的重要性。 。 。原來PHPstorm之所以都提示,都是因為大家按PHPDoc的規範寫了註釋啊!
最後可能有同學會問了,為什麼不把goChekc方法放到BaseModel裡面呢?對的,實際上規範的做法是應該這樣的,但是因為我這樣把Yii::$app->request->post()賦值在controller裡的$this->postData裡(雖然這樣方便一丟丟),而且在做token換id的一些操作了進行了手動賦值,所以沒有辦法,因為在model獲取不到這個postData,當然你一定要挪進去也是可以的,只不過每次都需要傳參$this->postData,見仁見智吧。
但是,這2個方法都不規範,$this->postData = Yii::$app->request->post(); 把全域的變數變成了局部變量,規範的做法應該是使用Yii::$app->request->post($name,$dafaultValue)來賦予post資料賦值。
最後,因為不是我一個人在寫,所以沒有辦法進行大刀闊斧地改動,只能盡可能地優化。
相關文章推薦:
#以上是如何來正確註解@return來讓PHPstorm動態回傳類的詳細內容。更多資訊請關注PHP中文網其他相關文章!