異常說(shuō)明
異常是推薦的錯(cuò)誤處理方式,傳統(tǒng)的錯(cuò)誤處理方式要判斷并一層一層返回到調(diào)用點(diǎn),如下所示:
<?php
class Code
{
protected $len;
public function make(int $len)
{
$this->len = $len;
if ($this->line() === false) {
return false;
}
}
public function line()
{
if ($this->len > 5) {
return false;
}
}
}
$code = new Code;
if ($code->make(10) === false) {
echo '驗(yàn)證碼創(chuàng)建失敗';
}
通過(guò)上面代碼我們發(fā)布處理錯(cuò)誤時(shí)及其不方便,需要多個(gè)判斷語(yǔ)句。下面是改用異常的處理方式。
<?php
class Code
{
protected $len;
public function make(int $len)
{
$this->len = $len;
$this->line();
}
public function line()
{
if ($this->len > 5) {
throw new Exception('長(zhǎng)度不能超過(guò)五位');
}
}
}
try {
$code = new Code;
$code->make(10);
} catch (Exception $e) {
echo $e->getMessage();
}
基本使用
try/catch
PHP需要手動(dòng)拋出異常,這與其他語(yǔ)言不同,異常使用try...cache觸發(fā)。
try{
...
}catch(){
...
}
在 try 代碼塊中對(duì)出現(xiàn)的錯(cuò)誤可以拋出異常,下面是手動(dòng)拋出異常的方法。
throw new Exception($message,$code)
catch 用于接收異常,可以設(shè)置多個(gè) catch 代碼塊,參數(shù)為 Exception 類或繼承于 Exception 的類。
<?php
class ValidateException extends Exception
{ }
try {
throw new ValidateException('is exception', 403);
} catch (ValidateException $e) {
echo 'httpException' . $e->getMessage() . ';code:' . $e->getCode();
} catch (Exception $e) {
echo $e->getMessage();
} finally {
echo '無(wú)論是否拋出異常都將執(zhí)行' . ';code:' . $e->getCode();;
}
finally
finally 需要放在 catch 后,finally 無(wú)論是否拋出異常都會(huì)執(zhí)行。
...
} catch (Exception $e) {
echo $e->getMessage();
} finally {
echo '無(wú)論是否拋出異常都將執(zhí)行';
}
...
異常類
基類方法
PHP為異常處理提供了基礎(chǔ)類 Exception,Exception 類可用方法如下:
| 方法 | 說(shuō)明 | 重寫(xiě) |
|---|---|---|
| getFile | 產(chǎn)生異常錯(cuò)誤的文件 | NO,final |
| getCode | 錯(cuò)誤碼 | NO,final |
| getLine | 錯(cuò)誤行號(hào) | NO,final |
| getMessage | 錯(cuò)誤消息 | NO,final |
| __toString | 對(duì)象轉(zhuǎn)字符串后輸出內(nèi)容 | YES |
<?php
class ValidateException extends Exception
{
//對(duì)象轉(zhuǎn)字符串時(shí)執(zhí)行的魔術(shù)方法
public function __toString()
{
return $this->getFile();
}
}
try {
throw new ValidateException('is exception', 403);
} catch (ValidateException $e) {
echo "文件:" . $e->getFile() . "<hr/>";
echo "消息:" . $e->getMessage() . "<hr/>";
echo "錯(cuò)誤碼:" . $e->getCode() . "<hr/>";
echo "錯(cuò)誤行:" . $e->getLine() . "<hr/>";
echo $e . "<hr/>";
}
異常實(shí)例
實(shí)際開(kāi)發(fā)中需要根據(jù)不同業(yè)務(wù)創(chuàng)建處理錯(cuò)誤的異常類,推薦使用異常來(lái)處理錯(cuò)誤而不是PHP的錯(cuò)誤處理機(jī)制。
因?yàn)榇a量比較大,大家請(qǐng)查看視頻教程來(lái)學(xué)習(xí)。
自定義異常
下面是通過(guò)實(shí)例講解自定義異常的使用方法。
目錄結(jié)構(gòu)
app
-- Exceptions
-- ValidateException.php
-- ViewException.php
-- Servers
-- Validate.php
-- View.php
-- vendor
-- view
-- error.blade.php
-- index.blade.php
-- success.blade.php
bootstrap.php
composer.json
controller.php
index.php
文件內(nèi)容
app\Exceptions\ValidateException.php
<?php
namespace App\Exceptions;
class ValidateException extends \Exception
{
public function render()
{
$_SESSION['VALIDATE_ERROR'] = '表單參數(shù)錯(cuò)誤';
header('location:index.php');
}
}
app\Exceptions\ViewException.php
<?php
namespace App\Exceptions;
use App\Servers\View;
class ViewException extends \Exception
{
public function render()
{
View::make('error', ['error' => $this->getMessage()]);
}
}
app\Servers\Validate.php
<?php
namespace App\Servers;
use App\Exceptions\ValidateException;
class Validate
{
public static function make()
{
$_SESSION['VALIDATE_ERROR'] = '';
if (empty($_POST['title'])) {
throw new ValidateException('表單錯(cuò)誤');
}
}
}
app\Servers\View.php
<?php
namespace App\Servers;
use App\Exceptions\ViewException;
class View
{
public static function make(string $tpl, array $vars = [])
{
$file = 'view/' . $tpl . '.blade.php';
if (!is_file($file)) {
throw new ViewException($file . '模板不存在');
}
include $file;
}
}
app\view\error.blade.php
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<h1><?php echo $vars['error'];?></h1>
</body>
</html>
app\view\index.blade.php
<?php if(isset($_SESSION['VALIDATE_ERROR'])):?>
<?php echo $_SESSION['VALIDATE_ERROR'];?>
<?php endif;?>
<form method="post" action="controller.php">
<input type="text" name="title">
<button>提交</button>
</form>
app\view\error.blade.php
<h1>操作成功</h1>
app\bootstrap.php
<?php
session_start();
include 'vendor/autoload.php';
class Boot
{
public function init()
{
set_exception_handler([$this, 'exception']);
}
public function exception($e)
{
if (method_exists($e, 'render')) {
$e->render();
}
}
}
(new Boot)->init();
composer.json
{
"name": "hd/app",
"authors": [
{
"name": "pfinalClub.com",
"email": "lampxiezi@163.com"
}
],
"autoload": {
"psr-4": {
"App\\": "."
}
},
"require": {}
}
controller.php
<?php
include 'bootstrap.php';
use App\Servers\Validate;
use App\Servers\View;
include 'vendor/autoload.php';
// try {
Validate::make();
View::make('success');
// } catch (ValidateException $e) {
// $e->render();
// } catch (ViewException $e) {
// $e->render();
// }
index.php
<?php
namespace App;
include 'bootstrap.php';
use App\Servers\View;
View::make('index');