Tự xây dựng một framework php - part3
=> xử lí lỗi khi có lỗi xảy ra trong project , hiển thị chi tiết lỗi, trace, detail request header.. giúp chúng ta debug nhanh chóng và dễ dàng cài đặt composer require filp/whoops thêm vào file bootstrap.php $environment = 'dev' ; /** * Register the error handler */ $whoops ...
=> xử lí lỗi khi có lỗi xảy ra trong project , hiển thị chi tiết lỗi, trace, detail request header.. giúp chúng ta debug nhanh chóng và dễ dàng
cài đặt
composer require filp/whoops
thêm vào file bootstrap.php
$environment = 'dev'; /** * Register the error handler */ $whoops = new WhoopsRun; if ($environment !== 'prod') { $whoops->pushHandler(new WhoopsHandlerPrettyPageHandler); } else { $whoops->pushHandler(function($e){ echo 'internal server error'; }); } $whoops->register();
ở đây mình tạo biến environment để check xem nếu đang ở chế độ development thì hiển thị lỗi cho dev dễ fix
nếu là môi trường production chỉ nên hiển thị trang thông báo lỗi chung chung để phía user không thấy được lỗi.. đề phòng "hacker" tấn công hệ thống thông qua các lỗi hiển thị
ví dụ: trong file TestController.php ta thêm dòng code 4/0; để bắn ra lỗi
public function bird() { 4/0; echo 'Trên cành cây'; }
Khi chưa cài thư viện handle lỗi
Sau khi cài
Đấy giao diện rất là trực quan, nhìn vào là biết ngay lỗi ở đâu
bài này mình ko nói về khái niệm này nữa
Chúng ta sẽ implement package này Auryn document của nó ở đây Docs
composer require rdlowrey/auryn
tạo thêm file Dependencies.php trong thư mục app
<?php
$injector = new AurynInjector;
$injector->define('SymfonyComponentHttpFoundationRequest', [
':query' => $_GET,
':request' => $_POST,
':attributes' => [],
':cookies' => $_COOKIE,
':files' => $_FILES,
':server' => $_SERVER,
':content' => null,
]);
$injector->share('SymfonyComponentHttpFoundationResponse');
$injector->alias('AppContractsBirdServiceInterface', 'AppServicesBirdService');
return $injector;
Các bạn đọc thêm docs để hiểu thêm về alias, share và define
define hiểu đơn giản như set parameter, or bind class
share: dùng chung object kiểu như Singleton
alias: kiểu như là interfaceA này sẽ đc khởi tạo bởi servicesA nào đấy
ok.. đọc lại đoạn code trên cũng hiểu phần nào chức năng của nó rồi nhỉ :v
next:
sửa lại code ở file appoostrap.php ở những part trước để implement cái mới nà:
thay
$request = Request::createFromGlobals(); $response = new Response();
bằng:
$request = $injector->make('SymfonyComponentHttpFoundationRequest'); $response = $injector->make('SymfonyComponentHttpFoundationResponse');
thay
$class = new $className; $class->$method($vars);
bằng
$class = $injector->make($className); $class->$method($vars);
file appoostrap.php sau khi sửa sẽ như sau
<?php
use SymfonyComponentHttpFoundationRequest;
use SymfonyComponentHttpFoundationResponse;
$environment = 'dev';
/**
* Register the error handler
*/
$whoops = new WhoopsRun;
if ($environment !== 'prod') {
$whoops->pushHandler(new WhoopsHandlerPrettyPageHandler);
} else {
$whoops->pushHandler(function($e){
echo 'internal server error';
});
}
$whoops->register();
$injector = include('Dependencies.php');
$request = $injector->make('SymfonyComponentHttpFoundationRequest');
$response = $injector->make('SymfonyComponentHttpFoundationResponse');
$dispatcher = FastRoutesimpleDispatcher(function (FastRouteRouteCollector $router) {
include '../routes/web.php';
});
$routeInfo = $dispatcher->dispatch($request->getMethod(), $request->getPathInfo());
switch ($routeInfo[0]) {
case FastRouteDispatcher::NOT_FOUND:
$response->setContent('404 - Page not found');
$response->setStatusCode(404);
break;
case FastRouteDispatcher::METHOD_NOT_ALLOWED:
$response->setContent('405 - Method not allowed');
$response->setStatusCode(405);
break;
case FastRouteDispatcher::FOUND:
$response->setStatusCode(200);
if(gettype($routeInfo[1]) === 'string'){
$rInfo = explode('@', $routeInfo[1]);
$className = $rInfo[0];
$method = $rInfo[1];
$vars = $routeInfo[2];
$class = $injector->make($className);
$class->$method($vars);
} else {
$handler = $routeInfo[1];
$vars = $routeInfo[2];
call_user_func($handler, $vars);
}
break;
}
$response->prepare($request);
$response->send();
Tiếp theo tạo appContractsBirdServiceInterface.php
<?php
namespace AppContracts;
interface BirdServiceInterface
{
/**
* @return string
*/
public function fly();
}
... và AppServicesBirdService.php
<?php
namespace AppServices;
use AppContractsBirdServiceInterface;
class BirdService implements BirdServiceInterface
{
public function fly()
{
return 'fly fly fly';
}
}
sửa file appControllersTestController.php;
<?php
namespace AppControllers;
use AppContractsBirdServiceInterface;
use SymfonyComponentHttpFoundationResponse;
class TestController
{
public function __construct(Response $response, BirdServiceInterface $birdService) {
$this->birdService = $birdService;
$this->response = $response;
}
public function bird()
{
$rs = $this->birdService->fly();
$this->response->setContent($rs);
}
}
nhờ cấu hình ở trên file appDependencies.php
$injector->alias('AppContractsBirdServiceInterface', 'AppServicesBirdService');
sẽ tìm BirdServiceInterface và khởi tạo bằng BirdService
kết quả:
part 4 to continue...