Laravel 5.1 on SAE環(huán)境開(kāi)發(fā)教程【附項(xiàng)目demo源碼】
本文實(shí)例講述了Laravel 5.1 on SAE環(huán)境開(kāi)發(fā)方法。分享給大家供大家參考,具體如下:
Laravel-簡(jiǎn)潔、優(yōu)雅的PHP開(kāi)發(fā)框架,為 WEB 藝術(shù)家創(chuàng)造的 PHP 框架,如今正式移植到SAE環(huán)境。
由于Laravel 5.1相比于Laravel 4有很多的改動(dòng),不僅以目錄結(jié)構(gòu)更加清晰,而且功能也更豐富。但是Laravel官方還是沒(méi)有原生支持SAE環(huán)境(估計(jì)永遠(yuǎn)不會(huì)支持),所以我就做了一個(gè)移植版本,可以很優(yōu)雅的切換本地和SAE環(huán)境。
由于SAE的特殊性,那么這幾個(gè)核心問(wèn)題就必須要解決
#1 putenv()函數(shù)禁用
#2 模板編譯
#3 緩存類
#4 日志處理
#5 Session類
#6 服務(wù)提供者緩存
#1 putenv()函數(shù)禁用
Laravel 5.1使用了這個(gè)putenv()函數(shù)來(lái)向當(dāng)前的環(huán)境中動(dòng)態(tài)添加變量,但是很遺憾的是SAE的PHPRuntime禁用了該函數(shù),所以只能使用折中的方法來(lái)實(shí)現(xiàn)。當(dāng)初本來(lái)想Hook掉該實(shí)現(xiàn),后來(lái)覺(jué)得沒(méi)必要,這個(gè)函數(shù)在Laravel 5.1中主要是為了使用.env配置文件來(lái)統(tǒng)一團(tuán)隊(duì)的配置。所以我是直接禁用了該功能,在vendor/vlucas/phpdotenv/src/Dotenv.php的86行左右,直接注釋掉該函數(shù),然后把所有的配置信息都寫到config文件夾的相應(yīng)配置文件中。雖然解決了該函數(shù)被禁用的問(wèn)題,但是實(shí)現(xiàn)的不夠優(yōu)雅,希望有大神可以給出更加優(yōu)雅的實(shí)現(xiàn)。
#2 模板編譯
該問(wèn)題主要還是因?yàn)镾AE的本地環(huán)境寫入被禁止,所以我使用了Wrapper來(lái)把編譯后的模板文件寫入到Storage。本來(lái)是打算寫到KVDB中,但是會(huì)出現(xiàn)一些奇奇怪怪問(wèn)題,原因不明。
在config\view.php文件中修改:
$compiled = [
'paths' => [
realpath(base_path('resources/views')),
],
'compiled' => realpath(storage_path('framework/views')),
];
if(SAE){
$compiled['compiled'] = 'saestor://'.SAE_STORAGE.'/compiled';
}
return $compiled;
注意要在相應(yīng)的Storage中建立compiled文件夾。
#3 緩存類
Laravel 5.1沒(méi)有直接提供SAE可用的Memcache緩存驅(qū)動(dòng),這個(gè)解決比較簡(jiǎn)單,直接寫一個(gè)服務(wù)提供者注冊(cè)到app.php即可,然后在config\cache.php中注冊(cè),具體實(shí)現(xiàn)看項(xiàng)目源碼
#4 日志處理
這也是一個(gè)比較棘手的問(wèn)題,由于Laravel 5.1的日志處理已經(jīng)不是和4一樣使用服務(wù)提供者,而且直接注入到啟動(dòng)器中,這就使得我們只能覆寫原生ConfigureLogging啟動(dòng)類,而官方也沒(méi)有給出如何覆寫和在哪里覆寫,所以我這邊的解決方案是判斷當(dāng)前環(huán)境為SAE后直接重寫Http內(nèi)核中的一個(gè)啟動(dòng)器屬性,核心代碼:
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',
];
}
這樣還不行,還必須重寫日志的部分實(shí)現(xiàn)
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依舊是本地寫的問(wèn)題,參考了Laravel4的移植,使用了memcache作為session的實(shí)現(xiàn),具體可以結(jié)合緩存部分來(lái)處理
#6 服務(wù)提供者緩存
在應(yīng)用程序的啟動(dòng)過(guò)程中,laravel會(huì)在bootstrap/cache/services.json生成服務(wù)提供者的緩存,為了加快下次訪問(wèn)的速度,依舊是本地寫的問(wèn)題,解決方案很簡(jiǎn)單,使用Storage的Wrapper即可
以上這些問(wèn)題解決后,差不多就算成功了。最后修改下bootstrap\app.php來(lái)實(shí)現(xiàn)本地與SAE環(huán)境的優(yōu)雅切換,主要是判斷環(huán)境然后生成SAE專有應(yīng)用實(shí)例和注入相應(yīng)的Http內(nèi)核。
/*
|--------------------------------------------------------------------------
| 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中來(lái)定義是否為SAE環(huán)境,原因很明確了,就是要注入相應(yīng)的應(yīng)用程序?qū)嵗虷ttp實(shí)例,然后再這里也定義一下Storage
然后就是config\app.php的相關(guān)配置,根據(jù)環(huán)境判斷來(lái)注入相應(yīng)的服務(wù)提供者
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;
}
最后再說(shuō)說(shuō)SAE專有應(yīng)用程序?qū)嵗虷ttp實(shí)例與原生的差別,主要還是本地寫的問(wèn)題。原生的會(huì)在應(yīng)用程序啟動(dòng)時(shí)候生成路由、配置、服務(wù)提供者、模板編譯的相關(guān)文件,以此來(lái)提升加載速度。但是到了SAE就不行了,所以重寫了Application類的部分與路徑相關(guān)的方法,來(lái)把這些文件生成到Storage中,而Http專有內(nèi)核則是處理啟動(dòng)器中的日志類。具體代碼就不貼出來(lái),可以看看項(xiàng)目。
再給一個(gè)SAE可以使用的rewrite
handle: - rewrite: if (path ~ "^/$") goto "public/index.php" - rewrite: if(!is_dir() && !is_file() && path~"^(.*)$") goto "public/index.php/$1"
總結(jié)
整個(gè)移植過(guò)程還算是很順利,得益于Laravel的拓展性與SAE的便利.不過(guò)在對(duì)于putenv()函數(shù)和日志處理的解決方法上,還是實(shí)現(xiàn)的不夠優(yōu)雅,希望能有人給出更有優(yōu)雅的實(shí)現(xiàn)方案。然后其他的SAE服務(wù)比如分詞、郵件、隊(duì)列等,則可以使用服務(wù)提供者自動(dòng)加載,這個(gè)就不多說(shuō)了。
項(xiàng)目github地址: https://github.com/wh469012917/laravel5-on-sae
軟件點(diǎn)擊此處本站下載。
更多關(guān)于Laravel相關(guān)內(nèi)容感興趣的讀者可查看本站專題:《Laravel框架入門與進(jìn)階教程》、《php優(yōu)秀開(kāi)發(fā)框架總結(jié)》、《smarty模板入門基礎(chǔ)教程》、《php日期與時(shí)間用法總結(jié)》、《php面向?qū)ο蟪绦蛟O(shè)計(jì)入門教程》、《php字符串(string)用法總結(jié)》、《php+mysql數(shù)據(jù)庫(kù)操作入門教程》及《php常見(jiàn)數(shù)據(jù)庫(kù)操作技巧匯總》
希望本文所述對(duì)大家基于Laravel框架的PHP程序設(shè)計(jì)有所幫助。
- 關(guān)于擴(kuò)展 Laravel 默認(rèn) Session 中間件導(dǎo)致的 Session 寫入失效問(wèn)題分析
- Laravel中間件實(shí)現(xiàn)原理詳解
- Laravel的throttle中間件失效問(wèn)題解決方法
- Laravel框架實(shí)現(xiàn)利用中間件進(jìn)行操作日志記錄功能
- Laravel框架基于中間件實(shí)現(xiàn)禁止未登錄用戶訪問(wèn)頁(yè)面功能示例
- Laravel實(shí)現(xiàn)用戶注冊(cè)和登錄
- Laravel中注冊(cè)Facades的步驟詳解
- 示例詳解Laravel的注冊(cè)重構(gòu)
- laravel 5.1下php artisan migrate的使用注意事項(xiàng)總結(jié)
- Laravel5.1數(shù)據(jù)庫(kù)連接、創(chuàng)建數(shù)據(jù)庫(kù)、創(chuàng)建model及創(chuàng)建控制器的方法
- Laravel5.1框架注冊(cè)中間件的三種場(chǎng)景詳解
相關(guān)文章
PHP實(shí)現(xiàn)WebSocket實(shí)例詳解
這篇文章主要介紹了PHP實(shí)現(xiàn)WebSocket實(shí)例詳解,本篇文章通過(guò)簡(jiǎn)要的案例,講解了該項(xiàng)技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下2021-09-09
PHP運(yùn)用foreach神奇的轉(zhuǎn)換數(shù)組(實(shí)例講解)
下面小編就為大家分享一篇PHP運(yùn)用foreach神奇的轉(zhuǎn)換數(shù)組(實(shí)例講解),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2018-02-02
php處理靜態(tài)頁(yè)面:頁(yè)面設(shè)置緩存時(shí)間實(shí)例
本篇文章主要介紹了php處理靜態(tài)頁(yè)面:頁(yè)面設(shè)置緩存時(shí)間實(shí)例,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-06-06
PHP基于GD庫(kù)的縮略圖生成代碼(支持jpg,gif,png格式)
你可能會(huì)遇到這樣的問(wèn)題,在用戶上傳了一張圖片后,得到這張圖片的縮略圖,PHP可以使用GD庫(kù)生成縮略圖,那么我們來(lái)探討下,如何才能生成高質(zhì)量的縮略圖呢?2014-06-06
114啦源碼(114la)不能生成地方房產(chǎn)和地方報(bào)刊問(wèn)題4級(jí)頁(yè)面0字節(jié)的解決方法
做了個(gè)網(wǎng)址導(dǎo)航站,用的是114la的源碼,沒(méi)想到里面有很多問(wèn)題,官方也沒(méi)出補(bǔ)丁,沒(méi)辦法,自己學(xué)著改吧2012-01-01

