摘要:的話,是一個(gè)遵循規(guī)范微型的框架,作者這樣說大致意思的核心工作分發(fā)了請求,然后調(diào)用回調(diào)函數(shù),返回一個(gè)對(duì)象。執(zhí)行的方法時(shí),我們從中取出的依賴,這時(shí)候,注冊的回調(diào)函數(shù)被調(diào)用,返回實(shí)例。
Slim
Slim的話,是一個(gè)遵循PSR (PSR-7)規(guī)范微型的框架,作者這樣說:
Slim is a PHP micro framework that helps you quickly write simple yet powerful web applications and APIs. At its core, Slim is a dispatcher that receives an HTTP request, invokes an appropriate callback routine, and returns an HTTP response. That’s it.
大致意思:slim的核心工作:分發(fā)了Http請求,然后調(diào)用回調(diào)函數(shù),返回一個(gè)Http response對(duì)象。
Slim其實(shí)就幫我們做了兩件事
路由的分發(fā)
依賴的注入
框架很小,所以別的部分(如db操作、模板引擎)可能需要自己實(shí)現(xiàn),但slim通過依賴注入,讓你可以很輕松的組裝其他功能到slim中。
快速入門:[ "addContentLengthHeader" => false, ]]; $app = new SlimApp($config); // Define app routes $app->get("/hello/{name}", function ($request, $response, $args) { return $response->write("Hello " . $args["name"]); }); // Run app $app->run();
request代表了當(dāng)前請求對(duì)象,response代表了當(dāng)前響應(yīng)對(duì)象,$args是占位符的鍵值對(duì)數(shù)組。
訪問/hello/salamander就會(huì)輸出Hello salamander
DB是我自己封裝的一個(gè)PDO的操作類。
$config = ["settings" => [ "addContentLengthHeader" => false, ]]; $app = new SlimApp($config); $container = $app->getContainer(); $container["db"] = function($c) { $dbHost = "localhost"; $dbName = "test"; $dbConf = [ "dsn" => "mysql:dbname={$dbName};host={$dbHost}", "username" => "root", "password" => "******", "charset" => "utf8" ]; $db = new AppLibraryDB(); $db->__setup($dbConf); return $db; }; // Define app routes $app->get("/user/{uid}", "AppControllerIndexController:index");IndexController類
namespace AppController; class IndexController { protected $container; public function __construct(ContainerInterface $container) { $this->container = $container; } public function index($request, $response, $args) { $info = $this->container["db"]->fetch("SELECT name FROM user WHERE uid = :uid", [ "uid" => $args["uid"] ]); echo "user name is " . $info["name"]; } }
IndexController類的是通過composer自動(dòng)載入的(代碼中沒寫):
"autoload": { "psr-4": { "App": "app/" } },
代碼中可以發(fā)現(xiàn),依賴容器的注入是在類實(shí)例化的時(shí)候發(fā)生的。執(zhí)行IndexController的index方法時(shí),我們從$container中取出的db依賴,這時(shí)候,注冊的回調(diào)函數(shù)被調(diào)用,返回實(shí)例。因?yàn)槭怯玫綍r(shí)才實(shí)例化,這個(gè)叫做延遲實(shí)例化。
結(jié)合SwooleSwoole讓PHP可以常駐內(nèi)存,而且它提供了Http Server的功能,所以Slim和Swoole沒什么沖突。
思考Slim是通過當(dāng)前路由(譬如/user/2,不帶查詢字符串)和http方法來找到正確的回調(diào)函數(shù)的。這些量Slim是從哪里取的呢?肯定是$_SERVER。查看slim源碼:
run()方法:
public function run($silent = false) { $response = $this->container->get("response"); try { ob_start(); $response = $this->process($this->container->get("request"), $response); } catch (InvalidMethodException $e) { $response = $this->processInvalidMethod($e->getRequest(), $response); } finally { $output = ob_get_clean(); } if (!empty($output) && $response->getBody()->isWritable()) { $outputBuffering = $this->container->get("settings")["outputBuffering"]; if ($outputBuffering === "prepend") { // prepend output buffer content $body = new HttpBody(fopen("php://temp", "r+")); $body->write($output . $response->getBody()); $response = $response->withBody($body); } elseif ($outputBuffering === "append") { // append output buffer content $response->getBody()->write($output); } } $response = $this->finalize($response); if (!$silent) { $this->respond($response); } return $response; }
發(fā)現(xiàn)$request對(duì)象是從容器取出來的,那$request是怎么注冊的呢??,那就看App類的構(gòu)造函數(shù)了,最后發(fā)現(xiàn)Container類的構(gòu)造函數(shù)中有registerDefaultServices()方法:
private function registerDefaultServices($userSettings) { $defaultSettings = $this->defaultSettings; /** * This service MUST return an array or an * instance of ArrayAccess. * * @return array|ArrayAccess */ $this["settings"] = function () use ($userSettings, $defaultSettings) { return new Collection(array_merge($defaultSettings, $userSettings)); }; $defaultProvider = new DefaultServicesProvider(); $defaultProvider->register($this); }
查看$defaultProvider->register()方法:
public function register($container) { if (!isset($container["environment"])) { /** * This service MUST return a shared instance * of SlimInterfacesHttpEnvironmentInterface. * * @return EnvironmentInterface */ $container["environment"] = function () { return new Environment($_SERVER); }; } if (!isset($container["request"])) { /** * PSR-7 Request object * * @param Container $container * * @return ServerRequestInterface */ $container["request"] = function ($container) { return Request::createFromEnvironment($container->get("environment")); }; } //...
可以看到$request對(duì)象是通過Request::createFromEnvironment方法構(gòu)造的,它需要從容器中取出environment依賴,而environment依賴是通過構(gòu)造一個(gè)Environment對(duì)象得來的,它正好放入了$_SERVER
查看Environment類源碼,可以發(fā)現(xiàn)它繼承了Collection類,Collection的構(gòu)造函數(shù)如下:
public function __construct(array $items = []) { $this->replace($items); }
從上面我們可以得出,我們主要注冊一個(gè)自定義的environment依賴就行,原來$_SERVER的信息可以從swoole的$request->server中取。
簡單實(shí)現(xiàn)server.php
on("start", function ($server) { echo "Swoole http server is started at http://0.0.0.0:8888 "; }); $http->on("request", function ($request, $response) { // Instantiate the app $config = [ "settings" => [ "addContentLengthHeader" => false, ] ]; $config["environment"] = function () use($request) { $server = []; foreach ($request->server as $key => $value) { $server[strtoupper($key)] = $value; } return new Environment($server); }; $app = new SlimApp($config); // Register routes require APP . "/routes.php"; // Run app $slimResponse = $app->run(true); $headers = $slimResponse->getHeaders(); foreach ($headers as $name => $values) { $response->header($name, implode(", ", $values)); } $response->header("X-Powered-By", "Salamander"); $response->end($slimResponse->getBody()); }); $http->start();
注意$request->server中key都是小寫的,所以這里轉(zhuǎn)化了一下。
routes.php(在App目錄中)
get("/", function (Request $request, Response $response) { $response->getBody()->write("Hello Salamander"); return $response; }); $app->get("/user/{uid}", function (Request $request, Response $response, $args) { $response->getBody()->write("Hello User:" . $args["uid"]); return $response; });測試
訪問/
訪問/user/45
打包下載測試百度云盤
tip:環(huán)境基于docker的,運(yùn)行docker-compose up即可
Issue
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://www.ezyhdfw.cn/yun/28198.html
摘要:使開發(fā)人員可以編寫高性能的異步并發(fā),服務(wù)。使用作為網(wǎng)絡(luò)通信框架,可以使企業(yè)研發(fā)團(tuán)隊(duì)的效率大大提升,更加專注于開發(fā)創(chuàng)新產(chǎn)品??傊?,這個(gè)庫讓可以常駐內(nèi)存,并提供了,等功能。 swoole 使 PHP 開發(fā)人員可以編寫高性能的異步并發(fā) TCP、UDP、Unix Socket、HTTP,WebSocket 服務(wù)。Swoole 可以廣泛應(yīng)用于互聯(lián)網(wǎng)、移動(dòng)通信、企業(yè)軟件、云計(jì)算、網(wǎng)絡(luò)游戲、物聯(lián)網(wǎng)(...
摘要:使開發(fā)人員可以編寫高性能的異步并發(fā),服務(wù)。使用作為網(wǎng)絡(luò)通信框架,可以使企業(yè)研發(fā)團(tuán)隊(duì)的效率大大提升,更加專注于開發(fā)創(chuàng)新產(chǎn)品??傊?,這個(gè)庫讓可以常駐內(nèi)存,并提供了,等功能。 swoole 使 PHP 開發(fā)人員可以編寫高性能的異步并發(fā) TCP、UDP、Unix Socket、HTTP,WebSocket 服務(wù)。Swoole 可以廣泛應(yīng)用于互聯(lián)網(wǎng)、移動(dòng)通信、企業(yè)軟件、云計(jì)算、網(wǎng)絡(luò)游戲、物聯(lián)網(wǎng)(...
摘要:總之,是用來管理多個(gè)容器的,用都會(huì)寫一個(gè)開啟所有服務(wù)關(guān)閉所有服務(wù)上面說了,關(guān)鍵是編排好,以下就是的目錄結(jié)構(gòu)訪問在目錄下運(yùn)行命令,在瀏覽器訪問可以看到講解和都是用了官方的鏡像,而是從本地構(gòu)建的。 Docker Docker 是一個(gè)開源的應(yīng)用容器引擎,讓開發(fā)者可以打包他們的應(yīng)用以及依賴包到一個(gè)可移植的容器中,然后發(fā)布到任何流行的 Linux機(jī)器上,也可以實(shí)現(xiàn)虛擬化。容器是完全使用沙箱機(jī)制,...
摘要:總之,是用來管理多個(gè)容器的,用都會(huì)寫一個(gè)開啟所有服務(wù)關(guān)閉所有服務(wù)上面說了,關(guān)鍵是編排好,以下就是的目錄結(jié)構(gòu)訪問在目錄下運(yùn)行命令,在瀏覽器訪問可以看到講解和都是用了官方的鏡像,而是從本地構(gòu)建的。 Docker Docker 是一個(gè)開源的應(yīng)用容器引擎,讓開發(fā)者可以打包他們的應(yīng)用以及依賴包到一個(gè)可移植的容器中,然后發(fā)布到任何流行的 Linux機(jī)器上,也可以實(shí)現(xiàn)虛擬化。容器是完全使用沙箱機(jī)制,...
閱讀 2670·2021-11-15 11:38
閱讀 2982·2021-11-02 14:44
閱讀 3937·2021-09-26 10:13
閱讀 3171·2021-08-13 15:02
閱讀 856·2019-08-30 15:56
閱讀 1633·2019-08-30 15:53
閱讀 2407·2019-08-30 13:01
閱讀 3297·2019-08-29 12:57