感觉好长时间没写东西了,一方面主要是自己的角色发生了变化,每天要面对各种各样的事情和突发事件,不能再有一个完整的长时间让自己静下来写代码,或者写文章。

另一方面现在公司技术栈不再停留在只有 Laravel + VUE 了,我们还有小程序、APP 等开发,所以我关注的东西也就多了。

接下来我还是会继续持续「高产」,把写技术文章当作一个习惯,坚持下去。

好了,废话不多说,今天来说一说「Eloquent: 修改器」。

一直想好好研究下 Eloquent。但苦于 Eloquent 有太多可研究的,无法找到一个切入点。前两天看一同事好像对这个「Eloquent: 修改器」了解不多,所以今天就拿它作为入口,扒一扒其实现源代码。

首先还是拿一个 Demo 为例:

Demo

<?php
namespace App\Models; use Illuminate\Database\Eloquent\Model;
use Carbon\Carbon; class Baby extends Model
{
protected $table = 'baby';
protected $appends = ['age']; public function getAgeAttribute()
{
$date = new Carbon($this->birthday);
return Carbon::now()->diffInYears($date);
}
}

这个代码比较简单,就是通过已有属性 birthday,计算 Baby 几岁了,得到 age 属性。

前端就可以直接拿到结果:

return $baby->age;

同样的,还有 setXxxAttribute 方法来定义一个修改器。

源代码

读代码还是从使用入手,如上通过 $baby->age 调用 age 属性,这个属性没在类中定义,所以只能通过 PHP 的魔术方法 __get() 调用了。

我们看看 Model 类的 __get() 方法:

/**
* Dynamically retrieve attributes on the model.
*
* @param string $key
* @return mixed
*/
public function __get($key)
{
return $this->getAttribute($key);
}

好了,我们开始解读源代码了:

/**
* Get an attribute from the model.
*
* @param string $key
* @return mixed
*/
public function getAttribute($key)
{
if (! $key) {
return;
} // If the attribute exists in the attribute array or has a "get" mutator we will
// get the attribute's value. Otherwise, we will proceed as if the developers
// are asking for a relationship's value. This covers both types of values.
if (array_key_exists($key, $this->attributes) ||
$this->hasGetMutator($key)) {
return $this->getAttributeValue($key);
} ...
}

重点自然就在第二个 if 上,主要判断 attributes 数组中是否包含该属性,如果没有,则会执行函数 $this->hasGetMutator($key)

/**
* Determine if a get mutator exists for an attribute.
*
* @param string $key
* @return bool
*/
public function hasGetMutator($key)
{
return method_exists($this, 'get'.Str::studly($key).'Attribute');
}

这就对上了我们的 Demo 中自定义的函数 getAgeAttribute(),也就返回 true 了。

接下来就是执行函数 $this->getAttributeValue($key),进而执行函数:return $this->mutateAttribute($key, $value);

/**
* Get the value of an attribute using its mutator.
*
* @param string $key
* @param mixed $value
* @return mixed
*/
protected function mutateAttribute($key, $value)
{
return $this->{'get'.Str::studly($key).'Attribute'}($value);
}

好了,到此我们基本就知道了获取自定义 Attribute 的流程了。

相信解析 set XxxAttribute 也是很简单的。

总结

好长时间没写东西了,先从最简单的入手,练练手。解析 Eloquent 需要费很多脑细胞,接下来的一段时间我会围绕着这个主题好好研究下去,尽可能的全部解读一遍::

```.
|____Capsule
| |____Manager.php
|____composer.json
|____Concerns
| |____BuildsQueries.php
| |____ManagesTransactions.php
|____Connection.php
|____ConnectionInterface.php
|____ConnectionResolver.php
|____ConnectionResolverInterface.php
|____Connectors
| |____ConnectionFactory.php
| |____Connector.php
| |____ConnectorInterface.php
| |____MySqlConnector.php
| |____PostgresConnector.php
| |____SQLiteConnector.php
| |____SqlServerConnector.php
|____Console
| |____Factories
| | |____FactoryMakeCommand.php
| | |____stubs
| | | |____factory.stub
| |____Migrations
| | |____BaseCommand.php
| | |____FreshCommand.php
| | |____InstallCommand.php
| | |____MigrateCommand.php
| | |____MigrateMakeCommand.php
| | |____RefreshCommand.php
| | |____ResetCommand.php
| | |____RollbackCommand.php
| | |____StatusCommand.php
| |____Seeds
| | |____SeedCommand.php
| | |____SeederMakeCommand.php
| | |____stubs
| | | |____seeder.stub
|____DatabaseManager.php
|____DatabaseServiceProvider.php
|____DetectsDeadlocks.php
|____DetectsLostConnections.php
|____Eloquent
| |____Builder.php
| |____Collection.php
| |____Concerns
| | |____GuardsAttributes.php
| | |____HasAttributes.php
| | |____HasEvents.php
| | |____HasGlobalScopes.php
| | |____HasRelationships.php
| | |____HasTimestamps.php
| | |____HidesAttributes.php
| | |____QueriesRelationships.php
| |____Factory.php
| |____FactoryBuilder.php
| |____JsonEncodingException.php
| |____MassAssignmentException.php
| |____Model.php
| |____ModelNotFoundException.php
| |____QueueEntityResolver.php
| |____RelationNotFoundException.php
| |____Relations
| | |____BelongsTo.php
| | |____BelongsToMany.php
| | |____Concerns
| | | |____InteractsWithPivotTable.php
| | | |____SupportsDefaultModels.php
| | |____HasMany.php
| | |____HasManyThrough.php
| | |____HasOne.php
| | |____HasOneOrMany.php
| | |____MorphMany.php
| | |____MorphOne.php
| | |____MorphOneOrMany.php
| | |____MorphPivot.php
| | |____MorphTo.php
| | |____MorphToMany.php
| | |____Pivot.php
| | |____Relation.php
| |____Scope.php
| |____SoftDeletes.php
| |____SoftDeletingScope.php
|____Events
| |____ConnectionEvent.php
| |____QueryExecuted.php
| |____StatementPrepared.php
| |____TransactionBeginning.php
| |____TransactionCommitted.php
| |____TransactionRolledBack.php
|____Grammar.php
|____Migrations
| |____DatabaseMigrationRepository.php
| |____Migration.php
| |____MigrationCreator.php
| |____MigrationRepositoryInterface.php
| |____Migrator.php
| |____stubs
| | |____blank.stub
| | |____create.stub
| | |____update.stub
|____MigrationServiceProvider.php
|____MySqlConnection.php
|____PostgresConnection.php
|____Query
| |____Builder.php
| |____Expression.php
| |____Grammars
| | |____Grammar.php
| | |____MySqlGrammar.php
| | |____PostgresGrammar.php
| | |____SQLiteGrammar.php
| | |____SqlServerGrammar.php
| |____JoinClause.php
| |____JsonExpression.php
| |____Processors
| | |____MySqlProcessor.php
| | |____PostgresProcessor.php
| | |____Processor.php
| | |____SQLiteProcessor.php
| | |____SqlServerProcessor.php
|____QueryException.php
|____README.md
|____Schema
| |____Blueprint.php
| |____Builder.php
| |____Grammars
| | |____ChangeColumn.php
| | |____Grammar.php
| | |____MySqlGrammar.php
| | |____PostgresGrammar.php
| | |____RenameColumn.php
| | |____SQLiteGrammar.php
| | |____SqlServerGrammar.php
| |____MySqlBuilder.php
| |____PostgresBuilder.php
| |____SQLiteBuilder.php
| |____SqlServerBuilder.php
|____Seeder.php
```

参考

未完待续

来源:https://segmentfault.com/a/1190000017778043

Eloquent: 修改器的更多相关文章

  1. 访问器 & 修改器

    访问器 model /** * 定义一个访问器 当 Eloquent 尝试获取 title 的值时,将会自动调用此访问器(查詢時自動調用) * @author jackie <2019.02.1 ...

  2. laravel 访问器 和修改器的使用

    对于访问器我是这样定义的,就是将数据库中的数据被访问时可以变成我们想要的数据类型(例如:数据库中的时间字段是int类型,要将她变成data(Y-m-d H:i:s),格式类型) 参看博客 https: ...

  3. CE修改器修改DNF 测试视频 阿修罗提升智力增加攻击力

    使用CE修改器来修改网络游戏,如DNF 测试视频: CE修改器:指的是Cheat Engine,字面上的意思指的是作弊引擎的意思,是一款内存修改编辑工具.通过修改游戏的内存数据来得到一些原本无法实现的 ...

  4. tp5 中 model 的修改器

    修改器可以在数据赋值的时候自动进行转换处理 class User extends Model { public function setNameAttr($value){ return strtolo ...

  5. Blender 之修改器代码分析

                           Blender的修改器(modifier)模块,默认界面右下块(Property)面板的扳手,分类(修改.生成.形变.模拟)列出所有的修改器.也可以空格键 ...

  6. mongodb的修改器

    在mongodb中通常文档只会有一部分要更新,利用原子的更新修改器,可以做到只更新文档的一部分键值,而且更新极为高效,更新修改器是种特殊的键,用来指定复杂的更新操作,比如调整.增加.或者删除键,还可以 ...

  7. 【MongoDB】4.MongoDB 原子修改器的 极速修改

    文档转自:http://blog.csdn.net/mcpang/article/details/7752736 对于文档的更新除替换外,针对某个或多个文档只需要部分更新可使用原子的更新修改器,能够高 ...

  8. MongoDB修改器的使用1

    为什么要使用修改器?     通常我们只会修改文档的一部分,这时候更新整个文档就显得很麻烦,通常是通过原子性的更新修改器来完成. 1."$set"修改器    "$set ...

  9. UWP游戏防内存修改器的方法

    最近我一直在编写适用于Windows 10商店的游戏.这款游戏比较怕玩家用修改器改金钱,因为这种修改会导致某些内购失效并且损害公平性.于是我把自己见过的三种反修改器的方法给网友们介绍一下. 首先说明一 ...

随机推荐

  1. List 去重操作

    list集合的去重操作 List<string> listCatalogID = list.Select(a=>a.CatalogID).Distinct().ToList(); 代 ...

  2. jquery-fullpage插件

    jquery fullpage.js全屏滚动插件/jquery-easing插件 // 前端自动化工具安装插件 在页面引入: <link rel="stylesheet" h ...

  3. (九)JavaScript之【JS函数(定义、参数、调用、【闭包】、call(),apply())】[较深,胆小勿进]

    一].定义: /** * 函数表达式 * * Function() 构造函数 * * 函数提升(Hoisting) * JavaScript默认将当前作用域提升到前面去 * Hoisting应用在变量 ...

  4. APK加固之静态脱壳机编写入门

    目录: 0x00APK加固简介与静态脱壳机的编写思路 1.大家都知道Android中的程序反编译比较简单,辛苦开发出一个APK轻易被人反编译了,所以现在就有很多APK加固的第三方平台,比如爱加密和梆梆 ...

  5. ArcGIS API for JavaScript开发初探——基本地图组件使用

    1.前言 在上一篇我们已经我们已经讲述了第一个地图应用程序的HelloMap的创建过程,这一篇我们来讲述基本地图组件:Home Button.比例尺.鹰眼图的使用方法. 2.基本地图组件 在ArcGI ...

  6. dell omsa管理工具

    dell服务器raid管理工具 lsiutil dell sas6i/r MegaCli dell prec omsa管理raid分区 显示物理硬盘信息 omreport storage pdisk ...

  7. 由Asp.Net客户端控件生成的服务器端控件

    由Asp.Net客户端控件生成的服务器端控件(也就是给客户端控件添加 runnat="server"),这样的控件既能在js中通过id命.类名获取到,也能在服务器端根据id获取到

  8. Jetty服务器的使用

    Jetty 是一个开源的servlet容器,它为基于Java的web容器,例如JSP和servlet提供运行环境.Jetty是使用Java语言编写的,它的API以一组JAR包的形式发布.开发人员可以将 ...

  9. Servlet是线程安全的吗?

    Servlet不是线程安全的. 要解释为什么Servlet为什么不是线程安全的,需要了解Servlet容器(即Tomcat)使如何响应HTTP请求的. 当Tomcat接收到Client的HTTP请求时 ...

  10. Win10桌面右键响应非常慢怎么办?

    Win10桌面右键响应非常慢怎么办? 或许所有人升级到Win10都可能会遇上一个共同问题,右键桌面弹出菜单的反应非常非常的慢,你也感觉到了吧.在桌面点个右键需要等待五六秒左右的时间,这到底是不是系统问 ...