浅谈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在XP下IIS和Apache2服务器上的安装
Sep 05 PHP
PHP 防恶意刷新实现代码
May 16 PHP
php 智能404跳转代码,适合换域名没改变目录的网站
Jun 04 PHP
PHP 数据结构 算法描述 冒泡排序 bubble sort
Jul 10 PHP
PHP面向对象三大特点学习(充分理解抽象、封装、继承、多态)
May 07 PHP
PHP删除数组中的特定元素的代码
Jun 28 PHP
ThinkPHP中limit()使用方法详解
Apr 19 PHP
PHP正则表达式入门教程(推荐)
May 18 PHP
PHP关键特性之命名空间实例详解
May 06 PHP
PHP实现函数内修改外部变量值的方法示例
Dec 28 PHP
PHP实现PDO操作mysql存储过程示例
Feb 13 PHP
PHP常用字符串输出方法分析(echo,print,printf及sprintf)
Mar 09 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
一个域名查询的程序
2006/10/09 PHP
Ping服务的php实现方法,让网站快速被收录
2012/02/04 PHP
PHP基于接口技术实现简单的多态应用完整实例
2017/04/26 PHP
php实现session共享的实例方法
2019/09/19 PHP
a标签的css样式四个状态
2021/03/09 HTML / CSS
可输入的下拉框
2006/06/19 Javascript
JavaScript 对象、函数和继承
2009/07/07 Javascript
javascript instanceof,typeof的区别
2010/03/24 Javascript
JavaScript/jQuery 表单美化插件小结
2012/02/14 Javascript
JS实现跟随鼠标的链接文字提示框效果
2015/08/06 Javascript
jquery表单验证需要做些什么
2015/11/17 Javascript
浅析jQuery移动开发中内联按钮和分组按钮的编写
2015/12/04 Javascript
JavaScript新增样式规则(推荐)
2016/07/19 Javascript
nodejs根据ip数组在百度地图中进行定位
2017/03/06 NodeJs
JavaScript事件方法(实例讲解)
2017/06/27 Javascript
捕获未处理的Promise错误方法
2017/10/13 Javascript
vue组件name的作用小结
2018/05/23 Javascript
JS构造一个html文本内容成文件流形式发送到后台
2018/07/31 Javascript
[42:32]Secret vs Optic 2018国际邀请赛小组赛BO2 第二场 8.18
2018/08/19 DOTA
用python删除java文件头上版权信息的方法
2014/07/31 Python
python字符串与url编码的转换实例
2018/05/10 Python
解决pycharm工程启动卡住没反应的问题
2019/01/19 Python
python3对接mysql数据库实例详解
2019/04/30 Python
虚拟机下载python是否需要联网
2020/07/27 Python
Python正则re模块使用步骤及原理解析
2020/08/18 Python
Python数据分析库pandas高级接口dt的使用详解
2020/12/11 Python
pyx文件 生成pyd 文件用于 cython调用的实现
2021/03/04 Python
移动Web—CSS为Retina屏幕替换更高质量的图片
2012/12/24 HTML / CSS
HTML5之SVG 2D入门1—SVG(可缩放矢量图形)概述
2013/01/30 HTML / CSS
Java中有几种方法可以实现一个线程?用什么关键字修饰同步方法?stop()和suspend()方法为何不推荐使用?
2015/08/04 面试题
英文导游欢迎词
2014/01/11 职场文书
本科毕业生自荐信
2014/05/26 职场文书
全国法制宣传日活动总结2014
2014/11/01 职场文书
《和时间赛跑》读后感3篇
2019/12/16 职场文书
浅谈MySQL user权限表
2021/06/18 MySQL
python如何将mat文件转为png
2022/07/15 Python