浅谈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 07 PHP
几种显示数据的方法的比较
Oct 09 PHP
php中强制下载文件的代码(解决了IE下中文文件名乱码问题)
May 09 PHP
Sorting Array Values in PHP(数组排序)
Sep 15 PHP
用PHP解决的一个栈的面试题
Jul 02 PHP
php中字符查找函数strpos、strrchr与strpbrk用法
Nov 18 PHP
PHP中的一些常用函数收集
May 26 PHP
PHP+apc+ajax实现的ajax_upload上传进度条代码
Jan 25 PHP
PHP设计模式之原型设计模式原理与用法分析
Apr 25 PHP
PHP通过文件路径获取文件名的实例代码
Oct 14 PHP
Laravel基础-关于引入公共文件的两种方式
Oct 18 PHP
PHP 构造函数和析构函数原理与用法分析
Apr 21 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
收音机鉴频器对声音的影响和频偏分析
2021/03/02 无线电
自己动手做一个SQL解释器
2006/10/09 PHP
php创建多级目录代码
2008/06/05 PHP
php 论坛采集程序 模拟登陆,抓取页面 实现代码
2009/07/09 PHP
PHP获取MAC地址的具体实例
2013/12/13 PHP
Mac版PhpStorm之XAMPP整合apache服务器配置的图文教程详解
2016/10/13 PHP
PHP调用API接口实现天气查询功能的示例
2017/09/21 PHP
浅析PHP数据导出知识点
2018/02/17 PHP
prototype 1.5 &amp; scriptaculous 1.6.1 学习笔记
2006/09/07 Javascript
javascript中的括号()用法小结
2014/04/14 Javascript
使用cluster 将自己的Node服务器扩展为多线程服务器
2014/11/10 Javascript
JavaScript实现文字与图片拖拽效果的方法
2015/02/16 Javascript
jquery实现简洁文件上传表单样式
2015/11/02 Javascript
如何开发出更好的JavaScript模块
2017/12/22 Javascript
jQuery动态添加li标签并添加属性和绑定事件方法
2018/02/24 jQuery
Vue.js添加组件操作示例
2018/06/13 Javascript
微信小程序scroll-view仿拼多多横向滑动滚动条
2020/04/21 Javascript
详解react-refetch的使用小例子
2019/02/15 Javascript
vue-cli配置flexible过程详解
2019/07/04 Javascript
[03:30]完美盛典趣味短片 CSGO2019年度名场面
2019/12/07 DOTA
详解python之简单主机批量管理工具
2017/01/27 Python
Python利用itchat对微信中好友数据实现简单分析的方法
2017/11/21 Python
Python 实现删除某路径下文件及文件夹的实例讲解
2018/04/24 Python
浅析Python数据处理
2018/05/02 Python
python实现逆序输出一个数字的示例讲解
2018/06/25 Python
Python使用Selenium模块实现模拟浏览器抓取淘宝商品美食信息功能示例
2018/07/18 Python
详解python中的生成器、迭代器、闭包、装饰器
2019/08/22 Python
python+selenium select下拉选择框定位处理方法
2019/08/24 Python
使用python去除图片白色像素的实例
2019/12/12 Python
从训练好的tensorflow模型中打印训练变量实例
2020/01/20 Python
Python类成员继承重写的实现
2020/09/16 Python
纯CSS3大转盘抽奖示例代码(响应式、可配置)
2017/01/13 HTML / CSS
九年级家长会邀请函
2014/01/15 职场文书
党员干部廉洁承诺书
2014/05/28 职场文书
党员自评材料范文
2014/12/17 职场文书
Python函数对象与闭包函数
2022/04/13 Python