源码网,源码论坛,源码之家,商业源码,游戏源码下载,discuz插件,棋牌源码下载,精品源码论坛

 找回密码
 立即注册
楼主: ttx9n

[PHP编程] 浅谈Laravel中的一个后期静态绑定

[复制链接]

7万

主题

861

回帖

32万

积分

论坛元老

Rank: 8Rank: 8

积分
329525
发表于 2017-8-11 09:08:12 | 显示全部楼层 |阅读模式
本篇文章主要介绍了浅谈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 属性。

<?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()的区别 

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

回复

使用道具 举报

2

主题

2万

回帖

473

积分

中级会员

Rank: 3Rank: 3

积分
473
发表于 2022-9-8 22:54:59 | 显示全部楼层
管灌灌灌灌灌灌灌灌灌灌
回复 支持 反对

使用道具 举报

4

主题

1万

回帖

60

积分

注册会员

Rank: 2

积分
60
发表于 2022-12-20 13:31:18 | 显示全部楼层
的vgdsvsdvdsvdsvds
回复 支持 反对

使用道具 举报

1

主题

2万

回帖

69

积分

注册会员

Rank: 2

积分
69
发表于 2023-4-25 20:19:22 | 显示全部楼层
为全额万千瓦
回复 支持 反对

使用道具 举报

4

主题

2万

回帖

303

积分

中级会员

Rank: 3Rank: 3

积分
303
发表于 2023-6-20 04:34:00 | 显示全部楼层
vcxvcxv
回复 支持 反对

使用道具 举报

2

主题

2万

回帖

380

积分

中级会员

Rank: 3Rank: 3

积分
380
发表于 2023-9-17 12:58:34 | 显示全部楼层
看看怎么样再说
回复 支持 反对

使用道具 举报

0

主题

1万

回帖

0

积分

中级会员

Rank: 3Rank: 3

积分
0
发表于 2023-10-25 09:45:37 | 显示全部楼层
下载来瞧瞧
回复 支持 反对

使用道具 举报

2

主题

2万

回帖

73

积分

注册会员

Rank: 2

积分
73
发表于 2024-4-4 17:19:28 | 显示全部楼层
看看怎么样再说
回复 支持 反对

使用道具 举报

0

主题

2万

回帖

0

积分

中级会员

Rank: 3Rank: 3

积分
0
发表于 2024-5-28 07:54:40 | 显示全部楼层
谢谢分享,先下来用用
回复 支持 反对

使用道具 举报

4

主题

2万

回帖

303

积分

中级会员

Rank: 3Rank: 3

积分
303
发表于 2024-6-18 02:08:25 | 显示全部楼层
hi哦和烦恼农家女
回复 支持 反对

使用道具 举报

高级模式
B Color Image Link Quote Code Smilies

本版积分规则

手机版|小黑屋|网站地图|源码论坛 ( 海外版 )

GMT+8, 2025-2-7 16:16 , Processed in 0.068989 second(s), 23 queries .

Powered by Discuz! X3.4

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表