Eloquent: 修改器

原作者:coding01 原文链接:https://juejin.im/post/5c309ee66fb9a04a0d570020


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

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

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

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

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

首先还是拿一个 Demo 为例:

Demo

namespace App\Models;


use Illuminate\Database\Eloquent\Model;

use Carbon\Carbon;


class BabyextendsModel

{

    protected$table ='baby';

    protected$appends = ['age'];


    publicfunctiongetAgeAttribute()

    {

        $date =newCarbon($this->birthday);

        returnCarbon::now()->diffInYears($date);

    }

}

复制代码

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

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

return $baby->age;

复制代码

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

源代码

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

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

/**

 * Dynamically retrieve attributeson the model.

 *

 *@param  string  $key

 *@return mixed

 */

publicfunction__get($key)

{

    return$this->getAttribute($key);

}

复制代码

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

/**

 * Get an attribute from the model.

 *

 *@param  string  $key

 *@return mixed

 */

publicfunctiongetAttribute($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 existsfor an attribute.

 *

 *@param  string  $key

 *@return bool

 */

publicfunctionhasGetMutator($key)

{

    returnmethod_exists($this,'get'.Str::studly($key).'Attribute');

}

复制代码

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

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

/**

 * Get the value of an attributeusing its mutator.

 *

 *@param  string  $key

 *@param  mixed  $value

 *@return mixed

 */

protectedfunctionmutateAttribute($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

你可能感兴趣的:(Eloquent: 修改器)