半個小時搞定Laravel目錄結構與設定

2022-02-15 19:00:39
本篇文章給大家帶來了Laravel目錄結構與設定的相關知識,Laravel的目錄結構相對來說在初始狀態下會更豐富一些,除了傳統的控制器之外,也幫我們準備好了指令碼、中介軟體之類的程式碼檔案的目錄,基本上是可以達到上手直接使用的,希望對大家有幫助。

Laravel 目錄結構與設定

Laravel 的目錄結構相對來說在初始狀態下會更豐富一些,除了傳統的控制器之外,也幫我們準備好了指令碼、中介軟體之類的程式碼檔案的目錄,基本上是可以達到上手直接使用的。

目錄結構

首先我們來看一看根目錄都有什麼。

fed7288dbb8d359b500ad6e14ad56004.png

其實根據名字就能知道這些目錄的作用,比如說 app 目錄是具體的應用程式碼。config 目錄是存放組態檔資訊的。在上篇文章中,我們提到過如果在虛擬機器器中使用 Laravel 的話,是需要用到 server.php 這個根目錄下的檔案的,其實這個檔案就是在根目錄下載入了 public/index.php 這個檔案。

bootstrap 是在啟動框架的時候需要載入的檔案,一般不太會修改這個檔案裡面的內容,在這個目錄下還包含 cache 相關的目錄檔案。database 很明顯是資料庫相關的內容。public 就是我們框架的入口目錄,另外一些資原始檔也可以放在這裡,比如直接顯示的圖片、靜態檔案之類的。resources 存放的是檢視和未編譯的資原始檔。

routes 目錄是路由檔案所存放的目錄,這個目錄很重要,當然,其實也就是這裡面的路由檔案很重要。它裡面預設包含 web.php 、api.php 、channels.php 以及 console.php ,分別代表預設的 web 請求路由、api 請求路由、註冊事件廣播以及基於閉包的控制檯指令碼命令。

storage 目錄是用於儲存應用程式生成的各類檔案,包括快取、紀錄檔等資訊。tests 目錄包含自動化測試相關的內容。

在這些目錄中,我們再重點看一下 app 目錄中包含的內容。

e1b12e66a7a124a5e97559c8ffa0a1a4.png

app 目錄是我們應用開發中使用最多的目錄。我們應用的控制器、模型、中介軟體之類的內容都在這個目錄中。

Console 目錄是我們寫的命令列指令碼目錄,也就是可以自定義的通過 php artisan 執行的命令列功能都在這個目錄中。

Exceptions 是我們可以自定義的異常類。Models 中存放我們自定義的資料模型。Providers 目錄中存放的是預設的以及我們可以自定義的一些服務提供者。

接下來是 Http 目錄。

Controllers 不用多說了,控制器都寫在這裡。Middleware 放的是預設的中介軟體,當然,我們自定義的中介軟體也可以寫在這個目錄裡面。

Kernel.php 是請求核心的控制檔案,在這個檔案中,我們可以定義請求的中介軟體。這也是一個非常重要的核心檔案,將來學習到的時候我們再詳細的講解說明。

組態檔

關於目錄結構的內容其實就是上面這些,接下來我們再來看看組態檔也就是根目錄下 config 目錄裡面的內容,這裡面的內容也是我們經常需要接觸到的。

3eb904759f464ddae25744fbfdbed8dc.png

其實從這些組態檔的名字就可以看出它們的作用。在接下來的文章中我們馬上就要接觸到的就是 database.php 這個檔案,因為在入門相關的內容中,我們還是要簡單地連下資料庫體驗一下的。

在 database.php 中,不僅可以定義要連線的 mysql 資料庫資訊,也可以定義要連線的 NoSQL 型別的資料庫(預設已經給了 redis 的連線設定)。我們這裡先看下 MySQL 連線資訊。

'mysql' => [
    'driver' => 'mysql',
    'url' => env('DATABASE_URL'),
    'host' => env('DB_HOST', '127.0.0.1'),
    'port' => env('DB_PORT', '3306'),
    'database' => env('DB_DATABASE', 'forge'),
    'username' => env('DB_USERNAME', 'forge'),
    'password' => env('DB_PASSWORD', ''),
    'unix_socket' => env('DB_SOCKET', ''),
    'charset' => 'utf8mb4',
    'collation' => 'utf8mb4_unicode_ci',
    'prefix' => '',
    'prefix_indexes' => true,
    'strict' => true,
    'engine' => null,
    'options' => extension_loaded('pdo_mysql') ? array_filter([
        PDO::MYSQL_ATTR_SSL_CA => env('MYSQL_ATTR_SSL_CA'),
    ]) : [],
],

通過組態檔程式碼,我們可以看到很多資訊都是通過 env() 這個函數獲取的。而這個函數獲取到的內容其實是根目錄下的 .env 這個檔案裡面的內容。開啟這個 .env 檔案,我們可以看到它和 php.ini 檔案的設定方式是相似的,都是 key=value 這種形式的設定資訊。

DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=laravel
DB_USERNAME=root
DB_PASSWORD=

在這裡,我們就可以設定當前環境下的資料庫連線資訊。這樣設定有什麼好處呢?

獨立的組態檔這種形式的很容易實現設定中心,也很容易實現測試環境和正式環境的分別部署。一般我們不會將這個 .env 放到 git 中,或者跟隨程式碼上傳。在正式環境或者測試環境都是手動地或者通過設定中心來進行設定。這樣的話,我們就不需要修改原始碼,只需要使用不同的這個 .env 組態檔就可以實現不同的環境下執行相同的程式碼了。

通過 XDebug ,我們可以追蹤到 env() 這個方法在底層呼叫了 vlucas 的 DotEnv 這個 Composer 元件來進行 PHPENV 型別檔案的讀寫載入。

對於載入來說,在程式執行的時候,我們會通過下面這段程式碼來進行載入。

// laravel/framework/src/Illuminate/Foundation/Application.php
foreach ($bootstrappers as $bootstrapper) {
    $this['events']->dispatch('bootstrapping: '.$bootstrapper, [$this]);

    $this->make($bootstrapper)->bootstrap($this);

    $this['events']->dispatch('bootstrapped: '.$bootstrapper, [$this]);
}

其中核心是 $this->make($bootstrapper)->bootstrap($this); 這一段,它在迴圈中會載入所有 $bootstrappers 陣列中的內容,這個陣列裡面的內容是在 laravel/framework/src/Illuminate/Foundation/Http/Kernel.php 中的類變數 $bootstrappers 所定義的。第一個環境變數啟動載入器就是我們載入組態檔所需要的,如下所示:

// laravel/framework/src/Illuminate/Foundation/Http/Kernel.php
/**
 * The bootstrap classes for the application.
 *
 * @var string[]
 */
protected $bootstrappers = [
    \Illuminate\Foundation\Bootstrap\LoadEnvironmentVariables::class,
    \Illuminate\Foundation\Bootstrap\LoadConfiguration::class,
    \Illuminate\Foundation\Bootstrap\HandleExceptions::class,
    \Illuminate\Foundation\Bootstrap\RegisterFacades::class,
    \Illuminate\Foundation\Bootstrap\RegisterProviders::class,
    \Illuminate\Foundation\Bootstrap\BootProviders::class,
];

原始碼中和程式碼中的 Bootstrap 相關的內容都是啟動載入器的實現,從檔名就可以看出,這個啟動載入器是載入環境變數相關內容的。.env 檔案裡面的設定資訊也將是以整體的環境變數的形式載入到系統中。

// laravel/framework/src/Illuminate/Foundation/Bootstrap/LoadEnvironmentVariables.php
$this->createDotenv($app)->safeLoad();

LoadEnvironmentVariables.php 中會通過上述程式碼進入到 DotEnv 元件中,通過以下方法讀取組態檔相關的資訊。

// vlucas/phpdotenv/src/Dotenv.php
create() 

// vlucas/phpdotenv/src/Loader/Loader.php 
load()

最後通過 ServerConstAdapter.php 檔案中的 write() 方法將這些組態檔中的資訊寫入到 $_SERVER 全域性變數陣列中。

//vlucas/phpdotenv/src/Repository/Adapter/ServerConstAdapter.php 
/**
 * Write to an environment variable, if possible.
 *
 * @param string $name
 * @param string $value
 *
 * @return bool
 */
public function write(string $name, string $value)
{
    $_SERVER[$name] = $value;

    return true;
}

在路由檔案中,我們可以通過列印 \$_SERVER 資料看到組態檔裡面我們設定過的資訊。之後的讀取,也直接是讀取這個 $_SERVER 中的資料。

Route::get('/', function () {
    var_dump($_SERVER);

    var_dump(env('REDIS_PASSWORD')); // null
    $_SERVER['REDIS_PASSWORD'] = '123456';
    var_dump(env('REDIS_PASSWORD')); // string '123456'
    
    return view('welcome');
});

其實反過來看,我們的 Laravel 就是將 .env 檔案中的資料快取到了全域性變數 $_SERVER ,然後我們在將來使用的時候就直接從全域性變數中獲取就可以了,這樣就可以避免下一次還要從檔案讀取,從而提高系統效率。

總結

一開始以為就是簡單地講講目錄和組態檔,沒想到吧,直接就進入原始碼的分析了。當然,這只是開胃菜而已。對於框架架構的學習,一定要設定好 XDebug 之類的偵錯工具,如果沒這些工具,這種使用了許多 Composer 元件來回撥用的程式碼還真不好找出最終實現的地方。

後面的文章也都會以這樣的方式進行,需要注意的是,我們的原始碼都是在 vendor 目錄下的,所以有的文章中這個路徑我就沒有寫了。

【相關推薦:】

以上就是半個小時搞定Laravel目錄結構與設定的詳細內容,更多請關注TW511.COM其它相關文章!