浅谈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 相关文章推荐
关于BIG5-HKSCS的解决方法
Mar 20 PHP
php中转义mysql语句的实现代码
Jun 24 PHP
PHP中操作ini配置文件的方法
Apr 25 PHP
php获取json数据所有的节点路径
May 17 PHP
PHP计算日期相差天数实例分析
Feb 23 PHP
PHP简单获取网站百度搜索和搜狗搜索收录量的方法
Aug 23 PHP
PHP会话控制实例分析
Dec 24 PHP
php中请求url的五种方法总结
Jul 13 PHP
PHP中OpenSSL加密问题整理
Dec 14 PHP
php ActiveMQ的安装与使用方法图文教程
Feb 23 PHP
TP5框架实现的数据库备份功能示例
Apr 05 PHP
Thinkphp5框架异常处理操作实例分析
Jun 03 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
一个改进的UBB类
2006/10/09 PHP
php中经典方法实现判断多维数组是否为空
2011/10/23 PHP
解析百度搜索结果link?url=参数分析 (全)
2012/10/09 PHP
PHP把数字转成人民币大写的函数分享
2014/06/30 PHP
php一维二维数组键排序方法实例总结
2014/11/13 PHP
php实现评论回复删除功能
2017/05/23 PHP
CI框架(CodeIgniter)公共模型类定义与用法示例
2017/08/10 PHP
Javascript-Mozilla和IE中的一个函数直接量的问题分析
2007/08/12 Javascript
js实现右下角可关闭最小化div(可用于展示推荐内容)
2013/06/24 Javascript
js中的replace方法使用介绍
2013/10/28 Javascript
禁止按回车键提交表单的方法
2015/06/11 Javascript
JS动态添加选项案例分析
2016/10/17 Javascript
JS百度地图搜索悬浮窗功能
2017/01/12 Javascript
vue2.0父子组件及非父子组件之间的通信方法
2017/01/21 Javascript
jQuery实现的图片点击放大缩小功能案例
2020/01/02 jQuery
Vuejs中的watch实例详解(监听者)
2020/01/05 Javascript
使用python实现扫描端口示例
2014/03/29 Python
Python中用于去除空格的三个函数的使用小结
2015/04/07 Python
Python实现简单的文件传输与MySQL备份的脚本分享
2016/01/03 Python
Python编程scoketServer实现多线程同步实例代码
2018/01/29 Python
Django中的DateTimeField和DateField实现
2021/02/24 Python
Roxy美国官网:澳大利亚冲浪、滑雪健身品牌
2016/07/30 全球购物
世界上最大的折扣香水店:FragranceNet.com
2016/10/26 全球购物
适用于所有创业者的创业计划书
2014/02/05 职场文书
心理学专业大学生职业生涯规划范文
2014/02/19 职场文书
给全校老师的建议书
2014/03/13 职场文书
爱心捐助倡议书
2014/05/19 职场文书
理财学专业自荐书
2014/06/28 职场文书
2015年网络管理员工作总结
2015/05/21 职场文书
总经理聘用协议书
2015/09/21 职场文书
致毕业季:你如何做好自己的职业生涯规划书?
2019/07/01 职场文书
Keras在mnist上的CNN实践,并且自定义loss函数曲线图操作
2021/05/25 Python
Java中常用解析工具jackson及fastjson的使用
2021/06/28 Java/Android
Python 可迭代对象 iterable的具体使用
2021/08/07 Python
Pygame Rect区域位置的使用(图文)
2021/11/17 Python
排查并解决MySQL生产库内存使用率高的报警
2022/04/11 MySQL