7.2. 使用异常的一个例子

未匹配的标注

持之以恒,方得始终!

在前面的章节中,我们使用了文件保存数据,一般做IO读写操作,是经常容易报错的地方,所以我们可以用异常来处理一下。

写文件时,可能会出现的错误:

  1. 文件无法打开。
  2. 无法获得写锁。
  3. 文件无法写入。

我们现在来创建一个异常类:
file_exceptions.php

class fileOpenException extends Exception {
    public function __toString() {
        return "fileOpenException " . $this->getCode() . ": " . $this->getMessage() . "<br/> in " . 
        $this->getFile() . " on line " . $this->getLine() . "<br/>"; 
    }

}


class fileWriteException extends Exception {
    public function __toString() {
        return "fileWriteException " . $this->getCode() . ": " . $this->getMessage() . "<br/> in " . 
        $this->getFile() . " on line " . $this->getLine() . "<br/>"; 
    }
}

class fileLockException extends Exception {
    public function __toString() {
        return "fileLockException " . $this->getCode() . ": " . $this->getMessage() . "<br/> in " . 
        $this->getFile() . " on line " . $this->getLine() . "<br/>"; 
    }
}

我们在之前的 processorder.php 中使用它:

// 载入异常类
require_once("../file_exceptions.php");

// 接收表单传参
$tireqty = intval($_REQUEST['tireqty'])??0;
$oilqty  = intval($_REQUEST['oilqty'])??0;
$sparkqty= intval($_REQUEST['sparkqty'])??0;
$address = $_REQUEST['address']??'';
$document_root = $_SERVER['DOCUMENT_ROOT'];
$date    = date("Y-m-d H:i:s");
?>

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>订单处理</title>
</head>
<body>
    <h1>Bob's Auto Parts - Order Result</h1>    
    <h2>Order Result</h2>

    <?php
    echo "<p> order processed at $date </p>";
    echo "<p> your order is as follows</p>";

    $totalqty = $tireqty + $oilqty + $sparkqty;
    echo "Items ordered : $totalqty <br/>";

    if ($totalqty == 0) {
        echo "你没有下单.";
    } else {
        if($tireqty > 0) echo "$tireqty tires <br>";
        if($oilqty > 0) echo "$oilqty oil <br>";
        if($sparkqty > 0) echo "$sparkqty spark plugs <br>";
    }

    $totalamount = 0.00;

    define('TIREPRICE', 100);
    define('OILPRICE', 10);
    define('SPARKPRICE', 4);

    $totalamount = $tireqty*TIREPRICE + $oilqty*OILPRICE + $sparkqty*SPARKPRICE;
    $totalamount = number_format($totalamount, 2, '.', ' ');

    echo "<p>total of order is $ $totalamount</p>";
    echo "<p>address to ship to is $address</p>";

    $data = "$date, $tireqty tires, $oilqty oil , $sparkqty spark plugs, $totalamount, $address \n";

    try {
        if ( !($fp = @fopen("$document_root/../myorders.txt", 'ab')) ) {
            throw new fileOpenException();
        }

        if ( !flock($fp, LOCK_EX) ) {
            throw new fileLockException();
        }

        if ( !fwrite($fp, $data, strlen($data)) ) {
            throw new fileWriteException();
        }

        flock($fp, LOCK_UN);
        fclose($fp);
        echo "<p>Order written.</p>";
    }

    catch (fileOpenException $foe) {
        echo "订单文件不能打开";
    }

    catch (Exception $e) {
        echo "订单无法处理,请稍后再试";
    }
    ?>

</body>
</html>

从上面例子可以知道:

  • 如果无法打开文件,将抛出一个 fileOpenException 异常。
  • 如果无法锁定文件,将抛出一个 fileLockException 异常。
  • 如果无法写入这个文件,将抛出一个 fileWriteException 异常。

我们上面只给了两个 catch 块,一个来捕获 fileOpenException ,另一个捕获 Exception,由于其它两个异常类是从 Exception 继承的,所以它们可以被第二个 catch 块捕获。

注意:如果异常没有匹配的 catch 块,将报一个致命错误。

后语:PHP还有系统自己的错误处理机制,跟异常没有太多关联,比如我使用未定义的变量,会报错,这是由系统自发的,就算使用异常,错误还是会打印出来,除非我们在 php.ini 中修改了错误级别。

如有任何侵权行为,请通知我删除,谢谢大家!
个人邮箱:865460609@qq.com

本文章首发在 LearnKu.com 网站上。

上一篇 下一篇
Junwind
讨论数量: 0
发起讨论 只看当前版本


暂无话题~