成人无码视频,亚洲精品久久久久av无码,午夜精品久久久久久毛片,亚洲 中文字幕 日韩 无码

資訊專欄INFORMATION COLUMN

Laravel 的十八個最佳實踐

gitmilk / 2066人閱讀

摘要:本文翻譯改編自的十八個最佳實踐這篇文章并不是什么由改編的原則模式等。只是為了讓你注意你在現(xiàn)實生活的項目中最常忽略的內(nèi)容。單一職責(zé)原則正在幫助你避免重復(fù)。當(dāng)然,這也包括了模板的范圍等。此外,也擁有很棒的內(nèi)置工具,比如軟刪除事件范圍等。

本文翻譯改編自 Laravel 的十八個最佳實踐

這篇文章并不是什么由 Laravel 改編的 SOLID 原則、模式等。

只是為了讓你注意你在現(xiàn)實生活的 Laravel 項目中最常忽略的內(nèi)容。

單一責(zé)任原則

一個類和一個方法應(yīng)該只有一個職責(zé)。
錯誤的做法:

public function getFullNameAttribute()
{
    if (auth()->user() && auth()->user()->hasRole("client") && auth()->user()->isVerified()) {
        return "Mr. " . $this->first_name . " " . $this->middle_name . " " $this->last_name;
    } else {
        return $this->first_name[0] . ". " . $this->last_name;
    }
}

推薦的做法:

public function getFullNameAttribute()
{
    return $this->isVerifiedClient() ? $this->getFullNameLong() : $this->getFullNameShort();
}

public function isVerfiedClient()
{
    return auth()->user() && auth()->user()->hasRole("client") && auth()->user()->isVerified();
}

public function getFullNameLong()
{
    return "Mr. " . $this->first_name . " " . $this->middle_name . " " . $this->last_name;
}

public function getFullNameShort()
{
    return $this->first_name[0] . ". " . $this->last_name;
}
強大的模型 & 簡單控制器

如果你使用查詢構(gòu)造器或原始 SQL 來查詢,請將所有與數(shù)據(jù)庫相關(guān)的邏輯放入 Eloquent 模型或存儲庫類中。

壞:

public function index()
{
    $clients = Client::verified()
        ->with(["orders" => function ($q) {
            $q->where("created_at", ">", Carbon::today()->subWeek());
        }])
        ->get();

    return view("index", ["clients" => $clients]);
}

好:

public function index()
{
    return view("index", ["clients" => $this->client->getWithNewOrders()]);
}

Class Client extends Model
{
    public function getWithNewOrders()
    {
        return $this->verified()
            ->with(["orders" => function ($q) {
                $q->where("created_at", ">", Carbon::today()->subWeek());
            }])
            ->get();
    }
}
驗證

將驗證從控制器移動到請求類。

很常見但不推薦的做法:

public function store(Request $request)
{
    $request->validate([
        "title" => "required|unique:posts|max:255",
        "body" => "required",
        "publish_at" => "nullable|date",
    ]);

    ....
}

最好是這樣:

public function store(PostRequest $request)
{    
    ....
}

class PostRequest extends Request
{
    public function rules()
    {
        return [
            "title" => "required|unique:posts|max:255",
            "body" => "required",
            "publish_at" => "nullable|date",
        ];
    }
}
業(yè)務(wù)邏輯應(yīng)該在服務(wù)類中

一個控制器必須只有一個職責(zé),因此應(yīng)該將業(yè)務(wù)邏輯從控制器移到服務(wù)類。

壞:

public function store(Request $request)
{
    if ($request->hasFile("image")) {
        $request->file("image")->move(public_path("images") . "temp");
    }
    
    ....
}

好:

public function store(Request $request)
{
    $this->articleService->handleUploadedImage($request->file("image"));

    ....
}

class ArticleService
{
    public function handleUploadedImage($image)
    {
        if (!is_null($image)) {
            $image->move(public_path("images") . "temp");
        }
    }
}
不要重復(fù)你自己(DRY)

盡可能重用代碼。 SRP(單一職責(zé)原則)正在幫助你避免重復(fù)。當(dāng)然,這也包括了 Blade 模板、Eloquent 的范圍等。

壞:

public function getActive()
{
    return $this->where("verified", 1)->whereNotNull("deleted_at")->get();
}

public function getArticles()
{
    return $this->whereHas("user", function ($q) {
            $q->where("verified", 1)->whereNotNull("deleted_at");
        })->get();
}

好:

public function scopeActive($q)
{
    return $q->where("verified", 1)->whereNotNull("deleted_at");
}

public function getActive()
{
    return $this->active()->get();
}

public function getArticles()
{
    return $this->whereHas("user", function ($q) {
            $q->active();
        })->get();
}
最好傾向于使用 Eloquent 而不是 Query Builder 和原生的 SQL 查詢。要優(yōu)先于數(shù)組的集合

Eloquent 可以編寫可讀和可維護(hù)的代碼。此外,Eloquent 也擁有很棒的內(nèi)置工具,比如軟刪除、事件、范圍等。

比如你這樣寫:

SELECT *
FROM `articles`
WHERE EXISTS (SELECT *
              FROM `users`
              WHERE `articles`.`user_id` = `users`.`id`
              AND EXISTS (SELECT *
                          FROM `profiles`
                          WHERE `profiles`.`user_id` = `users`.`id`) 
              AND `users`.`deleted_at` IS NULL)
AND `verified` = "1"
AND `active` = "1"
ORDER BY `created_at` DESC

還不如這樣寫:

Article::has("user.profile")->verified()->latest()->get();
批量賦值

比如你這樣寫:

$article = new Article;
$article->title = $request->title;
$article->content = $request->content;
$article->verified = $request->verified;
// Add category to article
$article->category_id = $category->id;
$article->save();

是不是還不如這樣寫:

$category->article()->create($request->all());
不要在 Blade 模板中執(zhí)行查詢并使用關(guān)聯(lián)加載(N + 1 問題)

不好的地方在于,這對于100 個用戶來說,等于執(zhí)行 101 個 DB 查詢:

[@foreach](https://laravel-china.org/users/5651) (User::all() as $user)
    {{ $user->profile->name }}
@endforeach

下面的做法,對于 100 個用戶來說,僅僅只執(zhí)行 2 個 DB 查詢:

$users = User::with("profile")->get();

...

[[@foreach](https://laravel-china.org/users/5651)](https://laravel-china.org/users/5651) ($users as $user)
    {{ $user->profile->name }}
@endforeach
與其花盡心思給你的代碼寫注釋,還不如對方法或變量寫一個描述性的名稱

壞:

if (count((array) $builder->getQuery()->joins) > 0)

好:

// 確定是否有任何連接。
if (count((array) $builder->getQuery()->joins) > 0)

最好:

if ($this->hasJoins())
不要把 JS 和 CSS 放在 Blade 模板中,也不要將任何 HTML 放在 PHP 類中

壞:

let article = `{{ json_encode($article) }}`;

好:



Or

最好的方法是使用在 Javascript 中這樣來傳輸數(shù)據(jù):

let article = $("#article").val();
在代碼中使用配置和語言文件、常量,而不是寫死它

壞:

public function isNormal()
{
    return $article->type === "normal";
}

return back()->with("message", "Your article has been added!");

好:

public function isNormal()
{
    return $article->type === Article::TYPE_NORMAL;
}

return back()->with("message", __("app.article_added"));
使用社區(qū)接受的標(biāo)準(zhǔn)的 Laravel 工具

最好使用內(nèi)置的 Laravel 功能和社區(qū)軟件包,而不是其他第三方軟件包和工具。因為將來與你的應(yīng)用程序一起工作的開發(fā)人員都需要學(xué)習(xí)新的工具。另外,使用第三方軟件包或工具的話,如果遇到困難,從 Laravel 社區(qū)獲得幫助的機會會大大降低。不要讓你的客戶為此付出代價!

任務(wù) 標(biāo)準(zhǔn)工具 第三方工具
授權(quán) Policies Entrust, Sentinel and other packages
前端編譯 Laravel Mix Grunt, Gulp, 3rd party packages
開發(fā)環(huán)境 Homestead Docker
部署 Laravel Forge Deployer and other solutions
單元測試 PHPUnit, Mockery Phpspec
瀏覽器測試 Laravel Dusk Codeception
數(shù)據(jù)庫操作 Eloquent SQL, Doctrine
模板 Blade Twig
數(shù)據(jù)操作 Laravel collections Arrays
表單驗證 Request classes 3rd party packages, validation in controller
認(rèn)證 Built-in 3rd party packages, your own solution
API 認(rèn)證 Laravel Passport 3rd party JWT and OAuth packages
創(chuàng)建 API Built-in Dingo API and similar packages
數(shù)據(jù)庫結(jié)構(gòu)操作 Migrations Working with DB structure directly
局部化 Built-in 3rd party packages
實時用戶接口 Laravel Echo, Pusher 3rd party packages and working with WebSockets directly
Generating testing data Seeder classes, Model Factories, Faker Creating testing data manually
生成測試數(shù)據(jù) Laravel Task Scheduler Scripts and 3rd party packages
數(shù)據(jù)庫 MySQL, PostgreSQL, SQLite, SQL Server MongoDB
遵循Laravel命名約定

遵循 PSR 標(biāo)準(zhǔn)。 另外,請遵循 Laravel 社區(qū)接受的命名約定:

類型 規(guī)則 正確示例 錯誤示例
Controller 單數(shù) ArticleController ArticlesController
Route 復(fù)數(shù) articles/1 article/1
Named route 帶點符號的蛇形命名 users.show_active users.show-active, show-active-users
Model 單數(shù) User Users
hasOne or belongsTo relationship 單數(shù) articleComment articleComments, article_comment
All other relationships 復(fù)數(shù) articleComments articleComment, article_comments
Table 復(fù)數(shù) article_comments article_comment, articleComments
Pivot table 按字母順序排列的單數(shù)模型名稱 article_user user_article, articles_users
Table column 帶著模型名稱的蛇形命名 meta_title MetaTitle; article_meta_title
Foreign key 帶_id后綴的單數(shù)型號名稱 article_id ArticleId, id_article, articles_id
Primary key - id custom_id
Migration - 2017_01_01_000000_create_articles_table 2017_01_01_000000_articles
Method 小駝峰命名 getAll get_all
Method in resource controller 具體看表格 store saveArticle
Method in test class 小駝峰命名 testGuestCannotSeeArticle test_guest_cannot_see_article
Variable 小駝峰命名 $articlesWithAuthor $articles_with_author
Collection 具描述性的復(fù)數(shù)形式 $activeUsers = User::active()->get() $active, $data
Object 具描述性的單數(shù)形式 $activeUser = User::active()->first() $users, $obj
Config and language files index 蛇形命名 articles_enabled ArticlesEnabled; articles-enabled
View 蛇形命名 show_filtered.blade.php showFiltered.blade.php, show-filtered.blade.php
Config 蛇形命名 google_calendar.php googleCalendar.php, google-calendar.php
Contract (interface) 形容詞或名詞 Authenticatable AuthenticationInterface, IAuthentication
Trait 形容詞 Notifiable NotificationTrait
盡可能使用更短、更易讀的語法

壞:

$request->session()->get("cart");
$request->input("name");

好:

session("cart");
$request->name;

更多示例:

通用語法 更短、更可讀的語法
Session::get("cart") session("cart")
$request->session()->get("cart") session("cart")
Session::put("cart", $data) session(["cart" => $data])
$request->input("name"), Request::get("name") $request->name, request("name")
return Redirect::back() return back()
is_null($object->relation) ? $object->relation->id : null } optional($object->relation)->id
return view("index")->with("title", $title)->with("client", $client) return view("index", compact("title", "client"))
$request->has("value") ? $request->value : "default"; $request->get("value", "default")
Carbon::now(), Carbon::today() now(), today()
App::make("Class") app("Class")
->where("column", "=", 1) ->where("column", 1)
->orderBy("created_at", "desc") ->latest()
->orderBy("age", "desc") ->latest("age")
->orderBy("created_at", "asc") ->oldest()
->select("id", "name")->get() ->get(["id", "name"])
->first()->name ->value("name")
使用 IoC 容器或 facades 代替新的 Class

新的 Class 語法創(chuàng)建類時,不僅使得類與類之間緊密耦合,還加重了測試的復(fù)雜度。推薦改用 IoC 容器或 facades。

壞:

$user = new User;
$user->create($request->all());

好:

public function __construct(User $user)
{
    $this->user = $user;
}

....

$this->user->create($request->all());
不要直接從 .env 文件獲取數(shù)據(jù)

將數(shù)據(jù)傳遞給配置文件,然后使用輔助函數(shù)?config()?在應(yīng)用程序中使用數(shù)據(jù)。

壞:

$apiKey = env("API_KEY");

好:

// config/api.php
"key" => env("API_KEY"),

// Use the data
$apiKey = config("api.key");
以標(biāo)準(zhǔn)格式存儲日期,必要時就使用訪問器和修改器來修改日期格式

壞:

{{ Carbon::createFromFormat("Y-d-m H-i", $object->ordered_at)->toDateString() }}
{{ Carbon::createFromFormat("Y-d-m H-i", $object->ordered_at)->format("m-d") }}

好:

// Model
protected $dates = ["ordered_at", "created_at", "updated_at"]
public function getMonthDayAttribute($date)
{
    return $date->format("m-d");
}

// View
{{ $object->ordered_at->toDateString() }}
{{ $object->ordered_at->monthDay }}
其他良好做法

千萬不要在路由文件中放置任何邏輯。

在 Blade 模板中最小化 vanilla PHP 的使用。

更多現(xiàn)代化 PHP 知識,請前往 Laravel / PHP 知識社區(qū)

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

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

相關(guān)文章

  • Laravel 動態(tài)添加 Artisan 命令的最佳實踐

    摘要:初步嘗試既然最常見的注冊命令的方式是修改類中的,那么一般正常人都會從這邊開始下手。又要自己取出實例,又要自己調(diào)用方法,調(diào)用方法之前還有自己先把實例化這么繁瑣,肯定不是運行時添加命令的最佳實踐,所以我決定繼續(xù)尋找更優(yōu)解。 本文首發(fā)于我的博客,原文鏈接:https://blessing.studio/best-... 雖然 Laravel 官方文檔提供的添加 Artisan Command...

    ninefive 評論0 收藏0
  • Laravel最佳實踐--事件驅(qū)動編程

    摘要:事件驅(qū)動編程是圖形用戶界面和其他應(yīng)用程序例如應(yīng)用程序中使用的主要范例,用于執(zhí)行某些操作來響應(yīng)用戶輸入。我們來看一下事件驅(qū)動編程帶來的收益?,F(xiàn)在讓我們看看采用事件驅(qū)動編程方法如何實現(xiàn)上述相同的功能。 在這篇文章中我們將了解到什么是事件驅(qū)動編程以及在Laravel中如何開始構(gòu)建一個事件驅(qū)動應(yīng)用,同時我們還將看到如何通過事件驅(qū)動編程來對應(yīng)用程序的邏輯進(jìn)行解耦。 在開始之前,先說明一下這篇文章...

    Drummor 評論0 收藏0
  • 貓頭鷹的深夜翻譯:在JAVA中記錄日志的十個小建議

    摘要:是指可能導(dǎo)致程序終止的非常嚴(yán)重的時間。具有最高的級別,旨在關(guān)閉中的日志功能。因此為每一個消息選擇一個合適的日志級別是非常重要的。日志的個小建議將日志訪日代碼塊它能顯著的減少因為字符串拼接而帶來的性能的影響。 前言 首先,這篇文章沒有進(jìn)行任何的日志功能的詳細(xì)介紹,而是對日志提出了幾種最佳實踐。適合對日志記錄有所了解的同學(xué)閱讀。下面是正文: JAVA日志管理既是一門科學(xué),又是一門藝術(shù)。科學(xué)...

    venmos 評論0 收藏0
  • Laravel 5.7 最佳實踐和開發(fā)技巧分享

    摘要:當(dāng)查詢數(shù)據(jù)時,本地范圍允許我們創(chuàng)建自己的查詢構(gòu)造器鏈?zhǔn)椒椒?。這樣便會知道這是一個本地范圍并且可以在查詢構(gòu)造器中使用。某些查詢構(gòu)造器不可用或者說可用但是方法名不同,關(guān)于這些請查閱所有集合的方法。 showImg(https://segmentfault.com/img/remote/1460000017877956?w=800&h=267); Laravel 因可編寫出干凈,可用可調(diào)試的...

    ninefive 評論0 收藏0

發(fā)表評論

0條評論

閱讀需要支付1元查看
<