Laravel 中的一个后期静态绑定

发布时间 - 2019-10-23 00:00:00    点击率:

关于 php 的 new static 延迟静态绑定,或者叫后期静态绑定,在 laravel 中遇到一个使用上的问题。如下,在 laravel 中调用 model 新增数据的时候,首先给 model 加了一个获取分表的方法:

protected function addToMessage($msgType, $userID, $commentID, $replyCommentID, $replyUserID, $gameID)
{
    if (!$userID) {
        return 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-d H:i:s'),
    ]);
    return true;
}

这里 setTable 方法是在 Model 里定义的获取分表的方法:

public function setTable($table)
{
    $this->table = $table;
    return $this;
}

从报错日志中发现 $this->table 并没有生效,但实际上在调用 create 方法之前打印表名的时候是期望的值,这里调用 create 方法为什么 $this->table 没有被重置呢?

这里 $this->message 是一个继承 Model 类的模型类,其中 create 方法:

public static function create(array $attributes = [])
{
    $model = new static($attributes);
 
    $model->save();
 
    return $model;
}

位于 vendorlaravelframeworksrcIlluminateDatabaseEloquentModel.php Line 557.

因为 Laravel 框架的这个 Model 类是一个 abstract 类型,PHP 中 abstract 类可以用 new static 后期静态绑定的方式实例化,而 create 方法里 $model = new static($attributes) 实际上就是重新实例化了并返回,而调用者 Model 类没有定义 table 属性,所以这个时候 $this->table 是没有值的。

解决办法是用 save 方法即可,如图所示。实际上 create 方法也调用了 save 方法。

实验

一个抽象类 A,有个 create 方法,通过延迟静态绑定实例化并返回。B 类继承 A,test 方法中修改父类的 name 属性。

name = "Tony Tan";
        return $this;
    }
}
 
$obj1 = (new B)->test();
$obj2 = (new B)->test()->create();
var_dump($obj1);
var_dump($obj2);

结果显示 $obj1 和 $obj2 这两个实例都是 B 的实例,调用 test 方法属性 name 改变了,但是调用 create 方法后,name 属性并没有改变。这也就是在本文中说的在 Lavarel 中遇到的场景。(这里如果把注释打开,打印的 name 就是重写的值)

如果把抽象类 A 改成普通类,new static 改成 new self 的方式实例化,结果就不同了,打印的属性 name 都是各自类的属性。

更多Laravel相关技术文章,请访问Laravel框架入门教程栏目进行学习!


# laravel  # php  # lavarel  # Static  # 父类  # 继承  # this  # table  # 绑定  # 都是  # 是一个  # 后期  # 是在  # 有个  # 抽象类  # 可以用  # 这也  # 这两个 


相关栏目: 【 网站优化151355 】 【 网络推广146373 】 【 网络技术251813 】 【 AI营销90571


相关推荐: 手机网站制作与建设方案,手机网站如何建设?  详解Android图表 MPAndroidChart折线图  Laravel如何处理异常和错误?(Handler示例)  网站制作公司哪里好做,成都网站制作公司哪家做得比较好,更正规?  nodejs redis 发布订阅机制封装实现方法及实例代码  Laravel如何从数据库删除数据_Laravel destroy和delete方法区别  微博html5版本怎么弄发超话_超话进入入口及发帖格式要求【教程】  Laravel如何实现本地化和多语言支持?(i18n教程)  Python文本处理实践_日志清洗解析【指导】  微信小程序 五星评分(包括半颗星评分)实例代码  如何在局域网内绑定自建网站域名?  如何为不同团队 ID 动态生成多个非值班状态按钮  Angular 表单中正确绑定输入值以确保提交与验证正常工作  利用 Google AI 进行 YouTube 视频 SEO 描述优化  如何用PHP快速搭建高效网站?分步指南  家族网站制作贴纸教程视频,用豆子做粘帖画怎么制作?  Python文件异常处理策略_健壮性说明【指导】  阿里云高弹*务器配置方案|支持分布式架构与多节点部署  进行网站优化必须要坚持的四大原则  太平洋网站制作公司,网络用语太平洋是什么意思?  实例解析angularjs的filter过滤器  ChatGPT 4.0官网入口地址 ChatGPT在线体验官网  如何在Windows服务器上快速搭建网站?  如何用花生壳三步快速搭建专属网站?  JS中页面与页面之间超链接跳转中文乱码问题的解决办法  Laravel如何部署到服务器_线上部署Laravel项目的完整流程与步骤  uc浏览器二维码扫描入口_uc浏览器扫码功能使用地址  UC浏览器如何设置启动页 UC浏览器启动页设置方法  详解免费开源的.NET多类型文件解压缩组件SharpZipLib(.NET组件介绍之七)  Laravel怎么实现一对多关联查询_Laravel Eloquent模型关系定义与预加载【实战】  Laravel怎么实现验证码功能_Laravel集成验证码库防止机器人注册  Laravel怎么实现API接口鉴权_Laravel Sanctum令牌生成与请求验证【教程】  制作旅游网站html,怎样注册旅游网站?  Laravel如何处理JSON字段_Eloquent原生JSON字段类型操作教程  PHP正则匹配日期和时间(时间戳转换)的实例代码  黑客如何通过漏洞一步步攻陷网站服务器?  C#如何调用原生C++ COM对象详解  Python结构化数据采集_字段抽取解析【教程】  HTML5空格和nbsp有啥关系_nbsp的作用及使用场景【说明】  Android中Textview和图片同行显示(文字超出用省略号,图片自动靠右边)  极客网站有哪些,DoNews、36氪、爱范儿、虎嗅、雷锋网、极客公园这些互联网媒体网站有什么差异?  Laravel如何操作JSON类型的数据库字段?(Eloquent示例)  Laravel如何集成Inertia.js与Vue/React?(安装配置)  javascript中的数组方法有哪些_如何利用数组方法简化数据处理  百度输入法ai组件怎么删除 百度输入法ai组件移除工具  Laravel任务队列怎么用_Laravel Queues异步处理任务提升应用性能  美食网站链接制作教程视频,哪个教做美食的网站比较专业点?  儿童网站界面设计图片,中国少年儿童教育网站-怎么去注册?  Laravel Docker环境搭建教程_Laravel Sail使用指南  如何安全更换建站之星模板并保留数据?