国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

php業(yè)務(wù)代碼風(fēng)格的幾個建議

tianyu / 3224人閱讀

摘要:業(yè)務(wù)代碼風(fēng)格的幾個建議關(guān)于循環(huán)體內(nèi)重復(fù)調(diào)用的問題代碼示例是一個可能超出個數(shù)據(jù)的大變量以上代碼塊是有非常嚴(yán)重問題的。所以,業(yè)務(wù)代碼應(yīng)盡量避免使用類似代碼。建議每個方法的代碼不超過行,除非情況特殊。

業(yè)務(wù)代碼風(fēng)格的幾個建議

關(guān)于循環(huán)體內(nèi)重復(fù)調(diào)用的問題

代碼示例:

// $array是一個可能超出1000個數(shù)據(jù)的大變量
foreach ($array as $ar) {
    $model = new Model();
    $modelData = $model->findOne(["id" => $ar["id"]]);
    $modelData["is_less"] = $modelData["tag"] == 3 ? true : false;
    $model2 = new AnotherModel();
    $model2->find(["id" => $ar["id"]])->update(["is_less" => $modelData["is_less"]]);
}

以上代碼塊是有非常嚴(yán)重問題的。

在循環(huán)體中,不能重復(fù)使用數(shù)據(jù)庫查詢太多次,尤其是相似或一致的sql,一定要批量查詢獲取數(shù)據(jù)之后再做相應(yīng)邏輯層面的處理。如果循環(huán)次數(shù)較多,不僅僅會體現(xiàn)在循環(huán)邏輯較慢上,而且在并發(fā)讀寫的業(yè)務(wù)中由于頻繁讀取硬盤以及鎖表等可能會給數(shù)據(jù)庫服務(wù)器造成巨大壓力。

所以以上代碼可以改造成:

$ids = array_columns($array, "id");
if ($ids) {
    $model = new Model();
    $modelDataList = $model->where(["in", "id", $ids])->all();
    $modelDataList = array_combine(array_columns($modelDataList, "id"), $modelDataList);
}
foreach ($array as $ar) {
    $modelData = empty($modelDataList[$ar["id"]]) ? [] : $modelDataList[$ar["id"]];
    if (!$modelData) {
        continue;
    }
    $modelData["is_less"] = $modelData["tag"] == 3 ? true : false;
    $model2 = new AnotherModel();
    $model2->find(["id" => $ar["id"]])->update(["is_less" => $modelData["is_less"]]);
}

還有一個例子,如:

foreach($ids as $id) {
    $data = RpcService::getMyData(["my_id" => $id]);
    $data["field1"] = $data["field2"] + $data["field3"];
    $sendPost = RpcService::sendToBoss(["field1" => $data["field1"]]);
}

像這種通過接口獲取數(shù)據(jù)或者更新數(shù)據(jù)的,一般不能在循環(huán)體內(nèi)重復(fù)調(diào)用,因?yàn)閔ttp或者其他實(shí)現(xiàn)rpc的網(wǎng)絡(luò)協(xié)議或多或少都會慢在數(shù)據(jù)傳輸上,而且對方業(yè)務(wù)的實(shí)現(xiàn)一般也不建議調(diào)用方循環(huán)調(diào)用,所以如果有批量調(diào)用接口的需求,應(yīng)該要求接口提供方提供批量操作的接口,在循環(huán)體外進(jìn)行操作。

以上代碼可修改為:

$dataList = RpcService::getMyDataList(["ids" => $ids]);
array_walk($dataList, function () {
    // 處理字段
});
RpcService::multiSendToBoss(["list" => array_columns($dataList, "field1")]);

還有文件讀取也是類似,php讀寫文件效率并不高,應(yīng)避免頻繁讀寫相同文件。例如:

$readFilePath = "current_file";
foreach($writeFilePaths as $path) {
    $content = file_get_content(realpath($readFilePath));
    file_put_content($path, $content);
}

應(yīng)將文件內(nèi)容放在循環(huán)體外部。

其他但凡是有耗時或不建議頻繁調(diào)用的邏輯,都應(yīng)該寫在循環(huán)體外。

關(guān)于業(yè)務(wù)層面類調(diào)用或方法調(diào)用可讀性的問題。

關(guān)于這一點(diǎn),先看一下代碼示例:

class DemoClass 
{
    
    public $handler = [];
    public function handlerRegister(Handler $handler)
    {
        $this->handler[] = $hanlder;
    }
    
    public function run($id, $params)
    {
        foreach ($this->handler as $h) {
            if ($h->id === $id) {
                return $h->handle($params);
            }
        }
    }
}


class Handler
{
    public $id;
    public function handle($params)
    {
        $result = call_user_func($params["callback"], $params["params"]);
        $resultData = (new $result)->getData();
        $next = $params["next"];
        return $next($resultData);
    }
}

call_user_func、call_user_func_array、Reflection類等可以對變量里的某些內(nèi)容直接實(shí)例化或者調(diào)用,這在機(jī)器編譯運(yùn)行看來是沒什么問題的,但是人看的話就比較費(fèi)心了,你要追根溯源搞清楚調(diào)用的是啥,反射的是啥,雖然寫起來很簡單粗暴,但對讀的人不太友好。況且,即便是phpstorm這樣的強(qiáng)大的IDE,也不能幫你識別追溯這些變量的源頭。

所以,業(yè)務(wù)代碼應(yīng)盡量避免使用類似代碼。

但是,如果你寫的是底層腳手架,是豐富框架功能的一個工具包,那么你可以按照自己的想法來,使用者看不看得懂就不重要了。所以像以上的例子往往出現(xiàn)在vendor依賴包中的比較多,寫起來比較簡單,也不必?fù)?dān)心別人看不懂的問題。

關(guān)于輔助方法編寫的問題

這一點(diǎn)不同的框架有不同的表現(xiàn),可能有一些框架有自身實(shí)現(xiàn)思想的考慮,不方便全局調(diào)用一些東西,但目前很多框架都使用了容器,所以使用輔助方法進(jìn)一步精簡代碼就有些必要了。

寫有輔助方法文件,需要在框架加載過程中,業(yè)務(wù)使用之前引入,最好是全局引入。

比如Yii2中如果要實(shí)現(xiàn)一個json返回,需要寫以下代碼:

Yii::$app->response->format = Response::FORMAT_JSON;
return [
    "code" => 1,
    "message" => "success"
];

如果你寫了一個輔助方法如下:

function ajax(array $data) 
{
    Yii::$app->response->format = Response::FORMAT_JSON;
    return $data;
}

那么代碼可以寫成:

return ajax([
    "code" => 1,
    "message" => "success"
]);

又比如:獲取一個post提交的所有參數(shù):

$post = Yii::$app->request->post(); // 獲取所有
$field1 = Yii::$app->request->post("field1"); // 獲取其中的某個參數(shù)

輔助方法如下:

function post($key = null, default = null)
{
    if ($key === null) {
        return Yii::$app->request->post(); // 獲取所有
    } 
    return Yii::$app->request->post($key, $default)
}

調(diào)用如下:

$post = post();
$field1 = post("field1");

又比如,根據(jù)鍵銷毀數(shù)組中的某一個值。

// 原生寫法
if (isset($arr[$key])) {
    unset($key);
}

// 輔助方法
function array_pull(&$arr, $key)
{
    if (isset($arr[$key])) {
        unset($key);
    }
}
// 調(diào)用
array_pull($arr, $key);

關(guān)于邏輯塊復(fù)用和可讀性的問題

比如:

public function handle($params)
{
    $dataList = (new Model)->query($params)->all();
    $return = [];
    foreach ($dataList as $data) {
        
        if ($data["key"] == 1) {
            $data["field1"] = "123";
        } else if ($data["key"] == 2) {
            $data["field1"] = "678";
            $data["field2"] = "7hj";
        } else if ($data["key"] == 3) {
            $data["field1"] = "uyo";
        } else {
            $data["field1"] = "other";
        }
        
        if ($data["field1"] == "123") {
            $other = [
                "other1" => 34,
                "other2" => 35,
                "other3" => 98
            ];
            $return[] = $other;
        } elseif ($data["field1"] == "678") {
            $other = [
                "other1" => 341,
                "other2" => 351,
                "other3" => 981
            ]; 
            if ($data["field2"] == "7hj") {
                $other = [
                    "other1" => 3412,
                    "other2" => 3512,
                    "other3" => 9812
                ]; 
            }
            $return[] = $other;
        } else if ($data["field1"] === "uyo") {
            $other = [
                "other1" => 3412,
                "other2" => 3512,
                "other3" => 9812
            ]; 
            $return[] = $other;
        } else {
            $other = [
                "other1" => 34123,
                "other2" => 35123,
                "other3" => 98123
            ]; 
            $return[] = $other;
        }
        
    }
}

以上代碼出現(xiàn)的問題主要有三個:無注釋、判斷條件太多、邏輯塊無法復(fù)用。

如果出現(xiàn)更復(fù)雜的邏輯,這段代碼無疑可能會超過100多行,這在開發(fā)維護(hù)人員看起來是很艱難的。

注釋問題和判斷條件太多可能由于業(yè)務(wù)的問題,有時候無法避免,這里重點(diǎn)說一下邏輯塊復(fù)用。

以上的代碼片段中,dataList的獲取,應(yīng)該是一個獨(dú)立的方法,因?yàn)閷砜赡芷渌δ芤矔褂猛瑯拥姆椒ǐ@取對應(yīng)數(shù)據(jù);針對于data["field1"]的取值,也應(yīng)該是一個獨(dú)立的方法;下面對于data["field1"]的判斷,也應(yīng)該是一個獨(dú)立方法。這就需要對代碼拆分,既能夠保證代碼簡潔性、復(fù)用性和可讀性,也避免多個無用變量在一個邏輯塊中積累。

在代碼邏輯中,一個功能應(yīng)該由一個方法來實(shí)現(xiàn),一個方法也應(yīng)該只做一件事。

這樣把這段代碼拆分之后,將會變?yōu)椋?/p>

public function getDataList($params)
{
    return (new Model)->query($params)->all();
}

public function handleField($data)
{
    if ($data["key"] == 1) {
        $data["field1"] = "123";
    } else if ($data["key"] == 2) {
        $data["field1"] = "678";
        $data["field2"] = "7hj";
    } else if ($data["key"] == 3) {
        $data["field1"] = "uyo";
    } else {
        $data["field1"] = "other";
    }
    return $data;
}

public function getOther()
{
    if ($data["field1"] == "123") {
        $other = [
            "other1" => 34,
            "other2" => 35,
            "other3" => 98
        ];
    } elseif ($data["field1"] == "678") {
        $other = [
            "other1" => 341,
            "other2" => 351,
            "other3" => 981
        ]; 
        if ($data["field2"] == "7hj") {
            $other = [
                "other1" => 3412,
                "other2" => 3512,
                "other3" => 9812
            ]; 
        }
    } else if ($data["field1"] === "uyo") {
        $other = [
            "other1" => 3412,
            "other2" => 3512,
            "other3" => 9812
        ]; 
    } else {
        $other = [
            "other1" => 34123,
            "other2" => 35123,
            "other3" => 98123
        ]; 
    }
    return $other;
}

public function handle($params)
{
    $dataList = $this->getDataList($params);
    $return = [];
    foreach ($dataList as $data) {
        $data = $this->handleField($data);
        $return[] = $other;
    }
    return $return;
}

這幾個方法各自承擔(dān)一個功能,只完成一件事。handle()方法只是用來組織幾個方法的數(shù)據(jù),簡單明了。

建議每個方法的代碼不超過30行,除非情況特殊。

關(guān)于公共方法書寫風(fēng)格的建議

關(guān)于公共方法調(diào)用的代碼風(fēng)格,應(yīng)該遵循調(diào)用者最少知道的原則,調(diào)用者只需按照對應(yīng)參數(shù)傳入即可,后面的邏輯復(fù)雜性,原則上不必被調(diào)用者知道,且調(diào)用者應(yīng)能夠充分知曉正確與錯誤信息,且應(yīng)保證其健壯性。

涉及到傳入?yún)?shù)為數(shù)組的,應(yīng)告知調(diào)用者該數(shù)組內(nèi)部參數(shù)的詳細(xì)說明,或在注釋中給出對應(yīng)示例。

頁面下載使用專用文件服務(wù)器

涉及到web頁面直接生成數(shù)據(jù)下載的,應(yīng)盡量使用專用的文件服務(wù)器,而不是直接在頁面進(jìn)行下載,且下載應(yīng)盡量使用異步生成文件。

例如用戶在點(diǎn)擊頁面下載按鈕之后跳入自己的下載頁面,這個頁面上有自己的文件下載的歷史表格,有狀態(tài)標(biāo)記文件是否可以進(jìn)行下載,當(dāng)后臺將文件生成好上傳到文件服務(wù)器之后,會標(biāo)記成可下載。

好處:記錄下載歷史、歷史文件下載、下載性能優(yōu)化、可以處理大文件。

壞處:需要多做一個頁面和一張表,且需要等待文件生成上傳至文件服務(wù)器的時間。

文件服務(wù)器可以使用對象云。

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/31235.html

相關(guān)文章

  • SOA面向服務(wù)基礎(chǔ)

    摘要:面向服務(wù)面向服務(wù)的基礎(chǔ)面向服務(wù)的三層應(yīng)用層,服務(wù)層,數(shù)據(jù)層應(yīng)用層用于給用戶展示,,,,安卓。在服務(wù)器端,進(jìn)程保持睡眠狀態(tài)直到調(diào)用信息到達(dá)為止。編譯完成,提示我們已經(jīng)在下了。 面向服務(wù) 面向服務(wù)的基礎(chǔ) 面向服務(wù)的三層:應(yīng)用層,服務(wù)層,數(shù)據(jù)層 * 應(yīng)用層:用于給用戶展示,PC,H5,IOS,安卓。 * 服務(wù)層:業(yè)務(wù)邏輯,提供接口(商品,訂單,支付,用戶,物流)。 * 數(shù)據(jù)層:提供數(shù)據(jù)支持(...

    songze 評論0 收藏0
  • 如何讓PHP性能問題不再飽受詬病

    摘要:作為開發(fā)中應(yīng)用最廣泛的開源腳本語言,憑借庫類豐富,使用簡單,安全等特點(diǎn),成為和等互聯(lián)網(wǎng)巨頭和全球超過網(wǎng)站的主要開發(fā)語言,然而性能問題是一直以來飽受詬病的,來自開發(fā)組的高馳濤同學(xué)將為我們帶來他對性能優(yōu)化方面的思考和建議。 PHP作為Web開發(fā)中應(yīng)用最廣泛的開源腳本語言,憑借庫類豐富,使用簡單,安全等特點(diǎn),成為Facebook和BAT等互聯(lián)網(wǎng)巨頭和全球超過70%網(wǎng)站的主要開發(fā)語言,然而性能...

    warnerwu 評論0 收藏0
  • 轉(zhuǎn)鳥哥建議:讓PHP7達(dá)到最高性能幾個建議

    摘要:讓達(dá)到最高性能的幾個建議懶得排版了,伯樂在線鏈接原文出處惠新宸歡迎分享原創(chuàng)到伯樂頭條已經(jīng)發(fā)布了,作為十年來最大的版本升級,最大的性能升級,在多放的測試中都表現(xiàn)出很明顯的性能提升,然而,為了讓它能發(fā)揮出最大的性能,我還是有幾件事想提醒下。 讓 PHP7 達(dá)到最高性能的幾個建議 懶得排版了,伯樂在線鏈接:http://blog.jobbole.com/95657/ 原文出處: 惠新宸(@L...

    dcr309duan 評論0 收藏0
  • 使用Swoole加速Laravel(正式環(huán)境中)

    摘要:如需要支持熱啟動,請自行谷歌,大概原理就是用監(jiān)控文件變更,如果更新了重啟如果正式環(huán)境中還可以自己寫個部署腳本,后重啟服務(wù)等,方法很多不一一列舉。 1 Laravel的速度瓶頸在哪? 1.1 已有的一些優(yōu)化方法 1.1.1 laravel官方提供了一些優(yōu)化laravel的優(yōu)化方法 php artisan optimize php artisan config:cache php arti...

    vibiu 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<