当前位置: 首页 > 后端技术 > PHP

正确注解@return让PHPstorm动态返回类

时间:2023-03-29 21:27:35 PHP

场景是这样的。有一个BaseModel(继承自ActionRecord),其他的model都继承自它,然后还有一个方法,直接贴上这个类的代码:classBaseModelextendsActiveRecord{protected$temp_model;publicfunctiongetCacheModel(){return$this->temp_model;}}该方法的作用是获取参数校验时从数据库中检测到的缓存实例对象。这时候,问题就来了。当我取出这个对象时,PHPstorm没有任何提示(比如方法提示,属性提示等)。按照一般情况,只需要在方法前加上@return注解即可。/***@returnstatic*/publicfunctiongetCacheModel(){return$this->temp_model;}下面继续深入研究。关于thisstatic的含义,我特地在PHPDoc上查了下,static是消费Thisvalue的类的一个对象,如果被继承就会代表子类。(请参阅PHP手册中的后期静态绑定)。(请参阅PHP手册中的后期静态绑定)。大概意思就是调用这个方法的类会被返回。如果它被子类的父类方法调用,那么子类将被返回。同理,有2个selfAn对象是使用该类型的类,如果被继承,它仍然代表最初定义的类。$this确切的对象实例,通常用于表示流畅的界面。直译如下,self:使用该类型的类的对象,如果继承自该类型,仍将代表其最初定义所在的类。大意是和static类似,但是父类的方法被子类调用,返回的还是父类。$this:这个确切的对象实例,通常用来表示一个流畅的界面。几乎和自己一样。但是到这里,我的问题还是没有解决,不管我怎么改@return的值,还是会返回BaseModel,虽然我在这个getCacheModel()方法中打印self::className()时,它显示为子类名.于是我们继续往上看,我是在controller中调用的,controller的代码如下:publicfunctionactionCommitReward(){$model=$this->goCheck(newTakeRewards(['scenario'=>'commit_reward']));//获取实际要修改的数据$reward=$model->getCacheModel();}好像没有问题,这个时候要注意了,$model是调用$this->goCheck()获取的,我们去看看goCheck方法://验证参数是否合法publicfunctiongoCheck($model,$dada=''){$data=$this->postData;//post传入数据if($model->load($data,'')&&$model->validate())//数据校验return$model;else(newPublicFunction())->returnWayTip('1001',PublicFunction::getModelError($model));//这里理解为抛出异常}这里有个不规范的地方。由于这里传入的是模型(对象类型),所以PHPstorm无法知道我们传入的是什么类。添加注释后:/***@paramobject$model*@paramstring$dada*@returnmodel1|model2*/在此之后,问题“勉强解决”了。只是每次添加表时,需要在@return中添加该表对应的类名,会有类中不应存在的属性提示。这里为什么不能用static呢?因为这里是$this调用的,返回controller类是没有用的,这也导致后面使用$model->getCacheModel()方法时无法识别应该返回的类(返回什么类取决于goCheck@return注释是什么)。当然,你不需要写注释,然后你会发现所有的提示都没有了。这次才真正体会到注解的重要性。..原来PHPstorm之所以全部提示,是因为大家按照PHPDoc规范写了注释!最后可能有同学会问,为什么不把goChekc方法放在BaseModel里面呢?是的,其实规范的做法应该是这样的,但是因为我在controller中把Yii::$app->request->post()赋给了$this->postData(虽然方便),还有一些操作changingtokenid已经手动赋值了,所以没办法,因为模型中获取不到postData,当然要搬进去,但是每次都需要传参数$this->postData,不同的人有不同意见。但是,这两种方法都没有标准化。$this->postData=Yii::$app->request->post();将全局变量变成局部变量。规范的做法应该是使用Yii::$app->request->post($name,$dafaultValue)给post数据赋值。最后因为不是我一个人写的,没办法大刀阔斧的改动,只能尽量优化。BTW,希望大佬们有更好的意见谈谈,因为我比较经验比较少,正在自己琢磨。