摘要:的話,是一個遵循規范微型的框架,作者這樣說大致意思的核心工作分發了請求,然后調用回調函數,返回一個對象。執行的方法時,我們從中取出的依賴,這時候,注冊的回調函數被調用,返回實例。
Slim
Slim的話,是一個遵循PSR (PSR-7)規范微型的框架,作者這樣說:
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的核心工作:分發了Http請求,然后調用回調函數,返回一個Http response對象。
Slim其實就幫我們做了兩件事
路由的分發
依賴的注入
框架很小,所以別的部分(如db操作、模板引擎)可能需要自己實現,但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代表了當前請求對象,response代表了當前響應對象,$args是占位符的鍵值對數組。
訪問/hello/salamander就會輸出Hello salamander
DB是我自己封裝的一個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自動載入的(代碼中沒寫):
"autoload": { "psr-4": { "App": "app/" } },
代碼中可以發現,依賴容器的注入是在類實例化的時候發生的。執行IndexController的index方法時,我們從$container中取出的db依賴,這時候,注冊的回調函數被調用,返回實例。因為是用到時才實例化,這個叫做延遲實例化。
結合SwooleSwoole讓PHP可以常駐內存,而且它提供了Http Server的功能,所以Slim和Swoole沒什么沖突。
思考Slim是通過當前路由(譬如/user/2,不帶查詢字符串)和http方法來找到正確的回調函數的。這些量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; }
發現$request對象是從容器取出來的,那$request是怎么注冊的呢??,那就看App類的構造函數了,最后發現Container類的構造函數中有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對象是通過Request::createFromEnvironment方法構造的,它需要從容器中取出environment依賴,而environment依賴是通過構造一個Environment對象得來的,它正好放入了$_SERVER
查看Environment類源碼,可以發現它繼承了Collection類,Collection的構造函數如下:
public function __construct(array $items = []) { $this->replace($items); }
從上面我們可以得出,我們主要注冊一個自定義的environment依賴就行,原來$_SERVER的信息可以從swoole的$request->server中取。
簡單實現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都是小寫的,所以這里轉化了一下。
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:環境基于docker的,運行docker-compose up即可
Issue
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/28198.html
摘要:使開發人員可以編寫高性能的異步并發,服務。使用作為網絡通信框架,可以使企業研發團隊的效率大大提升,更加專注于開發創新產品。總之,這個庫讓可以常駐內存,并提供了,等功能。 swoole 使 PHP 開發人員可以編寫高性能的異步并發 TCP、UDP、Unix Socket、HTTP,WebSocket 服務。Swoole 可以廣泛應用于互聯網、移動通信、企業軟件、云計算、網絡游戲、物聯網(...
摘要:使開發人員可以編寫高性能的異步并發,服務。使用作為網絡通信框架,可以使企業研發團隊的效率大大提升,更加專注于開發創新產品。總之,這個庫讓可以常駐內存,并提供了,等功能。 swoole 使 PHP 開發人員可以編寫高性能的異步并發 TCP、UDP、Unix Socket、HTTP,WebSocket 服務。Swoole 可以廣泛應用于互聯網、移動通信、企業軟件、云計算、網絡游戲、物聯網(...
摘要:總之,是用來管理多個容器的,用都會寫一個開啟所有服務關閉所有服務上面說了,關鍵是編排好,以下就是的目錄結構訪問在目錄下運行命令,在瀏覽器訪問可以看到講解和都是用了官方的鏡像,而是從本地構建的。 Docker Docker 是一個開源的應用容器引擎,讓開發者可以打包他們的應用以及依賴包到一個可移植的容器中,然后發布到任何流行的 Linux機器上,也可以實現虛擬化。容器是完全使用沙箱機制,...
摘要:總之,是用來管理多個容器的,用都會寫一個開啟所有服務關閉所有服務上面說了,關鍵是編排好,以下就是的目錄結構訪問在目錄下運行命令,在瀏覽器訪問可以看到講解和都是用了官方的鏡像,而是從本地構建的。 Docker Docker 是一個開源的應用容器引擎,讓開發者可以打包他們的應用以及依賴包到一個可移植的容器中,然后發布到任何流行的 Linux機器上,也可以實現虛擬化。容器是完全使用沙箱機制,...
閱讀 2448·2021-11-15 11:38
閱讀 2832·2021-11-02 14:44
閱讀 3812·2021-09-26 10:13
閱讀 3055·2021-08-13 15:02
閱讀 776·2019-08-30 15:56
閱讀 1428·2019-08-30 15:53
閱讀 2358·2019-08-30 13:01
閱讀 3184·2019-08-29 12:57