浅谈Laravel中的一个后期静态绑定


Posted in PHP onAugust 11, 2017

关于 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;
}

位于 vendor\laravel\framework\src\Illuminate\Database\Eloquent\Model.php Line 557.

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

浅谈Laravel中的一个后期静态绑定

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

实验

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

<?php
 
abstract class A
{
  protected $name = "tanteng";
 
  public static function create()
  {
    return new static();
  }
}
 
class B extends A
{
  //protected $name = '纸牌屋弗兰克';
 
  public function test()
  {
    $this->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 都是各自类的属性。

参考链接

PHP中new self()和new static()的区别 

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

PHP 相关文章推荐
PHP4实际应用经验篇(3)
Oct 09 PHP
一个PHP模板,主要想体现一下思路
Dec 25 PHP
PHP 文件缓存的性能测试
Apr 25 PHP
php中使用Imagick实现图像直方图的实现代码
Aug 30 PHP
PHP+MYSQL会员系统的登陆即权限判断实现代码
Sep 23 PHP
Thinkphp中的volist标签用法简介
Jun 18 PHP
Symfony2之session与cookie用法小结
Mar 18 PHP
PHP中的Trait 特性及作用
Apr 03 PHP
php安装扩展mysqli的实现步骤及报错解决办法
Sep 23 PHP
PHP时间戳和日期相互转换操作实例小结
Dec 18 PHP
微信支付之JSAPI公众号支付详解
May 15 PHP
php判断IP地址是否在多个IP段内
Aug 18 PHP
浅谈PHP中new self()和new static()的区别
Aug 11 #PHP
php使用 readfile() 函数设置文件大小大小的方法
Aug 11 #PHP
详解PHP使用日期时间处理器Carbon人性化显示时间
Aug 10 #PHP
PHP弱类型语言中类型判断操作实例详解
Aug 10 #PHP
CI框架(CodeIgniter)公共模型类定义与用法示例
Aug 10 #PHP
PHP实现驼峰样式字符串(首字母大写)转换成下划线样式字符串的方法示例
Aug 10 #PHP
基于PHP实现栈数据结构和括号匹配算法示例
Aug 10 #PHP
You might like
PHP5 操作MySQL数据库基础代码
2009/09/29 PHP
php学习笔记(三)操作符与控制结构
2011/08/06 PHP
yii实现图片上传及缩略图生成的方法
2014/12/04 PHP
php中引用&amp;的用法分析【变量引用,函数引用,对象引用】
2016/12/12 PHP
thinkphp ajaxfileupload实现异步上传图片的示例
2017/08/28 PHP
用正则表达式替换图片地址img标签
2013/11/22 Javascript
jQuery中parentsUntil()方法用法实例
2015/01/07 Javascript
实例详解jQuery结合GridView控件的使用方法
2016/01/04 Javascript
jQuery遍历节点树方法分析
2016/09/08 Javascript
Canvas 制作动态进度加载水球详解及实例代码
2016/12/09 Javascript
jQuery Validate验证框架详解(推荐)
2016/12/17 Javascript
纯js实现html转pdf的简单实例(推荐)
2017/02/16 Javascript
Vue.js实现网格列表布局转换方法
2017/08/25 Javascript
Vue中如何实现proxy代理
2018/04/20 Javascript
浅谈React的最大亮点之虚拟DOM
2018/05/29 Javascript
JavaScript常用数组操作方法,包含ES6方法
2020/05/10 Javascript
vue中引入mxGraph的步骤详解
2019/05/17 Javascript
Vee-validate 父组件获取子组件表单校验结果的实例代码
2019/05/20 Javascript
JS实现动态添加外部js、css到head标签的方法
2019/06/05 Javascript
vue-router 控制路由权限的实现
2020/09/24 Javascript
Python实现动态添加类的属性或成员函数的解决方法
2014/07/16 Python
Python使用minidom读写xml的方法
2015/06/03 Python
python的keyword模块用法实例分析
2015/06/30 Python
Django model序列化为json的方法示例
2018/10/16 Python
使用Python实现图像标记点的坐标输出功能
2019/08/14 Python
sklearn-SVC实现与类参数详解
2019/12/10 Python
Tensorflow中的降维函数tf.reduce_*使用总结
2020/04/20 Python
25个CSS3动画按钮和菜单教程分享
2012/10/03 HTML / CSS
用纯CSS3实现网页中常见的小箭头
2017/10/16 HTML / CSS
荷兰领先的百货商店:De Bijenkorf
2018/10/17 全球购物
《植物妈妈有办法》教学反思
2014/02/25 职场文书
大学生村官个人对照检查材料(群众路线)
2014/09/26 职场文书
企业反腐倡廉心得体会
2015/08/15 职场文书
教师节主题班会教案
2015/08/17 职场文书
优秀共产党员主要事迹材料
2015/11/05 职场文书
SQL Server使用T-SQL语句批处理
2022/05/20 SQL Server