浅谈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 相关文章推荐
解决dede生成静态页和动态页转换的一些问题,及火车采集入库生成动态的办法
Mar 29 PHP
第二章 PHP入门基础之php代码写法
Dec 30 PHP
php使用qr生成二维码的示例分享
Jan 20 PHP
CodeIgniter CLI模式简介
Jun 17 PHP
将FCKeditor导入PHP+SMARTY的实现方法
Jan 15 PHP
php+mysql结合Ajax实现点赞功能完整实例
Jan 30 PHP
php上传文件问题汇总
Jan 30 PHP
PHP读取汉字的点阵数据
Jun 22 PHP
php 使用redis锁限制并发访问类示例
Nov 02 PHP
PHP 7.1新特性的汇总介绍
Dec 16 PHP
Yii框架弹出窗口组件CJuiDialog用法分析
Jan 07 PHP
PHP hex2bin()函数用法讲解
Feb 25 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
跟我学Laravel之安装Laravel
2014/10/15 PHP
让AJAX不依赖后端接口实现方案
2012/12/03 Javascript
Raphael带文本标签可拖动的图形实现代码
2013/02/20 Javascript
jQuery function的正确书写方法
2013/08/02 Javascript
解决jQuery uploadify在非IE核心浏览器下无法上传
2015/08/05 Javascript
javascript中类的定义方式详解(四种方式)
2015/12/22 Javascript
js判断图片加载完成后获取图片实际宽高的方法
2016/02/25 Javascript
基于Bootstrap里面的Button dropdown打造自定义select
2016/05/30 Javascript
JavaScript“尽快失败”的原则实例详解
2016/10/08 Javascript
JavaScript基于对象去除数组重复项的方法
2016/10/09 Javascript
webpack公共组件引用路径简化小技巧
2018/06/15 Javascript
jQuery实现的简单手风琴效果示例
2018/08/29 jQuery
解决vue-cli项目webpack打包后iconfont文件路径的问题
2018/09/01 Javascript
详解适配器在JavaScript中的体现
2018/09/28 Javascript
微信小程序 textarea 层级过高问题简单解决方案
2019/10/14 Javascript
JS eval代码快速解密实例解析
2020/04/23 Javascript
JavaScript常用工具函数库汇总
2020/09/17 Javascript
基于JavaScript实现简单扫雷游戏
2021/01/02 Javascript
详解Python中的动态属性和特性
2018/04/07 Python
python lxml中etree的简单应用
2019/05/10 Python
python 发送邮件的示例代码(Python2/3都可以直接使用)
2020/12/03 Python
加拿大领先的冒险和户外零售商:Atmosphere
2017/12/19 全球购物
印度尼西亚值得信赖的第一家网店:Bhinneka
2018/07/16 全球购物
ECCO英国官网:丹麦鞋履品牌
2019/09/03 全球购物
Fanatics官网:运动服装、球衣、运动装备
2020/10/12 全球购物
银行实习自我鉴定
2013/10/12 职场文书
预备党员思想汇报范文
2013/12/29 职场文书
高中自我评价范文
2014/01/27 职场文书
部队万能检讨书
2014/02/20 职场文书
聘任书的写作格式及范文
2014/03/29 职场文书
幼儿园清明节活动总结
2014/07/04 职场文书
党的群众路线教育实践活动个人整改措施材料
2014/11/04 职场文书
大学毕业论文致谢词
2015/05/14 职场文书
2019自荐信该如何写呢?
2019/07/05 职场文书
2019奶茶店创业计划书范本!
2019/07/15 职场文书
Python中使用tkFileDialog实现文件选择、保存和路径选择
2022/05/20 Python