浅谈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 相关文章推荐
一个ftp类(ini.php)
Oct 09 PHP
模拟OICQ的实现思路和核心程序(二)
Oct 09 PHP
php 格式化数字的时候注意数字的范围
Apr 13 PHP
php 获取本地IP代码
Jun 23 PHP
PHP的preg_match匹配字符串长度问题解决方法
May 03 PHP
PHP小教程之实现双向链表
Jun 12 PHP
php链表用法实例分析
Jul 09 PHP
ThinkPHP模型详解
Jul 27 PHP
PHP mysqli_free_result()与mysqli_fetch_array()函数详解
Sep 21 PHP
php+redis消息队列实现抢购功能
Feb 08 PHP
PHP实现上传图片到数据库并显示输出的方法
May 31 PHP
PHP中使用mpdf 导出PDF文件的实现方法
Oct 22 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
一个php作的文本留言本的例子(五)
2006/10/09 PHP
如何在PHP中使用Oracle数据库(4)
2006/10/09 PHP
php 数组二分法查找函数代码
2010/02/16 PHP
php的一些小问题
2010/07/03 PHP
PHP实现视频文件上传完整实例
2014/08/28 PHP
php数组冒泡排序算法实例
2016/05/06 PHP
PHP中使用foreach()遍历二维数组的简单实例
2016/06/13 PHP
PHP生成随机字符串实例代码(字母+数字)
2019/09/11 PHP
可以把编码转换成 gb2312编码lib.UTF8toGB2312.js
2007/08/21 Javascript
JavaScript 动态改变图片大小
2009/06/11 Javascript
jQuery 1.5.1 发布,全面支持IE9 修复大量bug
2011/02/26 Javascript
js中根据字数截取字符串,不能截断url
2012/01/12 Javascript
jquery制作LED 时钟特效
2015/02/01 Javascript
浅谈js中startsWith 函数不能在任何浏览器兼容的问题
2017/03/01 Javascript
微信小程序中遇到的iOS兼容性问题小结
2018/11/14 Javascript
浅谈Vue.js组件(二)
2019/04/09 Javascript
浅谈Vue的响应式原理
2019/05/30 Javascript
vue.js页面加载执行created,mounted的先后顺序说明
2020/11/07 Javascript
[01:00:14]DOTA2官方TI8总决赛纪录片 真视界True Sight
2019/01/16 DOTA
python网络编程学习笔记(七):HTML和XHTML解析(HTMLParser、BeautifulSoup)
2014/06/09 Python
浅谈python抛出异常、自定义异常, 传递异常
2016/06/20 Python
python ---lambda匿名函数介绍
2019/03/13 Python
tensorflow 自定义损失函数示例代码
2020/02/05 Python
如何利用python生成MD5并去重
2020/12/07 Python
简单介绍CSS3中Media Query的使用
2015/07/07 HTML / CSS
CSS3制作皮卡丘动画壁纸的示例
2020/11/02 HTML / CSS
我们没有写servlet的构造方法,那么容器是怎么创建servlet的实例呢
2013/04/24 面试题
个人实用简单的自我评价
2013/10/19 职场文书
预备党员思想汇报范文
2014/01/11 职场文书
小学红领巾中秋节广播稿
2014/01/13 职场文书
勤俭节约倡议书
2014/04/14 职场文书
养牛场项目建议书
2014/05/13 职场文书
党员承诺书范文2015
2015/04/27 职场文书
运动会入场词
2015/07/18 职场文书
tensorboard 可视化之localhost:6006不显示的解决方案
2021/05/22 Python
Sentry的安装、配置、使用教程(Sentry日志手机系统)
2022/07/23 Python