(原文地址,内容以原文为准,可能有修改补充:https://blog.tanteng.me/2017/...)关于PHP新的静态延迟staticbindingFixed,或者说后期的静态绑定,在Laravel中使用中遇到了问题。如下,在Laravel中调用Model添加新数据时,首先为Model添加获取子表的方法:protectedfunctionaddToMessage($msgType,$userID,$commentID,$replyCommentID,$replyUserID,$gameID){if(!$userID){返回false;}$table='t_message_'。hashID($userID,100);$this->message->setTable($table)->create(['msg_type'=>$msgType,'user_id'=>$userID,'comment_id'=>$commentID,'reply_comment_id'=>$replyCommentID,'reply_user_id'=>$replyUserID,'game_id'=>$gameID,'is_read'=>0,'created_at'=>date('Y-m-dH:i:s'),]);returntrue;}这里在Model中定义setTable方法获取子表:publicfunctionsetTable($table){$this->table=$table;return$this;}从错误日志中发现$this->table没有生效,但实际上在调用create方法之前打印表名时,是期望值。为什么这里调用create方法时$this->table不起作用?被重置怎么办?这里$this->message是一个模型类,继承了Model类,其中create方法:publicstaticfunctioncreate(array$attributes=[]){$model=newstatic($attributes);$模型->保存();return$model;}位于vendorlavelframeworksrcIlluminateDatabaseEloquentModel.php557行。由于Laravel框架的Model类是一个抽象类型,PHP中的抽象类可以通过newstatic后期静态绑定来实例化,而$model=newstatic($attributes)在create方法中其实是重新实例化返回的,但是调用者Model类没有定义table属性,所以此时$this->table没有值。解决方法是使用save方法,如图。实际上create方法也调用了save方法。实验一个抽象类A,它有一个create方法,通过延迟静态绑定来实例化和返回。B类继承自A,在测试方法中修改了父类的name属性。name="TonyTan";返回$这个;}}$obj1=(newB)->test();$obj2=(newB)->test()->create();var_dump($obj1);var_dump($obj2);结果显示,$obj1和$obj2的实例都是B的实例,调用test方法时属性name发生了变化,但是调用create方法后name属性没有发生变化。这就是本文提到的Lavarel遇到的场景。(这里如果开启了注释,打印出来的名字就是重写后的值。)如果把抽象类A改成普通类,把newstatic改成newself,结果就不一样了。打印的属性名称是各自的类属性。
