浅谈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 stream_context_create()作用和用法分析
Mar 29 PHP
php中处理mysql_fetch_assoc返回来的数组 不用foreach----echo
May 04 PHP
php实现邮件发送并带有附件
Jan 24 PHP
合并ThinkPHP配置文件以消除代码冗余的实现方法
Jul 22 PHP
PHP批量查询WordPress留言者E-mail地址实现方法
Feb 15 PHP
PHP使用CURL实现多线程抓取网页
Apr 30 PHP
详解Grunt插件之LiveReload实现页面自动刷新(两种方案)
Jul 31 PHP
初识ThinkPHP控制器
Apr 07 PHP
php实现基于pdo的事务处理方法示例
Jul 21 PHP
PHP使用栈解决约瑟夫环问题算法示例
Aug 27 PHP
phpcms实现验证码替换及phpcms实现全站搜索功能教程详解
Dec 13 PHP
laravel 解决路由除了根目录其他都404的问题
Oct 18 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 die()与exit()的区别实例详解
2016/12/03 PHP
php如何实现不借助IDE快速定位行数或者方法定义的文件和位置
2017/01/17 PHP
PHP排序算法之冒泡排序(Bubble Sort)实现方法详解
2018/04/20 PHP
ThinkPHP3.1.2 使用cli命令行模式运行的方法
2020/04/14 PHP
让人期待的2011年度最佳 jQuery 插件分享
2012/03/16 Javascript
JS中的prototype与面向对象的实例讲解
2013/05/22 Javascript
jquery实现简单实用的打分程序实例
2015/07/23 Javascript
Javascript获取数组中的最大值和最小值的方法汇总
2016/01/01 Javascript
angularjs实现文字上下无缝滚动特效代码
2016/09/04 Javascript
JS实现随机颜色的3种方法与颜色格式的转化
2017/01/05 Javascript
js/jquery控制页面动态加载数据 滑动滚动条自动加载事件的方法
2017/02/08 Javascript
微信小程序开发之map地图实现教程
2017/06/08 Javascript
vue左侧菜单,树形图递归实现代码
2018/08/24 Javascript
JavaScript时间日期操作实例小结【5个示例】
2018/12/22 Javascript
vue 重塑数组之修改数组指定index的值操作
2020/08/09 Javascript
[48:30]LGD vs infamous Supermajor小组赛D组 BO3 第一场 6.3
2018/06/04 DOTA
浅谈Python 字符串格式化输出(format/printf)
2016/07/21 Python
Python+django实现简单的文件上传
2016/08/17 Python
使用Django连接Mysql数据库步骤
2019/01/15 Python
使用Template格式化Python字符串的方法
2019/01/22 Python
Python逐行读取文件中内容的简单方法
2019/02/26 Python
python实现简易学生信息管理系统
2020/04/05 Python
Python OrderedDict的使用案例解析
2019/10/25 Python
TensorFlow自定义损失函数来预测商品销售量
2020/02/05 Python
python中使用input()函数获取用户输入值方式
2020/05/03 Python
python如何求100以内的素数
2020/05/27 Python
欧洲、亚洲、非洲和拉丁美洲的度假套餐:Great Value Vacations
2019/03/30 全球购物
在家更换处方镜片:Lensabl
2019/05/01 全球购物
英国豪华家具和家居用品购物网站:Teddy Beau
2020/10/12 全球购物
经销商培训邀请函
2014/01/21 职场文书
采购部经理岗位职责
2014/02/10 职场文书
2014年村委会工作总结
2014/11/24 职场文书
开会通知短信大全
2015/04/20 职场文书
焦点访谈观后感
2015/06/11 职场文书
Flask response响应的具体使用
2021/07/15 Python
MySQL中dd::columns表结构转table过程及应用详解
2022/09/23 MySQL