热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

浅谈Laravel中的一个后期静态绑定

关于 PHP  的 new static 延迟静态绑定,或者叫后期静态绑定,在 Laravel 中遇到一个使用上的问题。如下,在

关于 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 是没有值的。

解决办法是用 save 方法即可,如图所示。实际上 create 方法也调用了 save 方法。

实验

一个抽象类 A,有个 create 方法,通过延迟静态绑定实例化并返回。B 类继承 A,test 方法中修改父类的 name 属性。

<&#63;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:后期静态绑定

PHP中new self()和new static()的区别 

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。


推荐阅读
  • 然而并不是裁员的裁员,没裁员的正在准备裁员的路上.再加上一些人年终奖也已经骗到手了,依据优良传统,年后正是很多人辞职奔向更好的骗工资岗位的高峰期.所以,如何编简历(注意是编,不是 ... [详细]
  • 包含phpci中国怎么样的词条
    包含phpci中国怎么样的词条 ... [详细]
  • 后盾网lavarel视频项目Laravel 安装代码智能提示扩展「laravelidehelper」
    后盾网lavarel视频项目---Laravel安装代码智能提示扩展「laravel-ide-helper」一、总结一句话总结:laravel-ide-helper作 ... [详细]
  • lavarel  mongo 操作
    本人使用环境  Ubuntu18.04LTSphp7.2lavarel5.5mongodb的安装mongodb服务的安装  这个链接中有最全面最新的安装文档https:docs.m ... [详细]
  • 如何解决《带有file_get_contents的附件?》经验,为你挑选了1个好方法。 ... [详细]
  • 小编给大家分享一下yii和laravel的区别,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面 ... [详细]
  • Laravel提供了很多辅助函数,有时候我们也需要创建自己的辅助函数。必须把所有的『自定义辅助函数』存放于bootstrap文件夹中。并在bootstrapapp.php文件的 ... [详细]
  • 傻瓜式apt-get安装的php不支持phpthreads,搜索好久得到的答案是:使用源码编译安装。下面开始:1.下载php源码和phpthread源码,然后解压.使用的ph ... [详细]
  • php现在一般用什么数据库可以这么说,php之所以强大就是因为数据库,当然还有其他的用处,php和mysql数据库连接一起就成为了目前最好的组合我们叫lamp,比如你注册的用户名密 ... [详细]
  • Laravel提供了很多辅助函数,有时候我们也需要创建自己的辅助函数。必须把所有的『自定义辅助函数』存放于bootstrap文件夹中。并在bootstrapapp.php文件的 ... [详细]
  • 怎么在php的lavarel框架中添加类
    今天小编给大家分享一下怎么在php的lavarel框架中添加类的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇 ... [详细]
  • 系统环境要求PHP>5.5.9OpenSSLPHPExtensionPDOPHPExtensionMbstringPHPExtensionTokenizerPHP ... [详细]
  • Laravel9曾经公布,最新Release有许多个性,比方最低要求PHPv8.0、控制器路由组、全新的谬误页面、Scout数据库引擎、全新的邮件组件集成、Flysystem3.x、数据库存取晋升等。 ... [详细]
  • 黑马lavarel教程---1、lavarel目录结构一、总结一句话总结:一套视频讲的东西太少,要看多套视频1、安装lavarel需要额外开启的模块?extensionph ... [详细]
  • Ajax提交表单数据的几种方式方式一手工收集所有的用户输入,封装为大的“k1v1&k2v2…”键值对形式,使用$.post(url,data,fn把数据提交给服务器$.ajax ... [详细]
author-avatar
因为梦想2013
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有