Laravel中如何優雅地使用幫助類文件 helpers.php

舒適提示:篇幅較長,閱讀須要5-10分鐘。php

需求

        一個比較完善的表中基本上都會有type,status字段,來區分類型和狀態,如今的問題就是當api接口返回數據後,前端人員根本不知道你返回的type或者status字段是什麼意思,以前的作法是用if流程語句判斷,將status=1手動轉換成「啓用」,status=2轉換成「禁用」(剛入門的時候我就是這麼作的)。前端

        這樣的話,是否是很複雜呢?既然複雜,那麼就改進它,咱們能夠加一個type_str說明字段,來講明type中數字所表示的含義,同理,咱們給status配備一個status_str。ok,解決辦法有了,可是若是直接加在數據庫的話,又很不方便,因此咱們要借用一下helpers.phplaravel

實現步驟詳解

建立constants.php

這是一個自定義常量配置文件,路徑在config/constants.php,咱們在裏面定義咱們的常量:數據庫

<?php
return [
    'APP_NAME' => 'my project',
    'APP_URL'=> '你的域名',

    'USER_TYPE' => [
        1 => '代理商',
        2 => '分銷商',
		3 => '普通用戶',
    ],
複製代碼

你們能夠看到,我定義了一個USER_TYPE常量,爲何叫這個名字呢,下面會解釋。json

配置helpers.php文件

首先建立咱們的幫助類文件並編輯,路徑爲app/helpers.php
<?php
    if (!function_exists('constants')) {
        function constants(string $constName, $trans = false) {

            $config = config('constants.' . strtoupper($constName));

            if ($trans === false) {
                return $config;
            }
            if ($trans === 'label') {
                return array2label($config);
            }

        }
    }

   if (!function_exists('array2label')) {
        function array2label(array $arr) {
            $ret = [];

            foreach ($arr as $key => $item) {
                $ret[] = ['label' => $item, 'value' => $key];
            }
            return $ret;
        }
    }
複製代碼

來稍微解釋一下,我這裏定義了一個constants函數,他的做用是當咱們傳入參數時,經過config輔助函數從constants配置文件裏面獲取相應的值,完整的流程會在最後說明。api

將helpers.php加入到composer自動加載中
//將files添加到autoload"autoload": {
        "files": [
            "app/helpers.php",
        ],
        "classmap": [
            "app/Libraries",
            "database/seeds",
            "database/factories"
        ],
        "psr-4": {
            "App\\": "app/"
        }
    },
複製代碼
最後執行命令
composer dump-autoload
複製代碼

在模型Model中追加字段

基本配置到這裏就差很少了,咱們在model中追加type_str字段。數組

protected $appends = ['type_str'];
複製代碼

而後給type_str「賦值」,這裏不太懂的能夠查看文檔 追加json值bash

public function getTypeStrAttribute()
    {
        return array_get(constants( 'USER_TYPE'), $this->getAttribute('type'));
    }
複製代碼

這裏調用了以前在helpers.php中定義好的constants函數,array_get方法使用」.「號從嵌套數組中獲取值,固然也不必定用array_get,也能夠用其餘。app

繼續完善,使用trait實現代碼重用

到上一步,咱們的需求基本上就實現了。可是,我一個項目裏大約有10多張表使用到了type以及status字段,每一個模型中都寫這麼一段代碼,不太符合優雅的概念,因此完善過程當中又使用到了traitcomposer

關於trait,它是爲相似 PHP 的單繼承語言而準備的一種代碼複用機制,具體能夠參閱PHP文檔

建立trait文件並編輯

路徑在app/Traits/TypeTrait.php

<?php

namespace App\Traits;


trait TypeTrait
{
    public function getTypeStrAttribute()
    {
        return array_get(constants(class_basename(static::class) . '_TYPE'), $this->getAttribute('type'));
    }
}
複製代碼
使用trait

回到咱們Model模型,追加字段不變,可是不用再進行「賦值」操做了,只需:

use TypeTrait;
 
 protected $appends = ['type_str'];
複製代碼

還記得上面挖的坑爲何要命名爲USER_TYPE嗎?就是爲這裏作鋪墊的,仔細看TypeTrait.php文件,class_basename的做用是返回給定類刪除命名空間的類名,好比在uesr模型中它返回的就是user,這樣就方便咱們代碼的複用。

完整的步驟

可能有人看到這裏仍是有些迷糊,你說了半天這究竟是咋用的。讓咱們一塊兒走一遍流程(按照代碼進行流程):

  1. User控制器調用查詢方法,使用toArray()返回接口須要的字段。

  2. 查詢的時候就經過User模型查詢數據,使用的同時就追加了type_str字段,這個字段不是數據表中有的,而是咱們臨時添加上去的,因此咱們須要定義它的值。

  3. 因而User模型調用了TypeTrait.php中的getTypeStrAttribute()方法,這個方法有三層嵌套:

    3.1 最裏面的是class_basename返回給定類刪除命名空間的類名,若是咱們是經過User模型調用的就是User,而後使用「.」拼接了字符串,最後獲得的是User_TYPE。

    3.2 中間的一層,constants函數接收到了咱們的參數「User_TYPE」,strtoupper將「User_TYPE「所有轉換爲大寫字符,經過config在自定義常量配置文件constants.php中取值,返回一個USER_TYPE數組

    3.3 回到 getTypeStrAttribute()方法,最外面一層經過array_get匹配出type字段相對應的說明文字並返回,

  4. 這樣給追加字段賦值就成功了。

結束語:一共用了兩個小時完成,修修改改了三遍,可能仍是會有一些細小的紕漏,若是有什麼問題,歡迎評論指正,或者也能夠糾錯改正!

相關文章
相關標籤/搜索