<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ThinkChat2.0新版上線,更智能更精彩,支持會話、畫圖、視頻、閱讀、搜索等,送10W Token,即刻開啟你的AI之旅 廣告
                ### **1.通過`composer`進行安裝** `composer require slim/slim "^3.0"` ### **2.URL重寫** #### 1. Apache 中 ``` RewriteEngine On RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule ^ index.php [QSA,L] ``` #### 2. Nginx 中 詳見[鏈接](https://www.bookstack.cn/read/slim3-doc/c4b8302be1a9f031.md) ### **3. 編寫 Route** 在根目錄新建`index.php`,以此為項目路由 下面是`demo` ``` <?php /** * * @Description: Route 路由 * @Author: edison * @Date: 2021/6/8 * @Time: 21:55 * */ require 'vendor/autoload.php'; $app = new \Slim\App(); $app->get('/',function () { echo 'Home'; }); $app->get('/users',function () { echo 'Users'; }); $app->run(); ``` ### **4.容器** 下面是一個`demo` ``` <?php /** * * @Description: Route 路由 * @Author: edison * @Date: 2021/6/8 * @Time: 21:55 * */ require 'vendor/autoload.php'; $app = new \Slim\App(); // 實例化一個容器 $container = $app->getContainer(); // 向容器中注入 $container['greeting'] = function () { return 'Hello from the container'; }; $app->get('/',function () { // 加載容器 echo $this->greeting; }); $app->run(); ``` ### **5. 打開顯示錯誤信息** ``` <?php /** * * @Description: Route 路由 * @Author: edison * @Date: 2021/6/8 * @Time: 21:55 * */ require 'vendor/autoload.php'; $app = new \Slim\App([ 'settings' => [ 'displayErrorDetails' => true ] ]); $app->get('/error',function () { echo $this->nothing; }); $app->run(); ``` ### **6. 安裝 twig(用來創建模板)** 因為`demo`中使用的是`slim3.0`,所以這里安裝`twig 2.1` `composer require slim/twig-view:^2.1 ` #### 1. 在`Slim`容器中將次組件注冊為服務 ``` // Register component on container $container['view'] = function ($container) { $view = new \Slim\Views\Twig(__DIR__.'/resources/views', [ 'cache' => false ]); // Instantiate and add Slim specific extension $router = $container->get('router'); $uri = \Slim\Http\Uri::createFromEnvironment(new \Slim\Http\Environment($_SERVER)); $view->addExtension(new \Slim\Views\TwigExtension($router, $uri)); return $view; }; ``` #### 2. 使用此組件,指向對應的頁面模板 ``` $app->get('/',function ($request,$response) { return $this->view->render($response,'home.twig'); }); ``` #### 3. 新建模板 1. 在根目錄新建`resources/view`,用于存儲模板文件 2. 在`views`中新建`layouts`,用于存儲公共頁面 3. 新建`users.twig` ``` {% extends 'layouts/app.twig' %} {% block title %} Users View {% endblock %} {% block content %} Users View {% endblock %} ``` 4. 新建`layouts/app.twig` ``` <!doctype html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>{% block title %}{% endblock %}</title> </head> <body> {% block content %}{% endblock %} </body> </html> ``` 5. 新建`home.twig` ``` {% extends 'layouts/app.twig' %} {% block title %} Home View {% endblock %} {% block content %} Home View {% endblock %} ``` 6. 將數據渲染到模板 ``` $app->get('/users',function ($request,$response) { // 假設這里是從數據庫得到的users數據 $users = [ ['username' => 'alex'], ['username' => 'tom'], ['username' => 'lina'] ]; return $this->view->render($response,'users.twig',[ 'users' => $users, ]); }); ``` ``` {% extends 'layouts/app.twig' %} {% block title %} Profile for {{ user.username }} {% endblock %} {% block content %} <ul> {% for user in users %} <li>{{ user.username }}</li> {% endfor %} </ul> {% endblock %} ``` 7. 模板之間的跳轉與提交數據 * 模板之間的跳轉 1. 在路由中設置別名`setName` ``` $app->get('/',function ($request,$response) { return $this->view->render($response,'home.twig'); })->setName('home'); $app->get('/users',function ($request,$response) { // 假設這里是從數據庫得到的users數據 $users = [ ['username' => 'alex'], ['username' => 'tom'], ['username' => 'lina'] ]; return $this->view->render($response,'users.twig',[ 'users' => $users, ]); })->setName('users.index'); ``` ``` <a href="{{ path_for('users.index') }}">Users Page</a> ``` * 模板提交數據 ``` <form action="{{ path_for('contact') }}"></form> ``` ### **7.提交路由** * 前端 ``` <form action="{{ path_for('contact') }}" method="post"> <label for="email">Email</label> <input type="text" name="email" id="email"> <button type="submit">提交</button> </form> ``` * 后端 ``` $app->get('/contact',function ($request,$response){ return $this->view->render($response,'contact.twig'); }); $app->post('/contact',function ($request,$response){ echo $request->getParam('email'); // 重定向 return $response->withRedirect('....'); })->setName('contact'); ``` ### **8.路由分組** `Slim`路由可將相同前綴的請求進行分組 ``` $app->group('/topics',function () { $this->get('',function () { echo 'Topics'; }); $this->get('/{id}',function ($request,$response,$args) { echo 'Topic'.$args['id']; }); }); ``` ### **9.在`slim`中使用`pdo`** 1. 利用`PDO`連接遠程數據庫(這里使用容器進行依賴注入) ``` $container = $app->getContainer(); /** * 使用pdo訪問數據庫 */ $container['db'] = function () { $dsn='mysql:host=81.70.105.47;dbname=xike_myxs_site'; $user='xike_myxs_site'; $password='F8T8ECdsij8L4NiG'; $status=1; return new PDO($dsn,$user,$password); }; ``` 2. 查詢數據庫取得用戶信息 ``` $app->get('/',function () { $user = $this->db->query("SELECT * FROM xike_user")->fetchAll(PDO::FETCH_OBJ); var_dump($user); }); ``` ### **10. 利用PDO查詢小例子** ``` $app->get('/users/{mobile}',function ($request,$response,$args) { // 先使用占位符進行查詢語句整合 $user = $this->db->prepare("SELECT * FROM xike_user WHERE mobile = :mobile"); // 將占位符替換為真實數據進行查詢 $user->execute([ 'mobile' => trim($args['mobile']) ]); var_dump($user->fetch(PDO::FETCH_OBJ)); }); ``` **注意:query用于簡單查詢。(好處簡單) prepare+execute用于預處理,使sql語句靈活了很多,也可用防止SQL注入等問題。 總的來說是prepare強大安全,query簡單。** ### **11. psr 4自動加載** 1. 在`composer.json`中添加`psr4自動加載` ``` "autoload-dev": { "psr-4": { "App\\": "app" } } ``` 2. 執行`composer`將自動加載掛載到類 `composer dump-autoload -o` ### **12.`Slim`中的控制器** 1. 路由指向控制器 在使用自動加載后,路由可指向控制器 ``` $app->get('/topics',\App\controllers\TopicController::class.':index'); ``` 2. 在控制器中使用容器 因為要多個控制器使用容器,所以直接摘離,放到公共控制器中,此處為`BaseController.php` ``` abstract class BaseController { protected $container; public function __construct(ContainerInterface $container) { $this->container = $container; } } ``` 以后所有的控制器繼承此控制器即可 ### **13.重定向** 1. 路由中 ``` $app->get('/topics','\App\controllers\TopicController:index')->setName('topic.show'); ``` 2. 控制器中 ``` public function store($request,$response) { return $response->withRedirect($this->container->router->pathFor('topic.show'),['id' => 5]); } ``` ### **14.設置狀態碼** **關鍵代碼** ``` $response->withStatus(404) ``` 1. `BaseController.php`中 ``` public function render404($response) { return $this->container->view->render($response->withStatus(404),'error/404.twig'); } ``` 2. 子類中 ``` public function show($request,$response,$args) { $topic = $this->container->db->prepare("SELECT * FROM topics WHERE ID = :id"); $topic->execute([ 'id' => $args['id'] ]); $topic = $topic->fetch(\PDO::FETCH_OBJ); if ($topic === false) { return $this->render404($response); } return $topic; } ``` ### **15.響應結果JSON格式化** ``` public function show($request,$response,$args) { $topic = $this->container->db->prepare("SELECT * FROM topics WHERE ID = :id"); $topic->execute([ 'id' => $args['id'] ]); $topic = $topic->fetch(\PDO::FETCH_OBJ); if ($topic === false) { return $response->withJson([ 'error' => '未找到對應的主題' ],404); } return $response->withJson($topic,200); } ``` ### **16.中間件** #### 1. 路由中間件 中間件編寫 ``` $middleware = function ($request,$response,$next) { // $response->getBody()->write('Before'); if (!isset($_SESSION['user_id'])) { $response = $response->withRedirect($container->router->pathFor('login')); } return $next($request,$response); }; ``` ``` // 偽造token $token = function ($request,$response,$next) { $request = $request->withAttribute('token','abc123'); return $next($request,$response); }; ``` 使用 ``` $app->get('/topics','\App\controllers\TopicController:index')->add($middleware); ``` #### 2. 控制器中間件 新建`RedirectIfUnauthenticated.php` ``` class RedirectIfUnauthenticated { public function __invoke($request,$response,$next) { if (!isset($_SESSION['user_id'])) { $response = $response->withRedirect("login地址"); } return $next($request,$response); } } ``` 在路由中使用 ``` $app->get('/topics','\App\controllers\TopicController:index')->add(new \App\controllers\RedirectIfUnauthenticated()); ``` #### 3.在控制器中間件中使用容器 路由中 ``` $app->get('/topics','\App\controllers\TopicController:index')->add(new \App\controllers\RedirectIfUnauthenticated($container)); ``` 控制器中 ``` class RedirectIfUnauthenticated { protected $container; public function __construct(ContainerInterface $container) { $this->container = $container; } public function __invoke($request,$response,$next) { if (!isset($_SESSION['user_id'])) { $response = $response->withRedirect($this->container->router->pathFor('login')); } return $next($request,$response); } } ``` #### 4.IP過濾器小例子 路由器中全局啟用中間件 `$app->add(new \App\controllers\InFilter());` 中間件編寫 ``` class InFilter { protected $db; public function __construct(\PDO $db) { $this->db = $db; } public function __invoke($request,$response,$next) { $ips = $this->db->query("SELECT * FROM blocked")->fetchAll(PDO::FETCH_COLUMN,0); if (in_array($_SERVER['REMOTE_ADDR'],$ips)) { return $response->withStatus(401)->write('Denied'); } return $next($request,$response); } } ``` ### **17.異常處理** 路由中 ``` $container['notFoundHandler'] = function ($container) { return new \App\controllers\NotFoundHandler($container); }; ``` 控制器中 ``` <?php /** * * @Description: * @Author: edison * @Date: 2021/6/14 * @Time: 16:03 * */ namespace App\controllers; use Psr\Http\Message\ResponseInterface; use Psr\Http\Message\ServerRequestInterface; use Slim\Handlers\AbstractHandler; class NotFoundHandler extends AbstractHandler { protected $view; public function __construct(Twig $view) { $this->view = $view; } public function __invoke(ServerRequestInterface $request,ResponseInterface $response) { $contentType = $this->determineContentType($request); switch ($contentType) { case 'application/json': $output = $this->renderNotFoundJson($response); break; case 'text/html': $output = $this->renderNotFoundHtml($response); break; } return $output->withStatus(404); } protected function renderNotFoundJson($response) { return $response->withJson([ 'error' => 'Not Found' ]); } protected function renderNotFoundHtml($response) { return $response->view->render($response,'errors/404.twigt'); } } ```
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看