浅谈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作的文本留言本的例子(二)
Oct 09 PHP
如何开发一个虚拟域名系统
Oct 09 PHP
php面向对象全攻略 (七) 继承性
Sep 30 PHP
浅谈php中mysql与mysqli的区别分析
Jun 10 PHP
php记录代码执行时间(实现代码)
Jul 05 PHP
php定义数组和使用示例(php数组的定义方法)
Mar 29 PHP
PHP定时更新程序设计思路分享
Jun 10 PHP
php连接oracle数据库的核心步骤
May 26 PHP
php解决DOM乱码的方法示例代码
Nov 20 PHP
使用一个for循环将N*N的二维数组的所有值置1实现方法
May 29 PHP
PHP常用函数之获取汉字首字母功能示例
Oct 21 PHP
PHP dirname简单使用代码实例
Nov 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程序中使用Rust扩展的方法
2015/07/03 PHP
深入浅析用PHP实现MVC
2016/03/02 PHP
FireFox JavaScript全局Event对象
2009/06/14 Javascript
分页栏的web标准实现
2011/11/01 Javascript
javascript获得服务器端控件的ID的实现代码
2011/12/28 Javascript
jquery实现微博文字输入框 输入时显示输入字数 效果实现
2013/07/12 Javascript
js实现文字在按钮上滚动的方法
2015/08/20 Javascript
jQuery实现鼠标滑过图片移动特效
2016/12/08 Javascript
老生常谈的跨域处理
2017/01/11 Javascript
详解Angular的8个主要构造块
2017/06/20 Javascript
React学习笔记之列表渲染示例详解
2017/08/22 Javascript
vue小图标favicon不显示的解决方案
2017/09/19 Javascript
jquery ajax异步提交表单数据的方法
2017/10/27 jQuery
使用vue-router beforEach实现判断用户登录跳转路由筛选功能
2018/06/25 Javascript
js防抖函数和节流函数使用场景和实现区别示例分析
2020/04/11 Javascript
关于Vue中$refs的探索浅析
2020/11/05 Javascript
[52:44]VGJ.T vs infamous Supermajor小组赛D组败者组第一轮 BO3 第一场 6.3
2018/06/04 DOTA
python基础教程之对象和类的实际运用
2014/08/29 Python
python搭建微信公众平台
2016/02/09 Python
Python之re操作方法(详解)
2017/06/14 Python
Python反射和内置方法重写操作详解
2018/08/27 Python
对Python中for复合语句的使用示例讲解
2018/11/01 Python
浅谈pandas筛选出表中满足另一个表所有条件的数据方法
2019/02/08 Python
Python 程序报错崩溃后如何倒回到崩溃的位置(推荐)
2020/06/23 Python
python 中的9个实用技巧,助你提高开发效率
2020/08/30 Python
CSS3常用的几种颜色渐变模式总结
2016/11/18 HTML / CSS
泰国第一在线超市:Tops
2021/02/13 全球购物
领导证婚人证婚词
2014/01/13 职场文书
业务总经理岗位职责
2014/02/03 职场文书
《小山羊和小灰兔》教学反思
2014/02/19 职场文书
信息学院毕业生自荐信范文
2014/03/04 职场文书
车队司机个人自我鉴定
2014/04/17 职场文书
导游词之塘栖古镇
2019/12/04 职场文书
PyTorch的Debug指南
2021/05/07 Python
Spring Cloud Gateway去掉url前缀
2021/07/15 Java/Android
Win11 Dev 预览版25174.1000发布 (附更新修复内容汇总)
2022/08/05 数码科技