浅谈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+DBM的同学录程序(4)
Oct 09 PHP
php生成xml简单实例代码
Dec 16 PHP
PHPCMS的使用小结
Sep 20 PHP
mysql总结之explain
Feb 27 PHP
PHP仿博客园 个人博客(2) 数据库增添改删
Jul 05 PHP
修改PHP脚本使WordPress拦截垃圾评论的方法示例
Dec 10 PHP
PHP编写登录验证码功能 附调用方法
May 19 PHP
24条货真价实的PHP代码优化技巧
Jul 28 PHP
php使用crypt()函数进行加密
Jun 08 PHP
PHP memcache在微信公众平台的应用方法示例
Sep 13 PHP
解决Laravel 不能创建 migration 的问题
Oct 09 PHP
PHP 99乘法表的几种实现代码
Oct 13 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时区转换转换函数
2014/01/07 PHP
PHP中批量生成静态html(命令行下运行PHP)
2014/04/19 PHP
php监测数据是否成功插入到Mysql数据库的方法
2016/11/25 PHP
PHP实现按之字形顺序打印二叉树的方法
2018/01/16 PHP
浅谈PHP之ThinkPHP框架使用详解
2020/07/21 PHP
MC Dialog js弹出层 完美兼容多浏览器(5.6更新)
2010/05/06 Javascript
在浏览器中获取当前执行的脚本文件名的代码
2011/07/19 Javascript
如何使用Jquery获取Form表单中被选中的radio值
2013/08/09 Javascript
IE下Ajax缓存问题的快速解决方法(get方式)
2014/01/09 Javascript
深入浅出分析javaScript中this用法
2015/05/09 Javascript
JavaScript数组迭代器实例分析
2015/06/09 Javascript
Node.js读写文件之批量替换图片的实现方法
2016/09/07 Javascript
axios发送post请求springMVC接收不到参数的解决方法
2018/03/05 Javascript
JavaScript中十种一步拷贝数组的方法实例详解
2019/04/22 Javascript
jQuery子选择器与可见性选择器实例分析
2019/06/28 jQuery
JavaScript字符串处理常见操作方法小结
2019/11/15 Javascript
Vue.js原理分析之nextTick实现详解
2020/09/07 Javascript
Python入门篇之字典
2014/10/17 Python
Python和perl实现批量对目录下电子书文件重命名的代码分享
2014/11/21 Python
在windows系统中实现python3安装lxml
2016/03/23 Python
基于Django模板中的数字自增(详解)
2017/09/05 Python
PyCharm代码提示忽略大小写设置方法
2018/10/28 Python
python画环形图的方法
2020/03/25 Python
Python+Dlib+Opencv实现人脸采集并表情判别功能的代码
2020/07/01 Python
python使用多线程查询数据库的实现示例
2020/08/17 Python
sublime3之内网安装python插件Anaconda的流程
2020/11/10 Python
你正在寻找的CSS3 动画技术
2011/07/27 HTML / CSS
Europcar英国:英国汽车和货车租赁
2017/01/21 全球购物
美国宠物用品网站:Value Pet Supplies
2018/03/17 全球购物
西部世纪.net笔试题面试题
2014/04/03 面试题
函授毕业生的自我鉴定
2013/11/26 职场文书
教师评语大全
2014/04/28 职场文书
2014年职称评定工作总结
2014/11/26 职场文书
合理化建议书范文
2015/09/14 职场文书
职场新人刚入职工作总结该怎么写?
2019/05/15 职场文书
导游词之丹东鸭绿江
2019/10/24 职场文书