php學(xué)習(xí)Eloquent修改器源碼示例解析
引言
感覺好長(zhǎng)時(shí)間沒寫東西了,一方面主要是自己的角色發(fā)生了變化,每天要面對(duì)各種各樣的事情和突發(fā)事件,不能再有一個(gè)完整的長(zhǎng)時(shí)間讓自己靜下來寫代碼,或者寫文章。
另一方面現(xiàn)在公司技術(shù)棧不再停留在只有 Laravel + VUE 了,我們還有小程序、APP 等開發(fā),所以我關(guān)注的東西也就多了。
接下來我還是會(huì)繼續(xù)持續(xù)「高產(chǎn)」,把寫技術(shù)文章當(dāng)作一個(gè)習(xí)慣,堅(jiān)持下去。
好了,廢話不多說,今天來說一說「Eloquent: 修改器
」。
一直想好好研究下 Eloquent。但苦于 Eloquent 有太多可研究的,無法找到一個(gè)切入點(diǎn)。前兩天看一同事好像對(duì)這個(gè)「Eloquent: 修改器
」了解不多,所以今天就拿它作為入口,扒一扒其實(shí)現(xiàn)源代碼。
首先還是拿一個(gè) 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); } }
這個(gè)代碼比較簡(jiǎn)單,就是通過已有屬性 birthday
,計(jì)算 Baby 幾歲了,得到 age
屬性。
前端就可以直接拿到結(jié)果:
return $baby->age;
同樣的,還有 setXxxAttribute
方法來定義一個(gè)修改器。
源代碼
讀代碼還是從使用入手,如上通過 $baby->age
調(diào)用 age
屬性,這個(gè)屬性沒在類中定義,所以只能通過 PHP 的魔術(shù)方法 __get()
調(diào)用了。
我們看看 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); } ... }
重點(diǎn)自然就在第二個(gè) if
上,主要判斷 attributes
數(shù)組中是否包含該屬性,如果沒有,則會(huì)執(zhí)行函數(shù) $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'); }
這就對(duì)上了我們的 Demo
中自定義的函數(shù) getAgeAttribute()
,也就返回 true
了。
接下來就是執(zhí)行函數(shù) $this->getAttributeValue($key)
,進(jìn)而執(zhí)行函數(shù):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
也是很簡(jiǎn)單的。
總結(jié)
好長(zhǎng)時(shí)間沒寫東西了,先從最簡(jiǎn)單的入手,練練手。解析 Eloquent
需要費(fèi)很多腦細(xì)胞,接下來的一段時(shí)間我會(huì)圍繞著這個(gè)主題好好研究下去,盡可能的全部解讀一遍::
. |____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: 修改器 http://www.dbjr.com.cn/article/177489.htm
- __get()使用說明 http://php.net/manual/zh/language.oop5.overloading.php#object.get
以上就是php學(xué)習(xí)Eloquent修改器源碼示例解析的詳細(xì)內(nèi)容,更多關(guān)于php Eloquent修改器的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
yii2實(shí)現(xiàn)分頁,帶搜索的分頁功能示例
本篇文章主要介紹了yii2實(shí)現(xiàn)分頁,帶搜索的分頁功能示例,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下。2017-01-01thinkPHP自動(dòng)驗(yàn)證機(jī)制詳解
這篇文章主要介紹了thinkPHP自動(dòng)驗(yàn)證機(jī)制,結(jié)合實(shí)例形式分析了thinkPHP自動(dòng)驗(yàn)證機(jī)制的格式、原理與具體操作技巧,需要的朋友可以參考下2016-12-12codeigniter自帶數(shù)據(jù)庫(kù)類使用方法說明
在 CodeIgniter 中,使用數(shù)據(jù)庫(kù)是非常頻繁的事情。你可以使用框架自帶的數(shù)據(jù)庫(kù)類,就能便捷地進(jìn)行數(shù)據(jù)庫(kù)操作2014-03-03thinkphp5.1 文件引入路徑問題及注意事項(xiàng)
這篇文章主要介紹了thinkphp5.1 文件引入路徑問題,本文給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2018-06-06PHP中使用substr()截取字符串出現(xiàn)中文亂碼問題該怎么辦
本文給大家介紹使用php substr()截取字符串出現(xiàn)亂碼問題該怎么辦,涉及到php substr()方法的一些知識(shí)點(diǎn),感興趣的朋友一起學(xué)習(xí)下吧2015-10-10關(guān)于js和php對(duì)url編碼的處理方法
這篇文章主要介紹了關(guān)于js和php對(duì)url編碼的處理方法,需要的朋友可以參考下2014-03-03