浅谈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中的正规表达式(二)
Oct 09 PHP
php数组函数序列之rsort() - 对数组的元素值进行降序排序
Nov 02 PHP
php数据库配置文件一般做法分享
Jul 07 PHP
PHP APC的安装与使用详解
Jun 13 PHP
php 利用socket发送HTTP请求(GET,POST)
Aug 24 PHP
常见PHP数据库解决方案分析介绍
Sep 24 PHP
深入解析WordPress中加载模板的get_template_part函数
Jan 11 PHP
php实现微信扫码自动登陆与注册功能
Sep 22 PHP
关于 Laravel Redis 多个进程同时取队列问题详解
Dec 25 PHP
PHP实现将base64编码字符串转换成图片示例
Jun 22 PHP
php日志函数error_log用法实例分析
Sep 23 PHP
php-fpm超时时间设置request_terminate_timeout资源问题分析
Sep 27 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之密码加密的几种方式
2015/07/29 PHP
PHP模板引擎Smarty之配置文件在模板变量中的使用方法示例
2016/04/11 PHP
thinkPHP5框架中widget的功能与用法详解
2018/06/11 PHP
php7 新增功能实例总结
2020/05/25 PHP
用javascript实现计算两个日期的间隔天数
2007/08/14 Javascript
javascript关于open.window子页面执行完成后刷新父页面的问题分析
2015/04/27 Javascript
JS实现的简洁二级导航菜单雏形效果
2015/10/13 Javascript
js实现继承的5种方式
2015/12/01 Javascript
jQuery实现可兼容IE6的淡入淡出效果告警提示功能示例
2017/09/20 jQuery
微信小程序首页的分类功能和搜索功能的实现思路及代码详解
2018/09/11 Javascript
VUE2.0 ElementUI2.0表格el-table自适应高度的实现方法
2018/11/28 Javascript
浅谈Angular单元测试总结
2019/03/22 Javascript
Vue Render函数原理及代码实例解析
2020/07/30 Javascript
[01:15:15]VG VS EG Supermajor小组赛B组胜者组第一轮 BO3第二场 6.2
2018/06/03 DOTA
python实现数通设备tftp备份配置文件示例
2014/04/02 Python
采用python实现简单QQ单用户机器人的方法
2014/07/03 Python
基础的十进制按位运算总结与在Python中的计算示例
2016/06/28 Python
Python+selenium实现自动循环扔QQ邮箱漂流瓶
2018/05/29 Python
JSON文件及Python对JSON文件的读写操作
2018/10/07 Python
django drf框架自带的路由及最简化的视图
2019/09/10 Python
Python 基于wxpy库实现微信添加好友功能(简洁)
2019/11/29 Python
Python3实现mysql连接和数据框的形成(实例代码)
2020/01/17 Python
解决Python 异常TypeError: cannot concatenate 'str' and 'int' objects
2020/04/08 Python
Python 改变数组类型为uint8的实现
2020/04/09 Python
python openssl模块安装及用法
2020/12/06 Python
New Balance英国官方网站:始于1906年,百年慢跑品牌
2016/12/07 全球购物
蒂芙尼澳大利亚官方网站:Tiffany&Co. Australia
2017/08/27 全球购物
西海岸男士和男童服装:Johnnie-O
2018/03/15 全球购物
英国在线定做百叶窗网站:Make My Blinds
2020/08/17 全球购物
国际贸易专业个人求职信范文分享
2013/12/14 职场文书
中英文自我评价语句
2013/12/20 职场文书
公司端午节活动方案
2014/02/04 职场文书
志愿者工作心得体会
2016/01/15 职场文书
z-index不起作用
2021/03/31 HTML / CSS
如何利用JavaScript实现二叉搜索树
2021/04/02 Javascript
php访问对象中的成员的实例方法
2021/11/17 PHP