【轉】laravel aliases別名的原理


在laravel發現有些類可以直接use 類名,就能使用了,例如use DB;就可以使用DB類了,問題是DB這個類並不在根命名空間,這里面實際就是用到了別名。

先通過如下例子來分析基本原理

建立如下文件upload.php,內容為

<?php
namespace test\test2;
class upload{
public function test(){
return 123;
}
}
2 建立文件index.php,內容為

<?php
namespace b;
require('upload.php');
class_alias ( '\test\test2\upload' , 'upload');
$a=new \upload();
echo $a->test();

瀏覽器執行index.php,成功輸出結果123;
可以看到class upload在命名空間test\test2下 但是new upload的時候 並沒有new  \test\test2\upload 而是直接new \upload,原因不多說,就是因為函數class_alias導致的.具體的這個函數的用法可以參考手冊。這里要補充說明class_alias的第3個參數默認為true,手冊上的意思是Whether to autoload if the original class is not found.是什么意思了,還是通過例子說明 ,把index.php修改如下

<?php
namespace b;
//require('upload.php');
spl_autoload_register(function($class){
$num=strrpos($class,'\\');
$num++;
$file=substr($class, $num).'.php';
require($file);
});

class_alias ( '\test\test2\upload' , 'upload');
$a=new \upload();
echo $a->test();

可以看到我注釋掉了require('upload.php'),但是代碼還是成功執行了。有了上面的例子說明,就能看懂laravel的別名實現機制了.
在laravel中,比方說我需要使用Log類,我們通過use Log; Log::info();就能使用記錄日志了.下面來分析原理

laravel的加載過程這里不分析,中間有一步會執行如下這個'Illuminate\Foundation\Bootstrap\RegisterFacades'的bootstrap方法;

class RegisterFacades
{
public function bootstrap(Application $app)
{
//......省略......
AliasLoader::getInstance($app->make('config')->get('app.aliases'))->register();
}
}
$app->make('config')->get('app.aliases')這一步讀取了config文件夾下的app.php的配置文件,這個配置文件里面我們定義了別名列表.

意思就是說如果是需要使用別名 ,必須在配置文件中注冊別名
例如配置文件中有一行配置為'Log' => Illuminate\Support\Facades\Log::class,
繼續追蹤執行流程,代碼會執行到這一步

public function load($alias)
{
if (isset($this->aliases[$alias])) {
return class_alias($this->aliases[$alias], $alias);
}
}
到了這里 ,看了之前的原理的人應該都明白了,我們new Log類 ,根據我們的配置'Log' => Illuminate\Support\Facades\Log::class,實際上是調用的Illuminate\Support\Facades\Log這個類,  可是Illuminate\Support\Facades\Log里並沒有info方法,這是如何實現的了,可以百度facade原理,這里不細說,這里實際上調用的是是從容器里面獲取到了log對象,那么這個log對象是什么時候注冊到容器里面去的了,

protected $bootstrappers = [
'Illuminate\Foundation\Bootstrap\DetectEnvironment',
'Illuminate\Foundation\Bootstrap\LoadConfiguration',
'Illuminate\Foundation\Bootstrap\ConfigureLogging',
'Illuminate\Foundation\Bootstrap\HandleExceptions',
'Illuminate\Foundation\Bootstrap\RegisterFacades',
'Illuminate\Foundation\Bootstrap\RegisterProviders',
'Illuminate\Foundation\Bootstrap\BootProviders',
];

這塊代碼,看過源碼的人都應該熟悉了,在ConfigureLogging這個文件里就會將log注冊到容器里面.這樣一個完整的流程就結束了
from:https://blog.csdn.net/jimgethelp/article/details/77869971


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM