laravel version : 6.20.44
IDE : VsCode
程式碼追蹤元件 : "barryvdh/laravel-ide-helper": "2.8"
這篇分析圖片中的這一行程式碼
__construct
接收一個引數 $basePath
⌈應用的根路徑⌉,相對於 ~/bootstrap/app.php
則是 dirname(__DIR__)
__DIR__: D:\MyCode\study\laravel\laravel6\bootstrap
dirname(__DIR__): D:\MyCode\study\laravel\laravel6
回到 __construct
方法,第一行呼叫 $this->setBasePath($basePath);
,為了方便檢視,我把這行程式碼有關的程式碼單獨分離了出來放進偽 class 檔案裡
<?php
class Path
{
protected $basePath; //根路徑 D:\MyCode\study\laravel\laravel6
protected $appPath; // The custom application path defined by the developer.
protected $databasePath; // The custom database path defined by the developer.
protected $storagePath; // The custom storage path defined by the developer.
protected $environmentPath;// The custom environment path defined by the developer.
public function __construct($basePath = null)
{
if ($basePath) {
$this->setBasePath($basePath);
}
}
public function setBasePath($basePath)
{
$this->basePath = rtrim($basePath, '\/');
$this->bindPathsInContainer();
return $this;
}
protected function bindPathsInContainer()
{
$this->instance('path', $this->path());
$this->instance('path.base', $this->basePath());
$this->instance('path.lang', $this->langPath());
$this->instance('path.config', $this->configPath());
$this->instance('path.public', $this->publicPath());
$this->instance('path.storage', $this->storagePath());
$this->instance('path.database', $this->databasePath());
$this->instance('path.resources', $this->resourcePath());
$this->instance('path.bootstrap', $this->bootstrapPath());
}
public function path($path = '')
{
$appPath = $this->appPath ?: $this->basePath . DIRECTORY_SEPARATOR . 'app';
return $appPath . ($path ? DIRECTORY_SEPARATOR . $path : $path);
}
public function basePath($path = '')
{
return $this->basePath . ($path ? DIRECTORY_SEPARATOR . $path : $path);
}
public function langPath()
{
return $this->resourcePath() . DIRECTORY_SEPARATOR . 'lang';
}
public function configPath($path = '')
{
return $this->basePath . DIRECTORY_SEPARATOR . 'config' . ($path ? DIRECTORY_SEPARATOR . $path : $path);
}
public function publicPath()
{
return $this->basePath . DIRECTORY_SEPARATOR . 'public';
}
public function storagePath()
{
return $this->storagePath ?: $this->basePath . DIRECTORY_SEPARATOR . 'storage';
}
public function databasePath($path = '')
{
return ($this->databasePath ?: $this->basePath . DIRECTORY_SEPARATOR . 'database') . ($path ? DIRECTORY_SEPARATOR . $path : $path);
}
public function resourcePath($path = '')
{
return $this->basePath . DIRECTORY_SEPARATOR . 'resources' . ($path ? DIRECTORY_SEPARATOR . $path : $path);
}
public function bootstrapPath($path = '')
{
return $this->basePath . DIRECTORY_SEPARATOR . 'bootstrap' . ($path ? DIRECTORY_SEPARATOR . $path : $path);
}
public function useAppPath($path)
{
$this->appPath = $path;
$this->instance('path', $path);
return $this;
}
public function useStoragePath($path)
{
$this->storagePath = $path;
$this->instance('path.storage', $path);
return $this;
}
public function useDatabasePath($path)
{
$this->databasePath = $path;
$this->instance('path.database', $path);
return $this;
}
public function useEnvironmentPath($path)
{
$this->environmentPath = $path;
return $this;
}
}
分析
1. 定義了
$basePath
,$appPath
,$databasePath
,$storagePath
,$environmentPath
五個屬性
思考:除了 $basePath
,為什麼只定義這幾個目錄的屬性,而 resources
,config
路徑卻沒有定義屬性?我們發現屬性的註解寫著 The custom
,說明這幾個目錄路徑是允許自定義的。
2. 定義了
path($path = '')
,basePath($path = '')
,langPath()
,configPath($path = '')
,publicPath()
,storagePath()
,databasePath($path = '')
,resourcePath($path = '')
,bootstrapPath($path = '')
方法
一般情況下,在 $basePath
基礎上拼接成路徑,而允許自定義的屬性是這樣獲取的:
有的方法接收 $path=''
引數,有的卻沒有,不太理解,感覺沒什麼區別,以至於助手函式 helpers
中對是否接收 $path=''
引數的方法呼叫都不同:
有 $path=''
引數的:
if (! function_exists('database_path')) {
function database_path($path = '')
{
return app()->databasePath($path);
}
}
沒有 $path=''
引數的:
if (! function_exists('public_path')) {
function public_path($path = '')
{
return app()->make('path.public').($path ? DIRECTORY_SEPARATOR.ltrim($path, DIRECTORY_SEPARATOR) : $path);
}
}
if (! function_exists('storage_path')) {
function storage_path($path = '')
{
return app('path.storage').($path ? DIRECTORY_SEPARATOR.$path : $path);
}
}
有點意思,什麼寫法都有了
3. 將路徑透過 instance($abstract, $instance)
放進 $instances
屬性,列印 $instances
屬性:
array:9 [
"path" => "D:\MyCode\study\laravel\laravel6\app" //custom
"path.base" => "D:\MyCode\study\laravel\laravel6"
"path.lang" => "D:\MyCode\study\laravel\laravel6\resources\lang"
"path.config" => "D:\MyCode\study\laravel\laravel6\config"
"path.public" => "D:\MyCode\study\laravel\laravel6\public"
"path.storage" => "D:\MyCode\study\laravel\laravel6\storage" //custom
"path.database" => "D:\MyCode\study\laravel\laravel6\database" //custom
"path.resources" => "D:\MyCode\study\laravel\laravel6\resources"
"path.bootstrap" => "D:\MyCode\study\laravel\laravel6\bootstrap"
];
4. 定義了
useAppPath($path)
,useStoragePath($path)
,useDatabasePath($path)
,useEnvironmentPath($path)
,
這四個方法也是對應四個可自定義的屬性,在論壇中搜尋 useAppPath
發現這篇文章
詳解 packagit 用了什麼黑魔法,並可完全替換 artisan 命令
本作品採用《CC 協議》,轉載必須註明作者和本文連結