激情久久久_欧美视频区_成人av免费_不卡视频一二三区_欧美精品在欧美一区二区少妇_欧美一区二区三区的

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術|正則表達式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務器之家 - 編程語言 - PHP教程 - Laravel 5.1 on SAE環境開發教程【附項目demo源碼】

Laravel 5.1 on SAE環境開發教程【附項目demo源碼】

2021-03-09 16:16夏天的風 PHP教程

這篇文章主要介紹了Laravel 5.1 on SAE環境開發方法,結合實例形式詳細分析了Laravel 5.1在SAE環境下的具體開發相關操作步驟與注意事項,需要的朋友可以參考下

本文實例講述了Laravel 5.1 on SAE環境開發方法。分享給大家供大家參考,具體如下:

Laravel-簡潔、優雅的PHP開發框架,為 WEB 藝術家創造的 PHP 框架,如今正式移植到SAE環境。

由于Laravel 5.1相比于Laravel 4有很多的改動,不僅以目錄結構更加清晰,而且功能也更豐富。但是Laravel官方還是沒有原生支持SAE環境(估計永遠不會支持),所以我就做了一個移植版本,可以很優雅的切換本地和SAE環境。

由于SAE的特殊性,那么這幾個核心問題就必須要解決

#1 putenv()函數禁用
#2 模板編譯
#3 緩存類
#4 日志處理
#5 Session類
#6 服務提供者緩存

#1 putenv()函數禁用

Laravel 5.1使用了這個putenv()函數來向當前的環境中動態添加變量,但是很遺憾的是SAE的PHPRuntime禁用了該函數,所以只能使用折中的方法來實現。當初本來想Hook掉該實現,后來覺得沒必要,這個函數在Laravel 5.1中主要是為了使用.env配置文件來統一團隊的配置。所以我是直接禁用了該功能,在vendor/vlucas/phpdotenv/src/Dotenv.php的86行左右,直接注釋掉該函數,然后把所有的配置信息都寫到config文件夾的相應配置文件中。雖然解決了該函數被禁用的問題,但是實現的不夠優雅,希望有大神可以給出更加優雅的實現。

#2 模板編譯

該問題主要還是因為SAE的本地環境寫入被禁止,所以我使用了Wrapper來把編譯后的模板文件寫入到Storage。本來是打算寫到KVDB中,但是會出現一些奇奇怪怪問題,原因不明。

在config\view.php文件中修改:

?
1
2
3
4
5
6
7
8
9
10
$compiled = [
 'paths' => [
 realpath(base_path('resources/views')),
 ],
 'compiled' => realpath(storage_path('framework/views')),
];
if(SAE){
 $compiled['compiled'] = 'saestor://'.SAE_STORAGE.'/compiled';
}
return $compiled;

注意要在相應的Storage中建立compiled文件夾。

#3 緩存類

Laravel 5.1沒有直接提供SAE可用的Memcache緩存驅動,這個解決比較簡單,直接寫一個服務提供者注冊到app.php即可,然后在config\cache.php中注冊,具體實現看項目源碼

#4 日志處理

這也是一個比較棘手的問題,由于Laravel 5.1的日志處理已經不是和4一樣使用服務提供者,而且直接注入到啟動器中,這就使得我們只能覆寫原生ConfigureLogging啟動類,而官方也沒有給出如何覆寫和在哪里覆寫,所以我這邊的解決方案是判斷當前環境為SAE后直接重寫Http內核中的一個啟動器屬性,核心代碼:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
namespace Illuminate\Cloud\SAE;
use App\Http\Kernel as DefaultKernel;
class Kernel extends DefaultKernel{
 /**
 * The bootstrap classes for the application.
 *
 * @var array
 */
 protected $bootstrappers = [
 'Illuminate\Foundation\Bootstrap\DetectEnvironment',
 'Illuminate\Foundation\Bootstrap\LoadConfiguration',
 'Illuminate\Cloud\SAE\Log\ConfigureLogging',
 'Illuminate\Foundation\Bootstrap\HandleExceptions',
 'Illuminate\Foundation\Bootstrap\RegisterFacades',
 'Illuminate\Foundation\Bootstrap\RegisterProviders',
 'Illuminate\Foundation\Bootstrap\BootProviders',
 ];
}

這樣還不行,還必須重寫日志的部分實現

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
class Writer extends IlluminateLogWriter {
 protected function useSaeLog($level = 'debug'){
 $level = $this->parseLevel($level);
 $this->monolog->pushHandler($handler = new SaeLogHandler($level));
 $handler->setFormatter($this->getDefaultFormatter());
 }
 public function useFiles($path, $level = 'debug'){
 if (SAE) {
 return $this->useSaeLog($level);
 }
 parent::useFiles($path, $level);
 }
 public function useDailyFiles($path, $days = 0, $level = 'debug'){
 if (SAE) {
 return $this->useSaeLog($level);
 }
 parent::useDailyFiles($path, $days, $level);
 }
}

#5 Session類

Laravel5.1的session依舊是本地寫的問題,參考了Laravel4的移植,使用了memcache作為session的實現,具體可以結合緩存部分來處理

#6 服務提供者緩存

在應用程序的啟動過程中,laravel會在bootstrap/cache/services.json生成服務提供者的緩存,為了加快下次訪問的速度,依舊是本地寫的問題,解決方案很簡單,使用Storage的Wrapper即可
以上這些問題解決后,差不多就算成功了。最后修改下bootstrap\app.php來實現本地與SAE環境的優雅切換,主要是判斷環境然后生成SAE專有應用實例和注入相應的Http內核。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
/*
|--------------------------------------------------------------------------
| Create The Application
|--------------------------------------------------------------------------
|
| The first thing we will do is create a new Laravel application instance
| which serves as the "glue" for all the components of Laravel, and is
| the IoC container for the system binding all of the various parts.
|
*/
define('SAE',true);
define('SAE_STORAGE', 'laravel');
if(SAE){
 $app = new Illuminate\Cloud\SAE\Application(
 realpath(__DIR__.'/../')
 );
 $app->singleton(
 Illuminate\Contracts\Http\Kernel::class,
 Illuminate\Cloud\SAE\Kernel::class
 );
}else{
 $app = new Illuminate\Foundation\Application(
 realpath(__DIR__.'/../')
 );
 $app->singleton(
 Illuminate\Contracts\Http\Kernel::class,
 App\Http\Kernel::class
 );
}
/*
|--------------------------------------------------------------------------
| Bind Important Interfaces
|--------------------------------------------------------------------------
|
| Next, we need to bind some important interfaces into the container so
| we will be able to resolve them when needed. The kernels serve the
| incoming requests to this application from both the web and CLI.
|
*/
$app->singleton(
 Illuminate\Contracts\Console\Kernel::class,
 App\Console\Kernel::class
);
$app->singleton(
 Illuminate\Contracts\Debug\ExceptionHandler::class,
 App\Exceptions\Handler::class
);
/*
|--------------------------------------------------------------------------
| Return The Application
|--------------------------------------------------------------------------
|
| This script returns the application instance. The instance is given to
| the calling script so we can separate the building of the instances
| from the actual running of the application and sending responses.
|
*/
return $app;

這里解釋下為什么要在bootstrap\app.php中來定義是否為SAE環境,原因很明確了,就是要注入相應的應用程序實例和Http實例,然后再這里也定義一下Storage

然后就是config\app.php的相關配置,根據環境判斷來注入相應的服務提供者

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
if(SAE){
 $removeProviders = [
 Illuminate\Cache\CacheServiceProvider::class,
 Illuminate\Session\SessionServiceProvider::class,
 ];
 for($i = 0; $i < count($app['providers']); $i++){
 if (in_array($app['providers'][$i], $removeProviders)) {
 unset($app['providers'][$i]);
 }
 }
 $app['providers'] = array_merge($app['providers'],[
 Illuminate\Cloud\SAE\Cache\SaeCacheServiceProvider::class,
 Illuminate\Cloud\SAE\Session\SessionServiceProvider::class,
 Illuminate\Cloud\SAE\Storage\StorageServiceProvider::class,
 Illuminate\Cloud\SAE\Segment\SegmentServiceProvider::class,
 ]);
 $app['aliases']['Storage'] = Illuminate\Cloud\SAE\Storage\Storage::class;
 $app['aliases']['Segment'] = Illuminate\Cloud\SAE\Segment\Segment::class;
}

最后再說說SAE專有應用程序實例和Http實例與原生的差別,主要還是本地寫的問題。原生的會在應用程序啟動時候生成路由、配置、服務提供者、模板編譯的相關文件,以此來提升加載速度。但是到了SAE就不行了,所以重寫了Application類的部分與路徑相關的方法,來把這些文件生成到Storage中,而Http專有內核則是處理啟動器中的日志類。具體代碼就不貼出來,可以看看項目。

再給一個SAE可以使用的rewrite

?
1
2
3
handle:
 - rewrite: if (path ~ "^/$") goto "public/index.php"
 - rewrite: if(!is_dir() && !is_file() && path~"^(.*)$") goto "public/index.php/$1"

總結

整個移植過程還算是很順利,得益于Laravel的拓展性與SAE的便利.不過在對于putenv()函數和日志處理的解決方法上,還是實現的不夠優雅,希望能有人給出更有優雅的實現方案。然后其他的SAE服務比如分詞、郵件、隊列等,則可以使用服務提供者自動加載,這個就不多說了。

項目github地址: https://github.com/wh469012917/laravel5-on-sae

希望本文所述對大家基于Laravel框架的PHP程序設計有所幫助。

延伸 · 閱讀

精彩推薦
Weibo Article 1 Weibo Article 2 Weibo Article 3 Weibo Article 4 Weibo Article 5 Weibo Article 6 Weibo Article 7 Weibo Article 8 Weibo Article 9 Weibo Article 10 Weibo Article 11 Weibo Article 12 Weibo Article 13 Weibo Article 14 Weibo Article 15 Weibo Article 16 Weibo Article 17 Weibo Article 18 Weibo Article 19 Weibo Article 20 Weibo Article 21 Weibo Article 22 Weibo Article 23 Weibo Article 24 Weibo Article 25
主站蜘蛛池模板: 黄色三级网站 | 成人免费一区二区三区在线观看 | 国产一级毛片高清视频完整版 | 色网免费观看 | 一级黄色大片在线观看 | 一级毛片免费高清视频 | 久久精品国产99久久6动漫亮点 | 欧美国产一区二区三区 | 国产一区二区精品在线观看 | 九九黄色 | 欧美福利视频一区二区 | 久久久久9999 | 日韩av片在线免费观看 | 国产成人精品一区在线播放 | 久久成人福利 | 日本一区二区在线 | 国产一区在线观看视频 | 免费看h网站| 伊人午夜 | 欧美无极品| 久久国产精品区 | 亚洲一区二区在线视频 | 美国av免费看| 在线播放黄色片 | 亚洲一区二区三区四区精品 | 国产91大片 | 看一级毛片 | 久久久久一区二区三区 | 国产一区二区三区视频在线 | 亚洲成人伊人 | 91精品久久久久久久 | free国产hd老熟bbw | 午夜精品福利视频 | 91短视频版高清在线观看免费 | 精品国产视频一区二区三区 | 成人在线观看地址 | 日本精品中文字幕 | 大学生一级毛片在线视频 | 草逼一区 | 欧美18一19sex性护士农村 | 91黄瓜视频 |