浅谈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入门学习笔记之一
Oct 12 PHP
关于初学PHP时的知识积累总结
Jun 07 PHP
php中过滤非法字符的具体实现
Oct 29 PHP
php实现memcache缓存示例讲解
Dec 04 PHP
laravel 4安装及入门图文教程
Oct 29 PHP
PHP中iconv函数转码时截断字符问题的解决方法
Jan 21 PHP
php ImageMagick windows下安装教程
Jan 26 PHP
php实现在服务器上创建目录的方法
Mar 16 PHP
使用纯php代码实现页面伪静态的方法
Jul 25 PHP
从性能方面考虑PHP下载远程文件的3种方法
Dec 29 PHP
分享PHP-pcntl 实现多进程代码
Sep 30 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
wordpress之wp-settings.php
2007/08/17 PHP
php socket方式提交的post详解
2008/07/19 PHP
PHP编程最快明白(第一讲 软件环境和准备工作)
2010/10/25 PHP
windows下配置php5.5开发环境及开发扩展
2014/12/25 PHP
Centos7安装swoole扩展操作示例
2020/03/26 PHP
过虑特殊字符输入的js代码
2010/08/05 Javascript
基于jquery的一个OutlookBar类,动态创建导航条
2010/11/19 Javascript
js 实现 input type=&quot;file&quot; 文件上传示例代码
2013/08/07 Javascript
jquery将一个表单序列化为一个对象的方法
2014/01/03 Javascript
Bootstrap每天必学之栅格系统(布局)
2015/11/25 Javascript
jQuery Validate插件实现表单强大的验证功能
2015/12/18 Javascript
Javascript实现的SHA-256加密算法完整实例
2016/02/02 Javascript
限制复选框最多选择项的实现代码
2016/05/30 Javascript
AngularJS通过$location获取及改变当前页面的URL
2016/09/23 Javascript
原生js获取浏览器窗口及元素宽高常用方法集合
2017/01/18 Javascript
原生JS实现不断变化的标签
2017/05/22 Javascript
基于Vue渲染与插件的加载顺序的问题详解
2018/03/05 Javascript
vue中子组件向父组件传递数据的实例代码(实现加减功能)
2018/04/20 Javascript
[01:09:01]完美世界DOTA2联赛循环赛 Magma vs PXG BO2第一场 10.28
2020/10/28 DOTA
Python构造自定义方法来美化字典结构输出的示例
2016/06/16 Python
python算法演练_One Rule 算法(详解)
2017/05/17 Python
python基于TCP实现的文件下载器功能案例
2019/12/10 Python
Python递归函数特点及原理解析
2020/03/04 Python
基于Python和C++实现删除链表的节点
2020/07/06 Python
Python 处理日期时间的Arrow库使用
2020/08/18 Python
美国领先的汽车轮胎和轮毂供应商:TireBuyer
2016/07/21 全球购物
NYX Professional Makeup英国官网:美国平价专业彩妆品牌
2019/11/13 全球购物
俄罗斯金苹果网上化妆品和香水商店:Goldapple
2019/12/01 全球购物
法学专业个人求职信
2013/09/26 职场文书
自荐信封面
2013/12/04 职场文书
办公室内勤岗位职责范本
2013/12/09 职场文书
旷课检讨书3000字
2014/02/04 职场文书
七一讲话心得体会
2014/09/05 职场文书
2016年春节慰问信息大全
2015/11/30 职场文书
2019年家电促销广告语集锦
2019/10/21 职场文书
MySQL使用IF语句及用case语句对条件并结果进行判断 
2022/09/23 MySQL