TP5_接口開(kāi)發(fā)之全局異吵悦剑控制

前言:

說(shuō)到異常控制吕喘,也許很多會(huì)比較陌生赘那,我身邊很少人會(huì)去寫拋異常的代碼。但是異常用好了是非常的方便大家開(kāi)發(fā)氯质。首先我們來(lái)回顧下哪里可以看到異常募舟,首先我們用框架開(kāi)發(fā)的時(shí)候,我們的代碼出錯(cuò)或者別的東西闻察。如果開(kāi)啟調(diào)試模式的話拱礁,瀏覽器頁(yè)面會(huì)報(bào)出錯(cuò)誤的位置,還有調(diào)用的順序辕漂,甚至還有內(nèi)存的使用等等很多信息呢灶。這就是框架在捕獲異常時(shí)候,將這些數(shù)據(jù)獲取然后渲染了一套html钉嘹,才讓我們這么直觀的看到錯(cuò)誤鸯乃。那么既然開(kāi)發(fā)框架的開(kāi)發(fā)者為了方便我們使用,使用了拋出異常跋涣,捕獲異常飒责。我們也可以照貓畫虎,來(lái)學(xué)習(xí)下仆潮。

拋出異常

在捕獲異常之前我們先來(lái)看看拋出異常。

雖然可能不少朋友不常用拋出異常遣臼,可是拋出異常的方法性置,大家一定不會(huì)陌生

throw new Exception('錯(cuò)誤');

沒(méi)錯(cuò),使用throw命令 后面跟個(gè)new Exception 就拋出了揍堰。其實(shí)大家仔細(xì)觀察發(fā)現(xiàn)鹏浅,其實(shí)這個(gè)new Exception其實(shí)就是 實(shí)例化了一個(gè)類的對(duì)象。那么拋出異常的本質(zhì)屏歹,實(shí)際上就是 throw 一個(gè)異常類的對(duì)象隐砸。
那么怎么樣才算是一個(gè)異常類呢?
我們平時(shí)拋出最多的異常類就是think\Exception 這是一個(gè)tp封裝的一個(gè)異常類蝙眶。

image.png

我們發(fā)現(xiàn)這個(gè)異常類繼承一個(gè)基礎(chǔ)異常類季希,由此可知褪那,只有直接繼承鏈?zhǔn)嚼^承這個(gè)最最最基礎(chǔ)的Exception類的類才算做一個(gè)異常類。
那么我業(yè)務(wù)需要式塌,我們需要來(lái)構(gòu)建我們自己的異常類博敬,來(lái)方便我們拋出。

在寫自己的異常類之前峰尝,我們需要了解偏窝,我們的異常類需要包含哪些信息。我這里寫出3個(gè)信息在接口開(kāi)發(fā)中我認(rèn)為是足夠了武学。

首先我們建立一個(gè)基礎(chǔ)異常類祭往,我認(rèn)為在開(kāi)發(fā)中,只要是新的類型的類火窒,都應(yīng)該去建立一個(gè)Base類用來(lái)繼承硼补,先不管用不用的上,當(dāng)用上時(shí)確實(shí)會(huì)節(jié)省很多時(shí)間沛鸵,這也是面向?qū)ο缶幊痰膬?yōu)勢(shì)

class BaseException extends Exception
{
    //默認(rèn)返回碼為400參數(shù)錯(cuò)誤
    public $code = 400;
    //默認(rèn)返回信息為參數(shù)錯(cuò)誤
    public $msg = 'parameter error';
    //默認(rèn)返回通用錯(cuò)誤碼
    public $errorCode = 10000;
}

我們有了基類之后我們新建自定義異常類時(shí)繼承一下就好了括勺。后來(lái)我發(fā)現(xiàn)有些同類錯(cuò)誤,但是錯(cuò)誤信息又有點(diǎn)小差異這種去建立兩個(gè)異常類又有點(diǎn)傻逼曲掰。所以我在基類中加上一個(gè)構(gòu)造方法

//基礎(chǔ)異常類,用于被各種不同的異常繼承
class BaseException extends Exception
{
    //默認(rèn)返回碼為400參數(shù)錯(cuò)誤
    public $code = 400;
    //默認(rèn)返回信息為參數(shù)錯(cuò)誤
    public $msg = 'parameter error';
    //默認(rèn)返回通用錯(cuò)誤碼
    public $errorCode = 10000;

    //設(shè)計(jì)構(gòu)造函數(shù),方便某些異常類需要傳入?yún)?shù)修改
    public function __construct($params = [])
    {
        if (!is_array($params) || empty($params)) {
            //如果不是數(shù)組或?yàn)榭?則代表不修改當(dāng)前的類成員變量,也就是用預(yù)設(shè)的值來(lái)返回給客戶端
            return;
        }
        if (key_exists('code', $params)) {
            $this->code = $params['code'];
        }
        if (key_exists('msg', $params)) {
            $this->msg = $params['msg'];
        }
        if (key_exists('errorCode', $params)) {
            $this->errorCode = $params['errorCode'];
        }
    }
}

這樣的話疾捍,我們只需要寫一些比較大體的異常類,然后在構(gòu)造函數(shù)中傳入我想修改的信息就可以栏妖。

什么是全局異陈叶梗控制

然后我們需要思考,我們為什么要拋出異常吊趾,拋出異常和返回false有什么區(qū)別
下面我們?cè)O(shè)想下一個(gè)場(chǎng)景:

假如我們現(xiàn)在有個(gè)控制器層宛裕,控制器去調(diào)用一個(gè)服務(wù)層的方法,服務(wù)層代碼中又調(diào)用了模型層的方法论泛,在這個(gè)方法中間揩尸,我們判斷有個(gè)什么不太對(duì)的地方,我們需要返回個(gè)客戶端一個(gè)報(bào)錯(cuò)信息屁奏,比如岩榆,參數(shù)錯(cuò)誤或者別的東西。那么如果我們要使用返回false的話坟瓢,則需要勇边,從Model層的方法中返回false,然后在service層中接收折联,再返回false粒褒,然后控制器里接收,再根據(jù)返回的false的地方構(gòu)造報(bào)錯(cuò)信息诚镰,轉(zhuǎn)換為json奕坟,在返回給客戶端祥款。

那么拋出異常的優(yōu)勢(shì)就提現(xiàn)出來(lái)了,首先我們拋出的異常對(duì)象可以包含一些報(bào)錯(cuò)信息执赡,其次镰踏,拋出異常會(huì)直接中斷后面的所有代碼的執(zhí)行,非常的干脆沙合。

現(xiàn)在來(lái)看看沒(méi)有錯(cuò)誤的情況我們的操作流程


正常不出錯(cuò)的情況

也許沒(méi)有這么多層奠伪,可能就是一個(gè)模型就完了 我只是打個(gè)比方。

那么如果出錯(cuò)的情況首懈,流程應(yīng)該怎么走呢绊率?


異常控制

我們知道框架有一個(gè)異尘柯模控制滤否,會(huì)將拋出的異常處理成html頁(yè)面。我們希望有個(gè)類似的東西來(lái)幫我們捕獲我們拋出的異常最仑,并且藐俺,將錯(cuò)誤信息直接返回給客戶端。這樣我們就不用一層一層的往控制器傳泥彤。

那么事實(shí)上欲芹,TP5的確給了我們這樣的東西,在手冊(cè)中名字叫異常處理接管吟吝。從名字不難看出菱父,這個(gè)就是我們想要的功能,只是tp的文檔中寫的比較生澀剑逃,不太容易懂浙宜。必須要結(jié)合案例來(lái)學(xué)習(xí)。

TP5異常接管的使用

我們要接管tp5的異秤蓟牵控制粟瞬,我們需要知道tp5之前異常控制的地方在哪萤捆。tp5將這個(gè)路徑寫到了配置里了


原本tp異衬吨樱控制類

我們將我們自己的異常控制類建立好之后將完整的帶命名空間的路徑配置到這里鳖轰。
再看看自己的異常控制類如何寫

其實(shí)對(duì)于異撤龆疲控制來(lái)說(shuō)蕴侣,捕獲異常,分析異常類臭觉。昆雀。辱志。。還是非常復(fù)雜的狞膘,我們實(shí)際上只需要把最后一步渲染成html這一步改成我們需要的返回客戶端數(shù)據(jù)揩懒。所以我們將之前的tp的異常控制繼承挽封,然后重寫他渲染html那個(gè)方法供我們使用就好了

tp異骋亚颍控制的渲染方法

那么繼承了tp的Handle類,重寫這個(gè)render方法辅愿,當(dāng)然同樣的render方法傳入的異常對(duì)象$e 我們繼承之后也回收到

class ExceptionHandler extends Handle
{
    //同樣的這三個(gè)參數(shù)智亮,建立起來(lái),方便使用
    private $code;
    private $msg;
    private $errorCode;

    public function render(Exception $e)
    {
       
    }
}

在書寫我們的代碼之前点待,我們需要理解一個(gè)非常重要的概念:異常的分類

異常分類

我們將我們自己設(shè)計(jì)的異常阔蛉,分為一類。
將我們不可控的異常癞埠,分為一類状原。
我在圖中有舉了一些例子。
那么苗踪,我們?nèi)绾?strong>區(qū)分這兩類異常呢颠区?
細(xì)心的朋友肯定會(huì)發(fā)現(xiàn),我們自己設(shè)計(jì)的異常我們都會(huì)繼承我們自己寫B(tài)aseException類徒探,通過(guò)這一點(diǎn)就可以區(qū)分瓦呼,我們捕獲的異常到底是哪一類的。如果不是我們控制范圍之內(nèi)的異常测暗,我們就應(yīng)該異常他的異常信息央串,報(bào)一個(gè)通用的異常信心,比如未知錯(cuò)誤碗啄,錯(cuò)誤碼500 那種质和,這樣也能保護(hù)我們自己的一些信息。

除了報(bào)通用的錯(cuò)誤信息之外稚字,我們還應(yīng)該記錄日志饲宿,方便我們排查我們代碼的錯(cuò)誤

那么我們現(xiàn)在需要思考一個(gè)新的問(wèn)題,這個(gè)功能是屬于錦上添花的功能
那就是胆描,我們把異常接管了之后瘫想,遇到非我們?cè)O(shè)計(jì)的異常,就會(huì)報(bào)通用錯(cuò)誤昌讲,這個(gè)設(shè)定国夜,在生產(chǎn)模式下沒(méi)有問(wèn)題。但是在開(kāi)發(fā)階段短绸,我們更希望的是看到框架給我們?cè)O(shè)計(jì)好的html報(bào)錯(cuò)頁(yè)面车吹,方便我們定位錯(cuò)誤筹裕。
基于以上的考慮,我通過(guò)判斷debug是否開(kāi)啟來(lái)判斷是否處于生產(chǎn)模式窄驹,如果是開(kāi)發(fā)模式的話朝卒,就調(diào)用父類的方法render方法,這樣就可以渲染出友好的html報(bào)錯(cuò)頁(yè)面乐埠。

說(shuō)了這么多也來(lái)看看代碼吧(涉及到記錄日志方法抗斤,大家可以根據(jù)自己的需求來(lái),記錄數(shù)據(jù)庫(kù)也可以饮戳,我就不過(guò)多介紹豪治,不是本文重點(diǎn))

namespace app\lib\exception;

//用于繼承tp5的全局異常處理類,用來(lái)重寫其中的render方法來(lái)做最終的異常處理
use think\Config;
use think\exception\Handle;
use Exception;
use think\Log;

//總的異常處理類
class ExceptionHandler extends Handle
{
    private $code;
    private $msg;
    private $errorCode;

    public function render(Exception $e)
    {
        //如果這個(gè)傳入的異常類是我們自定義的異常類的話,就說(shuō)明這個(gè)異常在我們的控制之中
        if ($e instanceof BaseException) {
            //將該異常設(shè)定好的屬性給賦值到總的異常處理類
            $this->code = $e->code;
            $this->msg = $e->msg;
            $this->errorCode = $e->errorCode;
        } else {
            //判斷配置中的dbug是否開(kāi)啟確定開(kāi)發(fā)或生產(chǎn)模式
            if (Config::get('app_debug')) {
                //如果是開(kāi)發(fā)模式
                return parent::render($e);

            } else {
                //如果是生產(chǎn)模式,則返回與設(shè)定好的未知錯(cuò)誤的json
                $this->code = 500;
                $this->msg = 'Unknown Error';
                $this->errorCode = 999;
            }
            //全局的記錄日志
            $this->recordErrorLog($e);
        }
        $request = request();
        $result = [
            'errorCode' => $this->errorCode,
            'msg' => $this->msg,
            'url' => $request->url()
        ];
        //返回異常信息到客戶端
        return json($result, $this->code);
    }

    /**
     * @param $e
     * 傳入異常對(duì)象
     */
    private function recordErrorLog(Exception $e)
    {
        //由于在config文件中關(guān)閉了tp5自己的日志系統(tǒng),我們需要重新初始化下
        Log::init([
            'type' => 'file',
            'path' => LOG_PATH,
            'level' => ['error']
        ]);
        //記錄日志,傳入異常的信息
        Log::record($e->getMessage(), 'error');
    }
}

最后將方法寫好之后,不要忘了在config文件中配置你的異吵豆蓿控制類

應(yīng)用拋出異常

那么說(shuō)了這么多,現(xiàn)在拿出一個(gè)實(shí)例來(lái)展示下负拟。

這次測(cè)試的接口是一個(gè)非常簡(jiǎn)單的請(qǐng)求資源接口。我們?cè)O(shè)計(jì)的異常有兩個(gè)歹河,第一就是客戶端傳遞過(guò)來(lái)的id不是正整數(shù)掩浙。第二個(gè)異常就是請(qǐng)求的資源為空。同樣的我也故意寫一個(gè)代碼錯(cuò)誤拋出一個(gè)非我們自己設(shè)計(jì)的異常秸歧。

  1. 我們先看控制器厨姚,很明顯能看出來(lái),當(dāng)我去調(diào)用模型方法查出來(lái)的數(shù)據(jù)為空時(shí)键菱,我會(huì)拋出一個(gè)BannerMisssException異常谬墙。
    /**
     * @url http://local.jxshop.com/api/v1/banner/1
     * @http GET
     * @param $id integer banner的id
     * @throws BannerMissException
     * @return mixed json格式的banner數(shù)據(jù)
     */
    public function getBanner($id)
    {
        //實(shí)例化id驗(yàn)證器對(duì)象并調(diào)用上面的goCheck方法,來(lái)獲取并驗(yàn)證數(shù)據(jù)
        IdMustBePositiveInt::instance()->goCheck();
        //使用模型上的獲取banner數(shù)據(jù)方法
        $banner=BannerModel::getBannerInfoById($id);
        if (!$banner) {
            throw new BannerMissException();
        }
        return $banner;
    }
  1. 我們來(lái)看看異常類是怎么寫的


    BannerMiss異常類
  2. 拿postMan來(lái)測(cè)試一下,我們傳遞一個(gè)數(shù)據(jù)庫(kù)沒(méi)有的banner_id


    測(cè)試結(jié)果

大家可以看到我們的異尘福控制起作用了拭抬。我們控制器中拿到banner_id 10000 然后到數(shù)據(jù)庫(kù)中去尋找,數(shù)據(jù)庫(kù)沒(méi)有查到侵蒙,返回一個(gè)空值造虎,控制器中對(duì)返回值進(jìn)行判斷,如果為空纷闺,拋出異常算凿。這時(shí),異常對(duì)象就會(huì)被我們?cè)O(shè)計(jì)好的異忱绻Γ控制捕獲氓轰,并將異常對(duì)象中包含的報(bào)錯(cuò)信息取出,轉(zhuǎn)換為json浸卦。返回給客戶端戒努。

如果傳入的banner_id 在數(shù)據(jù)庫(kù)中能查到,則不拋出異常,返回應(yīng)該查詢到的數(shù)據(jù)


不拋異常

那么我們?cè)僭囈辉噦鬟f非正整數(shù)的值去呢储玫?

傳遞負(fù)數(shù)

同樣的會(huì)拋出異常,這個(gè)異常有別于剛才的BannerMiss萤皂。這是一個(gè)參數(shù)錯(cuò)誤異常撒穷。
也許有人會(huì)有疑問(wèn),這個(gè)異常是從哪里跑出來(lái)的呢裆熙?
其實(shí)答案就在goCheck()方法中端礼。這個(gè)方法是一個(gè)通用的驗(yàn)證數(shù)據(jù)方法,我在之前的TP5巧用驗(yàn)證器有過(guò)介紹入录,這里就不介紹了蛤奥。直接貼代碼

 /**
     * 獲取傳遞參數(shù),并驗(yàn)證
     * @return array
     * @throws Exception
     * @throws ParameterException
     */
    public function goCheck()
    {
        //接收參數(shù)
        $request = Request::instance();
        //通過(guò)param方法獲取到所有的參數(shù)
        $params = $request->param();
        //由哪個(gè)對(duì)象來(lái)調(diào)用goCheck方法,就是由哪個(gè)對(duì)象來(lái)調(diào)用check方法,將接收的所有參數(shù)傳遞進(jìn)去
        $result = $this->batch()->check($params);
        if (!$result) {
            //如果結(jié)果為false,調(diào)用getError方法獲取錯(cuò)誤信息
            $error = $this->getError();
            //拋出參數(shù)錯(cuò)誤異常
            throw new ParameterException(['msg' => $error]);
        } else {
            //調(diào)用獲取過(guò)濾參數(shù)的方法僚稿,返回給控制器
            return $this->getDataByRule($params);
        }
    }

這又展示了拋出異常的好處凡桥,異常是直接中斷程序進(jìn)程,將異常對(duì)象直接拋到最頂端的全局異呈赐控制里缅刽,在model里可以拋,在service里也可以蠢络,控制器里也可以衰猛,驗(yàn)證器里也行。有不正確的地方就拋出異常刹孔,給客戶端友好提示啡省。

之前展示的都是我們?cè)O(shè)計(jì)好的異常,那么如果是我們代碼寫的不對(duì)髓霞,或者別的什么我們沒(méi)有考慮到的異常出現(xiàn)怎么辦呢卦睹?本文之前也有提過(guò),如果是開(kāi)發(fā)模式酸茴,異撤衷ぃ控制捕獲后會(huì)渲染框架自己的報(bào)錯(cuò)html。如果是生產(chǎn)模式薪捍,會(huì)返回給客戶端一個(gè)通用錯(cuò)誤信息笼痹。并記錄日志。

那么我們現(xiàn)在演示一下酪穿。

非設(shè)計(jì)異常

我們?cè)诳刂破髦屑尤胍粋€(gè)除數(shù)為0的代碼凳干。我們都知道這樣寫肯定是要報(bào)錯(cuò)的。
首先我們看開(kāi)發(fā)模式下


開(kāi)發(fā)模式下的非設(shè)計(jì)異常

服務(wù)器返回了我們熟悉的tp報(bào)錯(cuò)頁(yè)面被济。準(zhǔn)確的定位救赐,還有代碼執(zhí)行的堆棧數(shù)據(jù)
那么現(xiàn)在我將代碼改為生產(chǎn)模式試試


關(guān)閉debug

生產(chǎn)模式下非設(shè)計(jì)異常

這時(shí),返回的就是一個(gè)通用的錯(cuò)誤信息。讓客戶端收到比較友好的json信息经磅,而不是一個(gè)HTML代碼泌绣。也保護(hù)了我們代碼和路徑不被暴露。

之前認(rèn)真看了代碼的朋友一定記得预厌,我們除了拋出通用錯(cuò)誤信息之外阿迈,我們還記錄日志,那么我們?nèi)タ纯慈罩纠镉袥](méi)有我們想要的內(nèi)容轧叽。

日志

我們看到根目錄中l(wèi)og文件苗沧,根據(jù)日期生成了日志文件

日志內(nèi)容

日志記錄錯(cuò)誤時(shí)間,請(qǐng)求ip 請(qǐng)求地址炭晒。錯(cuò)誤信息待逞。方便我們開(kāi)發(fā)者回溯錯(cuò)誤,修改bug

好了网严,兩種例子也展示完了识樱,這個(gè)全局異常控制屿笼,其實(shí)我想寫了很久了牺荠,一直沒(méi)有寫的原因還是感覺(jué)自己的理解不夠深刻,希望在文章中更多的表達(dá)清除自己的意思驴一。如果有疑問(wèn)的地方休雌,歡迎郵件xx9090950@gmail.com 有沒(méi)有寫對(duì)的地方,也希望能得到大神的指點(diǎn)肝断。感謝

以上

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末杈曲,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子胸懈,更是在濱河造成了極大的恐慌担扑,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,402評(píng)論 6 499
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件趣钱,死亡現(xiàn)場(chǎng)離奇詭異涌献,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)首有,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,377評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門燕垃,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人井联,你說(shuō)我怎么就攤上這事卜壕。” “怎么了烙常?”我有些...
    開(kāi)封第一講書人閱讀 162,483評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵轴捎,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我,道長(zhǎng)侦副,這世上最難降的妖魔是什么侦锯? 我笑而不...
    開(kāi)封第一講書人閱讀 58,165評(píng)論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮秦驯,結(jié)果婚禮上率触,老公的妹妹穿的比我還像新娘。我一直安慰自己汇竭,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,176評(píng)論 6 388
  • 文/花漫 我一把揭開(kāi)白布穴张。 她就那樣靜靜地躺著细燎,像睡著了一般。 火紅的嫁衣襯著肌膚如雪皂甘。 梳的紋絲不亂的頭發(fā)上玻驻,一...
    開(kāi)封第一講書人閱讀 51,146評(píng)論 1 297
  • 那天,我揣著相機(jī)與錄音偿枕,去河邊找鬼璧瞬。 笑死,一個(gè)胖子當(dāng)著我的面吹牛渐夸,可吹牛的內(nèi)容都是我干的嗤锉。 我是一名探鬼主播,決...
    沈念sama閱讀 40,032評(píng)論 3 417
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼墓塌,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼瘟忱!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起苫幢,我...
    開(kāi)封第一講書人閱讀 38,896評(píng)論 0 274
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤访诱,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后韩肝,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體触菜,經(jīng)...
    沈念sama閱讀 45,311評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,536評(píng)論 2 332
  • 正文 我和宋清朗相戀三年哀峻,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了涡相。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,696評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡谜诫,死狀恐怖漾峡,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情喻旷,我是刑警寧澤生逸,帶...
    沈念sama閱讀 35,413評(píng)論 5 343
  • 正文 年R本政府宣布,位于F島的核電站,受9級(jí)特大地震影響槽袄,放射性物質(zhì)發(fā)生泄漏烙无。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,008評(píng)論 3 325
  • 文/蒙蒙 一遍尺、第九天 我趴在偏房一處隱蔽的房頂上張望截酷。 院中可真熱鬧,春花似錦乾戏、人聲如沸迂苛。這莊子的主人今日做“春日...
    開(kāi)封第一講書人閱讀 31,659評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)三幻。三九已至,卻和暖如春呐能,著一層夾襖步出監(jiān)牢的瞬間念搬,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書人閱讀 32,815評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工摆出, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留朗徊,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 47,698評(píng)論 2 368
  • 正文 我出身青樓偎漫,卻偏偏與公主長(zhǎng)得像爷恳,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子骑丸,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,592評(píng)論 2 353

推薦閱讀更多精彩內(nèi)容