浅谈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实现用户认证及管理完全源码
Mar 11 PHP
认识并使用PHP超级全局变量
Jan 26 PHP
PHP 的ArrayAccess接口 像数组一样来访问你的PHP对象
Oct 12 PHP
php file_put_contents()功能函数(集成了fopen、fwrite、fclose)
May 24 PHP
解析php根据ip查询所在地区(非常有用,赶集网就用到)
Jul 01 PHP
ThinkPHP令牌验证实例
Jun 18 PHP
phpmyadmin出现Cannot start session without errors问题解决方法
Aug 14 PHP
浅析PHP7新功能及语法变化总结
Jun 17 PHP
微信利用PHP创建自定义菜单的方法
Aug 01 PHP
使用PHP+MySql实现微信投票功能实例代码
Sep 29 PHP
Laravel 在views中加载公共页面的实现代码
Oct 22 PHP
PHP7 foreach() 函数修改
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
mysql5写入和读出乱码解决
2006/11/25 PHP
php cookie 作用范围?不要在当前页面使用你的cookie
2009/03/24 PHP
PHP将DateTime对象转化为友好时间显示的实现代码
2011/09/20 PHP
php之Memcache学习笔记
2013/06/17 PHP
yii2使用gridView实现下拉列表筛选数据
2017/04/10 PHP
PHP中的函数声明与使用详解
2017/05/27 PHP
imagettftext() 失效,不起作用
2021/03/09 PHP
csdn 论坛技术区平均给分功能
2009/11/07 Javascript
jQuery 打造动态渐变按钮 详细图文教程
2010/04/25 Javascript
用js解决数字不能换行问题
2010/08/10 Javascript
javascript实现当前页导航激活的方法
2015/02/27 Javascript
理解JavaScript表单的基础知识
2016/01/25 Javascript
动态加载js、css的简单实现代码
2016/05/26 Javascript
js仿微博动态栏功能
2017/02/22 Javascript
AngularJS路由删除#符号解决的办法
2017/09/28 Javascript
用 Vue.js 递归组件实现可折叠的树形菜单(demo)
2017/12/25 Javascript
详解如何在JS代码中消灭for循环
2019/12/11 Javascript
nodejs中的异步编程知识点详解
2021/01/17 NodeJs
[54:19]完美世界DOTA2联赛PWL S2 Magma vs PXG 第二场 11.28
2020/12/01 DOTA
Python 3.x 判断 dict 是否包含某键值的实例讲解
2018/07/06 Python
Python读取csv文件分隔符设置方法
2019/01/14 Python
Python控制Firefox方法总结
2019/06/03 Python
bluepy 一款python封装的BLE利器简单介绍
2019/06/25 Python
python利用7z批量解压rar的实现
2019/08/07 Python
Python之time模块的时间戳,时间字符串格式化与转换方法(13位时间戳)
2019/08/12 Python
Python实现石头剪刀布游戏
2021/01/20 Python
美丽的珠宝配饰:SmallThings
2019/09/04 全球购物
计算机大学生的自我评价
2013/10/15 职场文书
证婚人搞笑证婚词
2014/01/10 职场文书
大学生最新职业生涯规划书范文
2014/01/12 职场文书
一个大学生十年的职业规划
2014/01/17 职场文书
幼儿园国庆节活动方案
2014/02/01 职场文书
2014年房产经纪人工作总结
2014/12/08 职场文书
酒店员工辞职信范文
2015/02/28 职场文书
2015年街道办事处团委工作总结
2015/10/14 职场文书
Vue Element plus使用方法梳理
2022/12/24 Vue.js