bài viết này mình xin giới thiệu về cách thức laravel chạy. để nếu bạn nào debug code laravel thì còn có sơ sở xem sai chỗ nào. Bài này không dành cho pro nhé
2021-01-04 1913 lượt xem
- Trang Chủ
- laravel
- Cơ chế xử lý request trong Laravel
tôi thích vậy đó
😂😂😂 Mời các Pro cút khỏi bài viết để khỏi ném đá chủ thớt 😂😂😂
tôi thích vậy đó
hùng đẹp trai
ahihi đồ ngốc trương thanh hùng nè
hùng đẹp trai
ahihi đồ ngốc trương thanh hùng nè
Javascript là 1 ngôn ngữ bị đồn là si-đa thì PHP lại là 1 ngôn ngữ không hề si-đa. Nó bị AIDS thôi. Đại loại là càng dễ tiếp cận càng dễ chơi cùng thì càng dễ si-đa. laravel không ngoại lệ, nó được viết trên nền php và dễ dùng, nhưng bạn đã thực sự hiểu laravel chạy như nào chưa?
hùng ebudezain
tôi thích vậy đó
Laravel là một framework theo mô hình MVC (Model – View – Controller) và mọi request đều được phân tích từ 1 url của request. từ request đó chúng ta sẽ phân tách để biết được nên chạy controller nào, action nào.
hùng ebudezain
hùng thông minh lắm
đọc dữ liệu hộ bố
0 - tổng quan
tôi thích vậy đó
hùng đẹp trai
bài viết được viết bởi trương thanh hùng //ebudezain.com/
hùng ebudezain
hùng đẹp trai
hùng ebudezain
hùng ebudezain
Biến global của nodejs người dùng A lưu lại giá trị thì người dùng B cũng có thể thấy giá trị đó. còn biến global của PHP thì khác ( khác nodejs thôi chứ giống java nhé ).
hùng ebudezain
hùng ebudezain
tôi thích vậy đó
ahihi đồ ngốc trương thanh hùng nè
tôi thích vậy đó
đọc dữ liệu hộ bố
đọc dữ liệu hộ bố
ahihi đồ ngốc trương thanh hùng nè
bài viết được viết bởi trương thanh hùng //ebudezain.com/
ahihi đồ ngốc trương thanh hùng nè
bài viết được viết bởi trương thanh hùng //ebudezain.com/
hùng thông minh lắm
bài viết được viết bởi trương thanh hùng //ebudezain.com/
ahihi đồ ngốc trương thanh hùng nè
Mọi request của người dùng vào laravel quy cho cùng đều chạy vào public/index.php. Blog này mình đang viết code bằng laravel và bạn thử bấm link này để url có thêm chữ index.php nhưng vẫn chạy cùng 1 controller cùng action nha.
tôi thích vậy đó
tôi thích vậy đó
hùng ebudezain
phân tích những thứ laravel làm
tôi thích vậy đó
Auto Loader
hùng thông minh lắm
hùng ebudezain
đọc dữ liệu hộ bố
tôi thích vậy đó
khi laravel khởi tạo project sẽ download rất nhiều package vào trong vendor. và nếu muốn sử dụng các package thì php cần require vào. bạn vào public/index.php sẽ thấy đoạn code require sau:
hùng ebudezain
hùng đẹp trai
hùng thông minh lắm
require __DIR__.'/../vendor/autoload.php';
bài viết được viết bởi trương thanh hùng //ebudezain.com/
ahihi đồ ngốc trương thanh hùng nè
ahihi đồ ngốc trương thanh hùng nè
đọc dữ liệu hộ bố
hùng ebudezain
nếu bạn download 1 package khác từ packagist.org thì bạn khỏi cần thêm autoload như các project khác.
bài viết được viết bởi trương thanh hùng //ebudezain.com/
Load application
đọc dữ liệu hộ bố
hùng thông minh lắm
tôi thích vậy đó
tôi thích vậy đó
tôi thích vậy đó
tôi thích vậy đó
đọc dữ liệu hộ bố
bài viết được viết bởi trương thanh hùng //ebudezain.com/
bài viết được viết bởi trương thanh hùng //ebudezain.com/
đọc dữ liệu hộ bố
Sau khi load vendor thì ứng dụng laravel cần load 1 app trong folder bootstraps. bạn nhìn trong folder public/index.php thì bạn thấy đoạn require sau:
bài viết được viết bởi trương thanh hùng //ebudezain.com/
hùng ebudezain
$app = require_once __DIR__.'/../bootstrap/app.php';
bài viết được viết bởi trương thanh hùng //ebudezain.com/
thì trong file bootstrap/app.php mục đích chính là khởi tạo 1 cái app, sau đó binding 1 và thứ cần thiết vào app bằng singleton. ví dụ khởi tạo những thứ cần thiết như path, biến global, đăng ký service provider,...
hùng ebudezain
bạn có thể xem kỹ hơn ở vendor\laravel\framework\src\Illuminate\Foundation\Application.php như sau:
ahihi đồ ngốc trương thanh hùng nè
hùng ebudezain
hùng đẹp trai
/** * Create a new Illuminate application instance. * * @param string|null $basePath * @return void */ public function __construct($basePath = null) { if ($basePath) { $this->setBasePath($basePath); } $this->registerBaseBindings(); /// tạo path và binding Service Container $this->registerBaseServiceProviders(); /// đăng ký Service Providers cơ bản cho application $this->registerCoreContainerAliases(); /// nạp các alias }
hùng thông minh lắm
hùng đẹp trai
hùng ebudezain
hùng thông minh lắm
ahihi đồ ngốc trương thanh hùng nè
Run application laravel
hùng đẹp trai
hùng ebudezain
tôi thích vậy đó
hùng thông minh lắm
bài viết được viết bởi trương thanh hùng //ebudezain.com/
ahihi đồ ngốc trương thanh hùng nè
ahihi đồ ngốc trương thanh hùng nè
đọc dữ liệu hộ bố
hùng ebudezain
Nãy giờ không động chạm gì tới request, bây giờ mới là lúc chạy thật.
hùng ebudezain
hùng ebudezain
bài viết được viết bởi trương thanh hùng //ebudezain.com/
tôi thích vậy đó
bài viết được viết bởi trương thanh hùng //ebudezain.com/
hùng đẹp trai
hùng ebudezain
bài viết được viết bởi trương thanh hùng //ebudezain.com/
Tạo Http Kernel
hùng đẹp trai
ahihi đồ ngốc trương thanh hùng nè
hùng đẹp trai
hùng đẹp trai
ahihi đồ ngốc trương thanh hùng nè
đọc dữ liệu hộ bố
hùng thông minh lắm
bài viết được viết bởi trương thanh hùng //ebudezain.com/
hùng đẹp trai
Để xử lý được request thì laravel khởi tạo kernel trước. dựa trên kernel sẽ xử lý request thông qua đối tượng request đã được nạp từ trên. Bạn tạm hiểu kernel là hạt nhân, core, lõi hay đại loại cái gì đó trung tâm xử lý cũng đc. Nó nhận vào request, đem đi phân tích và xử lý sau đó trả ra 1 response tương ứng.
tôi thích vậy đó
hùng ebudezain
hùng thông minh lắm
Xử lý request thông qua kernel
ahihi đồ ngốc trương thanh hùng nè
bài viết được viết bởi trương thanh hùng //ebudezain.com/
hùng thông minh lắm
Quay lại đoạn này
ahihi đồ ngốc trương thanh hùng nè
hùng đẹp trai
hùng thông minh lắm
$response = $kernel->handle( $request = Illuminate\Http\Request::capture() );
tôi thích vậy đó
ahihi đồ ngốc trương thanh hùng nè
hùng ebudezain
đọc dữ liệu hộ bố
ahihi đồ ngốc trương thanh hùng nè
tuy ngắn gọn nhưng kinh khủng khiếp lắm các bạn.
tôi thích vậy đó
tôi thích vậy đó
hùng ebudezain
bài viết được viết bởi trương thanh hùng //ebudezain.com/
đọc dữ liệu hộ bố
hùng ebudezain
bài viết được viết bởi trương thanh hùng //ebudezain.com/
ahihi đồ ngốc trương thanh hùng nè
ahihi đồ ngốc trương thanh hùng nè
bài viết được viết bởi trương thanh hùng //ebudezain.com/
Đầu tiên bạn mở app/Http/Kernel.php sẽ thấy nó extend từ HttpKernel ( tên định danh của class Illuminate\Foundation\Http\Kernel ).
hùng thông minh lắm
hùng đẹp trai
hùng thông minh lắm
ahihi đồ ngốc trương thanh hùng nè
hùng ebudezain
hùng đẹp trai
hùng thông minh lắm
Lưu ý là laravel lấy nền từ Symfony nên không khó hiểu khi mà class Request extends SymfonyRequest.
hùng ebudezain
bài viết được viết bởi trương thanh hùng //ebudezain.com/
hùng ebudezain
hùng thông minh lắm
ahihi đồ ngốc trương thanh hùng nè
tôi thích vậy đó
hùng thông minh lắm
hùng đẹp trai
Dòng $request = Illuminate\Http\Request::capture() quy cho cùng là tạo ra cái biến $request để trong HttpKernel sẽ có hàm public function handle($request) sẽ handle biến $request.
đọc dữ liệu hộ bố
tôi thích vậy đó
hùng ebudezain
bài viết được viết bởi trương thanh hùng //ebudezain.com/
Trở lại app/Http/Kernel.php bạn xem thấy có 3 thuộc tính định nghĩa trong file này là:
- protected $middleware, là Global middleware, mảng middleware này được khai báo, và tất cả các request đến ứng dụng đều phải đi qua tưng cái
- protected $middlewareGroups, loại này để phân ra làm 2 loại web và api. ví dụ như web thì kệ mợ nó chứ api thì phải trả ra json, hay hạn chế đánh cắp dữ liệu thì phải sử dụng rating limit.
- protected $routeMiddleware.đây là middleware mà khi khai báo trong router thì mới chạy.
hùng đẹp trai
truyền request vào router
hùng thông minh lắm
ahihi đồ ngốc trương thanh hùng nè
hùng đẹp trai
ahihi đồ ngốc trương thanh hùng nè
ahihi đồ ngốc trương thanh hùng nè
hùng ebudezain
hùng thông minh lắm
hùng đẹp trai
hùng ebudezain
hùng thông minh lắm
Khi laravel chạy function handle của Illuminate\Foundation\Http\Kernel thì sẽ có cái hàm cần chú ý là $this->sendRequestThroughRouter($request);
ahihi đồ ngốc trương thanh hùng nè
tôi thích vậy đó
hùng thông minh lắm
tôi thích vậy đó
/** * Handle an incoming HTTP request. * * @param \Illuminate\Http\Request $request * @return \Illuminate\Http\Response */ public function handle($request) { try { $request->enableHttpMethodParameterOverride(); $response = $this->sendRequestThroughRouter($request); } catch (Throwable $e) { $this->reportException($e); $response = $this->renderException($request, $e); } $this->app['events']->dispatch( new RequestHandled($request, $response) ); return $response; }
hùng ebudezain
tôi thích vậy đó
đọc dữ liệu hộ bố
đọc dữ liệu hộ bố
hùng đẹp trai
đọc dữ liệu hộ bố
hùng thông minh lắm
ahihi đồ ngốc trương thanh hùng nè
hùng thông minh lắm
hùng đẹp trai
Nếu bạn muốn tìm hiểu kỹ hơn, mình hy vọng bạn sẽ bắt đầu từ hàm này. Vì gần như mọi thứ lõi core đều được xử lý trong hàm này(Service Container, Request, File, Cookie, biến môi trường, các cấu hình, handle exception, đăng ký các Facades, đăng ký các Service Providers, và khởi động Service Provider, xử lý middleware, ... )
tôi thích vậy đó
hùng đẹp trai
hùng đẹp trai
hùng thông minh lắm
Dispatch request
bài viết được viết bởi trương thanh hùng //ebudezain.com/
ahihi đồ ngốc trương thanh hùng nè
đọc dữ liệu hộ bố
tôi thích vậy đó
ahihi đồ ngốc trương thanh hùng nè
hùng thông minh lắm
đối tượng request được tạo ra nhờ 1 loạt các biến global của PHP chạy vào Request của Symfony, đặc biệt biến $_SERVER để detect được url, bạn xem đoạn code này:
hùng ebudezain
ahihi đồ ngốc trương thanh hùng nè
hùng ebudezain
/** * Creates a new request with values from PHP's super globals. * * @return static */ public static function createFromGlobals() { $request = self::createRequestFromFactory($_GET, $_POST, [], $_COOKIE, $_FILES, $_SERVER); if ($_POST) { $request->request = new InputBag($_POST); } elseif (0 === strpos($request->headers->get('CONTENT_TYPE'), 'application/x-www-form-urlencoded') && \in_array(strtoupper($request->server->get('REQUEST_METHOD', 'GET')), ['PUT', 'DELETE', 'PATCH']) ) { parse_str($request->getContent(), $data); $request->request = new InputBag($data); } return $request; }
hùng đẹp trai
ahihi đồ ngốc trương thanh hùng nè
tôi thích vậy đó
đọc dữ liệu hộ bố
hùng thông minh lắm
Cụ thể, hàm sendRequestThroughRouter ở phần truyền request vào router sẽ start các hàm con như dispatchToRoute, findRoute cuối cùng là hàm getRequestUri trong Symfony\Component\HttpFoundation\Request.
hùng đẹp trai
ahihi đồ ngốc trương thanh hùng nè
ahihi đồ ngốc trương thanh hùng nè
hùng đẹp trai
hùng đẹp trai
Vì khi request được khởi tạo có truyền nguyên biến $_SERVER vào nên trong hàm prepareRequestUri có thể lấy REQUEST_URI trong biến $_SERVER ra để tìm đúng router.
hùng ebudezain
hùng thông minh lắm
tôi thích vậy đó
đọc dữ liệu hộ bố
bài viết được viết bởi trương thanh hùng //ebudezain.com/
hùng đẹp trai
Response được trả về và đóng thread.
đọc dữ liệu hộ bố
bài viết được viết bởi trương thanh hùng //ebudezain.com/
ahihi đồ ngốc trương thanh hùng nè
hùng đẹp trai
hùng đẹp trai
hùng đẹp trai
đọc dữ liệu hộ bố
hùng đẹp trai
Sau khi có $response nó sẽ được trả về cho người dùng từ mục xử lý request thông qua kernel thì cũng đã đến lúc gửi về cho client và đóng ứng dụng.
hùng ebudezain
hùng ebudezain
hùng ebudezain
$response->send(); // Gửi response đến người dùng $kernel->terminate($request, $response); // Đóng Kernel và kết thúc vòng đời của một request
đọc dữ liệu hộ bố
hùng đẹp trai
đọc dữ liệu hộ bố
hùng thông minh lắm
Tổng kết
hùng ebudezain
hùng ebudezain
ahihi đồ ngốc trương thanh hùng nè
dài quá nên mình tổng kết quá trình tổng thể của laravel sinh ra 1 response là:
- Auto loader: Tải những gì cần thiết (packages, library, classmap…) đầu tiên.
- Khởi tạo Laravel Application.
- Đăng ký và tạo Http Kernel, Console Kernel, Exceptions Handle.
- Đăng ký các middleware trong Illuminate\Foundation\Http\Kernel.
- Đăng ký request hiện tại thay thế cho request mới nhất ứng dụng nhận được để xử lý.
- Load bootstrappers: load biến môi trường, cấu hình, …
- Đăng ký và xử lý Service Providers
- Chuyển request qua các Middleware hoặc route và xử lý chúng theo ý dev ( có đôi khi bạn sẽ chạy affter middleware nên tùy lúc middleware sẽ chạy trước) và khi xử lý route, một chuỗi các hoạt động từ Router đến Controller đến Model và trả về một Response.
- Gửi response về cho người dùng.
- Kết thúc vòng đời của một request bằng việc đóng lại Http Kernel.