国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

PHP處理WEB請求的流程

zhangrxiang / 1085人閱讀

摘要:會依據(jù)協(xié)議,將請求的數(shù)據(jù)等信息發(fā)送給解析器,接下來解析器會解析文件,初始化執(zhí)行環(huán)境,然后處理請求,再以規(guī)定的格式返回處理后的結(jié)果,退出進程。它的特點是會在動態(tài)分配處理進程給請求,以達到提高效率的目的,大多數(shù)實現(xiàn)都會維護一個進程池。

PHP作為世界上最好的編程語音,被廣泛的運用到Web開發(fā)中。因為其語法和C類似,有著非常平緩的學(xué)習(xí)曲線,越來越多的人使用PHP進行Web產(chǎn)品的快速開發(fā)。PHP世界里也涌現(xiàn)了很多開發(fā)框架,比如Laravel、ThinkPHP等,但不論何總框架,他們在處理Web請求時的模式都是一樣的,本文首先闡述PHP開發(fā)Web應(yīng)用的基本架構(gòu),然后分別分析Laravel和ThinkPHP在處理Web請求時的處理流程。

PHP開發(fā)Web應(yīng)用的基本架構(gòu)

PHP開發(fā)Web應(yīng)用時所以的請求需要指向具體的入口文件。WebServer是一個內(nèi)容分發(fā)者,他接受用戶的請求后,如果是請求的是css、js等靜態(tài)文件,WebServer會找到這個文件,然后發(fā)送給瀏覽器;如果請求的是/index.php,根據(jù)配置文件,WebServer知道這個不是靜態(tài)文件,需要去找PHP解析器來處理,那么他會把這個請求簡單處理后交給PHP解析器。

WebServer會依據(jù)CGI協(xié)議,將請求的Url、數(shù)據(jù)、Http Header等信息發(fā)送給PHP解析器,接下來PHP解析器會解析php.ini文件,初始化執(zhí)行環(huán)境,然后處理請求,再以CGI規(guī)定的格式返回處理后的結(jié)果,退出進程。web server再把結(jié)果返回給瀏覽器。整個處理過程如上圖所示。

FastCGI

這里的PHP解析器就是實現(xiàn)了CGI協(xié)議的程序,每次請求到來時他會解析php.ini文件,初始化執(zhí)行環(huán)境,這就導(dǎo)致PHP解析器性能低下,于是就出現(xiàn)了CGI的改良升級版FastCGI。FastCGI是一種語言無關(guān)的協(xié)議,用來溝通程序(如PHP, Python, Java)和Web服務(wù)器(Apache2, Nginx), 理論上任何語言編寫的程序都可以通過FastCGI來提供Web服務(wù)。它的特點是會在動態(tài)分配處理進程給請求,以達到提高效率的目的,大多數(shù)FastCGI實現(xiàn)都會維護一個進程池。FastCGI會先啟一個master進程,解析配置文件,初始化執(zhí)行環(huán)境,然后再啟動多個worker進程。當請求過來時,master進程會這個請求傳遞給一個worker進程,然后立即接受下一個請求。而且當worker進程不夠用時,master可以根據(jù)配置預(yù)先啟動幾個worker進程等待;當然空閑worker進程太多時,也會自動關(guān)閉,這樣就提高了性能,節(jié)約了系統(tǒng)資源。整個過程FastCGI扮演著對CGI進程進行管理的角色。

PHP-FPM

PHP-FPM是一個專門針對PHP實現(xiàn)了FastCGI協(xié)議的程序,它實際上就是一個PHP FastCGI進程管理器,負責管理一個進程池,調(diào)用PHP解析器來處理來自Web服務(wù)器的請求。PHP-FPM能夠?qū)hp.ini文件的修改進行平滑過度。

新建一個helloworld.php文件,寫入下列代碼

配置好WebServer和PHP-FPM等php運行環(huán)境后,在瀏覽器中訪問該文件就可以直接得到輸出。

基于PHP的Web框架
PHP Web框架是

基于某模式將PHP開發(fā)常用功能封裝實現(xiàn)使開發(fā)者快速開發(fā)的工具

它主要的任務(wù)包括:

代碼重用:定義包、類、函數(shù)的放置和加載規(guī)則,建議直接整合Composer及其AutoLoad特性。

請求的分發(fā)管理:這個就是路由,Rest風(fēng)的框架喜歡Rewrite,簡單的一點的框架主要通過參數(shù)來定位模塊和方法所在。

配置文件管理:加載和動態(tài)加載配置數(shù)據(jù)

錯誤和異常管理:異常捕捉、錯誤日志記錄以及錯誤碼規(guī)范。

Layout和模板引擎:如何規(guī)劃頁面布局、widget如何重用、ajax頁面如何結(jié)合、過期- session如何重定向;數(shù)據(jù)和模板怎么渲染成HTML,是否壓縮和設(shè)置過期頭。

數(shù)據(jù)庫:如何融入控制器;支持什么樣的driver;考慮主從分離的擴展性;以及是否使用ORM

ThinkPHP3.2框架處理流程分析

TP的設(shè)計邏輯就是簡單粗暴,面對問題解決問題,所以他的處理流程是基于面向過程的思想,而沒有采用面向?qū)ο蟮囊蕾囎⑷?、控制反轉(zhuǎn)等思路。他的自動加載、錯誤處理通過php原生函數(shù)的回調(diào)來實現(xiàn)。TP處理每次請求要經(jīng)過四個步驟如下圖所示:

調(diào)用應(yīng)用路口index.php

index.php是TP的入口文件,所有的請求都由該文件接管,它的工作也很簡單主要是引入ThinkPHP入口文件

 5.3.0 !");


 


// 開啟調(diào)試模式 建議開發(fā)階段開啟 部署階段注釋或者設(shè)為false


define("APP_DEBUG",False);


 


// 定義應(yīng)用目錄


define("APP_PATH","./Application/");


 


// 引入ThinkPHP入口文件


require
"./ThinkPHP/ThinkPHP.php";
載入框架入口文件ThinkPHP.php

在ThinkPHP.php中主要記錄初始運行時間和內(nèi)存開銷,然后完成系統(tǒng)常量判斷及定義,最后載入框架引導(dǎo)類(ThinkThink)并執(zhí)行Think::start方法進行應(yīng)用初始化。

應(yīng)用初始化ThinkThink:start()

應(yīng)用初始化首先設(shè)置錯誤處理機制和自動加載機制

static public function start() {
      // 注冊AUTOLOAD方法
      spl_autoload_register("ThinkThink::autoload");      
      // 設(shè)定錯誤和異常處理
      register_shutdown_function("ThinkThink::fatalError");
      set_error_handler("ThinkThink::appError");
      set_exception_handler("ThinkThink::appException");

然后加載相關(guān)配置文件和運行模式定義文件,最后調(diào)用ThinkApp類的run方法啟動應(yīng)用

運行應(yīng)用App::run()

此后TP進入請求處理管道,TP為管道中定義了14個事件,每個事件都可以綁定回調(diào)函數(shù),請求到達管道后依次觸發(fā)這些事件,事件觸發(fā)后就會調(diào)用綁定到事件的回調(diào)函數(shù),整個管道的生命周期由app_init開始,由app_end結(jié)束。具體實現(xiàn)上,TP將這些事件命名為標簽(位),也可以稱之為鉤子,將回調(diào)函數(shù)命名為行為,當應(yīng)用程序運行到標簽的時候,就會被攔截下來,統(tǒng)一執(zhí)行相關(guān)的行為。

Laravel框架處理流程分析
統(tǒng)一入口

Laravel框架使用了統(tǒng)一入口,入口文件:/public/index.php

make("IlluminateContractsHttpKernel");
 
//運行Kernel類的handle方法,主要動作是運行middleware和啟動URL相關(guān)的Contrller
$response = $kernel->handle(
    $request = IlluminateHttpRequest::capture()
);
 
//控制器返回結(jié)果之后的操作,暫時還沒看,以后補上
$response->send();
 
$kernel->terminate($request, $response);
自動加載文件

laravel的自動加載,其實也就是Composer的自動加載
Composer根據(jù)聲明的依賴關(guān)系,從相關(guān)庫的源下載代碼文件,并根據(jù)依賴關(guān)系在 Composer 目錄下生成供類自動加載的 PHP 腳本,使用的時候,項目開始處引入 “/vendor/autoload.php” 文件,就可以直接實例化這些第三方類庫中的類了。

服務(wù)容器——Laravel真正的核心

服務(wù)容器,也叫IoC容器,其實包含了依賴注入(DI)和控制反轉(zhuǎn)(IoC)兩部分,是Laravel的真正核心。其他的各種功能模塊比如 Route(路由)、Eloquent ORM(數(shù)據(jù)庫 ORM 組件)、Request and Response(請求和響應(yīng))等等等等,實際上都是與核心無關(guān)的類模塊提供的,這些類從注冊到實例化,最終被使用,其實都是 Laravel 的服務(wù)容器負責的。

啟動Kernel代碼

Kernel實例調(diào)用handle方法,意味著Laravel的核心和公用代碼已經(jīng)準備完畢,此項目正式開始運行

代碼清單/app/Http/Kernel.php


"AppHttpMiddlewareAuthenticate",


        "auth.basic"
=>
"IlluminateAuthMiddlewareAuthenticateWithBasicAuth",


        "guest"
=>
"AppHttpMiddlewareRedirectIfAuthenticated",


        "test"
=>
"AppHttpMiddleware	estMiddleWare",


    ];


}

可以看到,其實這個文件里面沒有handle方法,只有一些屬性定義,所以真正的handle方法,實在父類里面實現(xiàn)的

代碼清單…/Illuminate/Foundation/Http/Kernel.php

//這個很重要,是項目的一些啟動引導(dǎo)項,Kernel的重要步驟中,首先就是啟動這些文件的bootstrap方法
protected $bootstrappers = [
        //檢測環(huán)境變量文件是否正常
        "IlluminateFoundationBootstrapDetectEnvironment",
        //取得配置文件,即把/config/下的所有配置文件讀取到容器(app()->make("config")可以查看所有配置信息)
        "IlluminateFoundationBootstrapLoadConfiguration",
        //綁定一個名字為log的實例到容器,怎么訪問??(app()->make("log"))
        "IlluminateFoundationBootstrapConfigureLogging",
        //設(shè)置異常抓取信息,這個還沒仔細看,但大概就是這個意思
        "IlluminateFoundationBootstrapHandleExceptions",
        //把/config/app.php里面的aliases項利用PHP庫函數(shù)class_alias創(chuàng)建別名,從此,我們可以使用App::make("app")方式取得實例
        "IlluminateFoundationBootstrapRegisterFacades",
        //把/config/app.php里面的providers項,注冊到容器
        "IlluminateFoundationBootstrapRegisterProviders",
        //運行容器中注冊的所有的ServiceProvider中得boot方法
        "IlluminateFoundationBootstrapBootProviders",
    ];
 
  //真正的handle方法
  public function handle($request)
    {
        try
        {
            //主要是這行,調(diào)度了需要運行的方法
            return $this->sendRequestThroughRouter($request);
        }
        catch (Exception $e)
        {
            $this->reportException($e);
            return $this->renderException($request, $e);
        }
    }
 
    protected function sendRequestThroughRouter($request)
    {
        $this->app->instance("request", $request);
        Facade::clearResolvedInstance("request");
        //運行上述$bootstrappers里面包含的文件的bootstrap方法,運行的作用,上面已經(jīng)注釋
        $this->bootstrap();
        //這是在對URL進行調(diào)度之前,也就是運行Route之前,進行的一些準備工作
        return (new Pipeline($this->app))    
                    ->send($request)        
                    //需要運行$this->middleware里包含的中間件
                    ->through($this->middleware)
                    //運行完上述中間件之后,調(diào)度dispatchToRouter方法,進行Route的操作
                    ->then($this->dispatchToRouter());
    }
 
    //前奏執(zhí)行完畢之后,進行Route操作
    protected function dispatchToRouter()
    {
        return function($request)
        {
            $this->app->instance("request", $request);
            //跳轉(zhuǎn)到Router類的dispatch方法
            return $this->router->dispatch($request);
        };
    }

下面就需要根據(jù)URL和/app/Http/routes.php文件,進行Route操作

文件清單…/Illuminate/Routing/Router.php

public
function
dispatch(Request
$request)


{


$this->currentRequest
=
$request;


//在4.2版本里面,Route有一個篩選屬性;5.0之后的版本,被Middleware代替


$response
=
$this->callFilter("before",
$request);


if
(is_null($response))


{    


//繼續(xù)調(diào)度


$response
=
$this->dispatchToRoute($request);


}


$response
=
$this->prepareResponse($request,
$response);


//在4.2版本里面,Route有一個篩選屬性;5.0之后的版本,被Middleware代替


$this->callFilter("after",
$request,
$response);


return
$response;


}


 


public
function
dispatchToRoute(Request
$request)


{


$route
=
$this->findRoute($request);


$request->setRouteResolver(function()
use
($route)


{


return
$route;


});


$this->events->fire("router.matched",
[$route,
$request]);


$response
=
$this->callRouteBefore($route,
$request);


if
(is_null($response))


{


//
 只看這一行,還是調(diào)度文件


$response
=
$this->runRouteWithinStack(


$route,
$request


);


}


$response
=
$this->prepareResponse($request,
$response);


$this->callRouteAfter($route,
$request,
$response);


return
$response;


}


 


protected
function
runRouteWithinStack(Route
$route,
Request
$request)


{


//
 取得routes.php里面的Middleware節(jié)點


$middleware
=
$this->gatherRouteMiddlewares($route);


//這個有點眼熟


return
(new
Pipeline($this->container))


->send($request)


//執(zhí)行上述的中間件


->through($middleware)


->then(function($request)
use
($route)


{    


//到Controller類了


return
$this->prepareResponse(


$request,


//run控制器


$route->run($request)


);


});


}


 


public
function
run(Request
$request)


{


$this->container
=
$this->container
?:
new
Container;


try


{


if
(
!
is_string($this->action["uses"]))


return
$this->runCallable($request);


if
($this->customDispatcherIsBound())


//實際上是運行了這行


return
$this->runWithCustomDispatcher($request);


 


//其實我是直接想運行這行


return
$this->runController($request);


}


catch
(HttpResponseException
$e)


{


return
$e->getResponse();


}


}


 


//繼續(xù)調(diào)度,最終調(diào)度到.../Illuminate/Routing/ControllerDispatcher.php文件的dispatch方法


protected
function
runWithCustomDispatcher(Request
$request)


{


list($class,
$method)
=
explode("@",
$this->action["uses"]);


 


$dispatcher
=
$this->container->make("illuminate.route.dispatcher");


return
$dispatcher->dispatch($this,
$request,
$class,
$method);
}

文件清單…/Illuminate/Routing/ControllerDispatcher.php

public
function
dispatch(Route
$route,
Request
$request,
$controller,
$method)


    {


        $instance
=
$this->makeController($controller);


        $this->assignAfter($instance,
$route,
$request,
$method);


        $response
=
$this->before($instance,
$route,
$request,
$method);


        if
(is_null($response))


        {


            //還要調(diào)度


            $response
=
$this->callWithinStack(


                $instance,
$route,
$request,
$method


            );


        }


        return
$response;


    }


 


    protected
function
callWithinStack($instance,
$route,
$request,
$method)


    {


        //又是Middleware......有沒有忘記,官方文檔里面Middleware可以加在控制器的構(gòu)造函數(shù)中??!沒錯,這個Middleware就是在控制器里面申明的


        $middleware
=
$this->getMiddleware($instance,
$method);


        //又是這個,眼熟吧


        return
(new
Pipeline($this->container))


                    ->send($request)


                    //再次運行Middleware


                    ->through($middleware)


                    ->then(function($request)
use
($instance,
$route,
$method)


                    {    


                        運行控制器,返回結(jié)果


                        return
$this->call($instance,
$route,
$method);


                    });


    }

終于到達控制器

轉(zhuǎn)自:http://www.eurekao.com/PHP-pr...

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/22586.html

相關(guān)文章

  • LNMP運維追蹤技巧總結(jié)

    摘要:的運維追蹤技巧總結(jié)曾幾何時我開始運維公司的網(wǎng)站,經(jīng)過一段時間的摸爬滾打,也算是總結(jié)了不少在服務(wù)器下調(diào)試追蹤各種網(wǎng)站錯誤的方法。 LNMP的運維追蹤技巧總結(jié) 曾幾何時我開始運維公司的LNMP網(wǎng)站,經(jīng)過一段時間的摸爬滾打,也算是總結(jié)了不少在LNMP服務(wù)器下調(diào)試追蹤各種網(wǎng)站錯誤的方法。好記性不如爛筆頭,還是總結(jié)一下吧! 在開始我會梳理一下我所理解的一個web請求從發(fā)起到響應(yīng)的各個階段服務(wù)器和...

    XboxYan 評論0 收藏0
  • LNMP運維追蹤技巧總結(jié)

    摘要:的運維追蹤技巧總結(jié)曾幾何時我開始運維公司的網(wǎng)站,經(jīng)過一段時間的摸爬滾打,也算是總結(jié)了不少在服務(wù)器下調(diào)試追蹤各種網(wǎng)站錯誤的方法。 LNMP的運維追蹤技巧總結(jié) 曾幾何時我開始運維公司的LNMP網(wǎng)站,經(jīng)過一段時間的摸爬滾打,也算是總結(jié)了不少在LNMP服務(wù)器下調(diào)試追蹤各種網(wǎng)站錯誤的方法。好記性不如爛筆頭,還是總結(jié)一下吧! 在開始我會梳理一下我所理解的一個web請求從發(fā)起到響應(yīng)的各個階段服務(wù)器和...

    Cristalven 評論0 收藏0
  • (PHP7內(nèi)核剖析-1) CGI與FastCGI

    摘要:是與之間數(shù)據(jù)交換的一種協(xié)議。當收到這個請求后,會啟動對應(yīng)的程序,這里就是的解析器。接下來解析器會解析文件,初始化執(zhí)行環(huán)境,然后處理請求,再以規(guī)定規(guī)定的格式返回處理后的結(jié)果,退出進程,再把結(jié)果返回給瀏覽器。 CGI:是 Web Server 與 Web Application 之間數(shù)據(jù)交換的一種協(xié)議。FastCGI:同 CGI,是一種通信協(xié)議,但比 CGI 在效率上做了一些優(yōu)化。PHP-...

    rubyshen 評論0 收藏0
  • (PHP7內(nèi)核剖析-1) CGI與FastCGI

    摘要:是與之間數(shù)據(jù)交換的一種協(xié)議。當收到這個請求后,會啟動對應(yīng)的程序,這里就是的解析器。接下來解析器會解析文件,初始化執(zhí)行環(huán)境,然后處理請求,再以規(guī)定規(guī)定的格式返回處理后的結(jié)果,退出進程,再把結(jié)果返回給瀏覽器。 CGI:是 Web Server 與 Web Application 之間數(shù)據(jù)交換的一種協(xié)議。FastCGI:同 CGI,是一種通信協(xié)議,但比 CGI 在效率上做了一些優(yōu)化。PHP-...

    Salamander 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<