浅谈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 相关文章推荐
最令PHP初学者头痛的十四个问题
Jul 12 PHP
PHP聊天室技术
Oct 09 PHP
PHP学习 运算符与运算符优先级
Jun 15 PHP
一个php Mysql类 可以参考学习熟悉下
Jun 21 PHP
PHP执行zip与rar解压缩方法实现代码
Dec 05 PHP
纯php打造的tab选项卡效果代码(不用js)
Dec 29 PHP
Yii使用ajax验证显示错误messagebox的解决方法
Dec 03 PHP
PHP计算百度地图两个GPS坐标之间距离的方法
Jan 09 PHP
PHP扩展迁移为PHP7扩展兼容性问题记录
Feb 15 PHP
PHP实现转盘抽奖算法分享
Apr 15 PHP
PHP开发api接口安全验证操作实例详解
Mar 26 PHP
PHP dirname(__FILE__)原理及用法解析
Oct 28 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
网站当前的在线人数
2006/10/09 PHP
mysql,mysqli,PDO的各自不同介绍
2012/09/19 PHP
解析php扩展php_curl.dll不加载的解决方法
2013/06/26 PHP
php smarty truncate UTF8乱码问题解决办法
2014/06/13 PHP
推荐几款用 Sublime Text 开发 Laravel 所用到的插件
2014/10/30 PHP
laravel 解决多库下的DB::transaction()事务失效问题
2019/10/21 PHP
jQuery循环滚动展示代码 可应用到文字和图片上
2012/05/11 Javascript
js+xml生成级联下拉框代码
2012/07/24 Javascript
JavaScript判断文件上传类型的方法
2014/09/02 Javascript
jQuery中的一些常见方法小结(推荐)
2016/06/13 Javascript
JavaScript生成.xls文件的代码
2016/12/22 Javascript
Node.js 使用命令行工具检查更新
2017/06/08 Javascript
vue 使某个组件不被 keep-alive 缓存的方法
2018/09/21 Javascript
jQuery.validate.js表单验证插件的使用代码详解
2018/10/22 jQuery
微信小程序实现元素渐入渐出动画效果封装方法
2019/05/18 Javascript
详解将微信小程序接口Promise化并使用async函数
2019/08/05 Javascript
jQuery实现推拉门效果
2020/10/19 jQuery
[15:58]DOTA2国际邀请赛采访专栏:Tongfu.Sansheng&KingJ,DK.rOtk
2013/08/08 DOTA
[03:49]辉夜杯现场龙骑士COSER秀情商“我喜欢芬队!”
2015/12/27 DOTA
python 排列组合之itertools
2013/03/20 Python
Python中的对象,方法,类,实例,函数用法分析
2015/01/15 Python
在Python中使用第三方模块的教程
2015/04/27 Python
Python实现OpenCV的安装与使用示例
2018/03/30 Python
python下解压缩zip文件并删除文件的实例
2018/04/24 Python
Django 在iframe里跳转顶层url的例子
2019/08/21 Python
selenium+Chrome滑动验证码破解二(某某网站)
2019/12/17 Python
Python实现随机生成任意数量车牌号
2020/01/21 Python
Python实现获取当前目录下文件名代码详解
2020/03/10 Python
使用CSS3实现多列布局与多背景的技巧
2016/02/29 HTML / CSS
本科毕业生专业自荐书范文
2014/02/05 职场文书
大学生助学金感谢信
2015/01/21 职场文书
《小摄影师》教学反思
2016/02/18 职场文书
AJAX学习笔记
2021/05/18 Javascript
Pycharm 如何设置HTML文件自动补全代码或标签
2021/05/21 Python
Python实现灰色关联分析与结果可视化的详细代码
2022/03/25 Python
React四级菜单的实现
2022/04/08 Javascript