浅谈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 相关文章推荐
用libTemplate实现静态网页的生成
Oct 09 PHP
PHP的栏目导航程序
Oct 09 PHP
PHP实现分页的一个示例
Oct 09 PHP
PHP 出现乱码和Sessions验证问题的解决方法!
Dec 06 PHP
php strlen mb_strlen计算中英文混排字符串长度
Jul 10 PHP
php google或baidu分页代码
Nov 26 PHP
学习php笔记 字符串处理
Oct 19 PHP
php实现的返回数据格式化类实例
Sep 22 PHP
经典PHP加密解密函数Authcode()修复版代码
Apr 05 PHP
PHP中的类型提示(type hinting)功能介绍
Jul 01 PHP
学习php设计模式 php实现适配器模式
Dec 07 PHP
php简单检测404页面的方法示例
Aug 23 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
使用迭代器 遍历文件信息的详解
2013/06/08 PHP
PHP文件操作实例总结
2016/09/27 PHP
Laravel学习教程之IOC容器的介绍与用例
2017/08/15 PHP
javascript flash下fromCharCode和charCodeAt方法使用说明
2008/01/12 Javascript
JS 密码强度验证(兼容IE,火狐,谷歌)
2010/03/15 Javascript
javascript最常用与实用的创建类的代码
2010/08/12 Javascript
jQuery powerFloat万能浮动层下拉层插件使用介绍
2010/12/27 Javascript
Jquery中显示隐藏的实现代码分析
2011/07/26 Javascript
jquery ajax传递中文参数乱码问题及解决方法说明
2014/02/07 Javascript
JQuery实现动态表格点击按钮表格增加一行
2014/08/24 Javascript
引用其它js时如何同时处理多个window.onload事件
2014/09/02 Javascript
javascript实现checkbox全选的代码
2015/04/30 Javascript
JS实现窗口加载时模拟鼠标移动的方法
2015/06/03 Javascript
jQuery实现带滚动导航效果的全屏滚动相册实例
2015/06/19 Javascript
JS中动态创建元素的三种方法总结(推荐)
2016/10/20 Javascript
javascript 判断当前浏览器版本并判断ie版本
2017/02/17 Javascript
react-native ListView下拉刷新上拉加载实现代码
2017/08/03 Javascript
关于Promise 异步编程的实例讲解
2017/09/01 Javascript
js实现多张图片每隔一秒切换一张图片
2019/07/29 Javascript
Layui数据表格之单元格编辑方式
2019/10/26 Javascript
vue实现div可拖动位置也可改变盒子大小的原理
2020/09/16 Javascript
openlayers4.6.5实现距离量测和面积量测
2020/09/25 Javascript
[02:14]DOTA2英雄基础教程 修补匠
2013/12/23 DOTA
[01:00:14]DOTA2官方TI8总决赛纪录片 真视界True Sight
2019/01/16 DOTA
在Linux命令行终端中使用python的简单方法(推荐)
2017/01/23 Python
Python基于Flask框架配置依赖包信息的项目迁移部署
2018/03/02 Python
使用python Fabric动态修改远程机器hosts的方法
2018/10/26 Python
Python实现从SQL型数据库读写dataframe型数据的方法【基于pandas】
2019/03/18 Python
python3 图片 4通道转成3通道 1通道转成3通道 图片压缩实例
2019/12/03 Python
Python环境下安装PyGame和PyOpenGL的方法
2020/03/25 Python
用html5的canvas和JavaScript创建一个绘图程序的简单实例
2016/07/06 HTML / CSS
BrandAlley英国:法国折扣奢侈品网上零售商
2017/07/03 全球购物
如何高效率的查找一个月以内的数据
2012/04/15 面试题
《吃水不忘挖井人》教学反思
2014/04/15 职场文书
鸟的天堂导游词
2015/01/31 职场文书
python爬虫之利用selenium模块自动登录CSDN
2021/04/22 Python