惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
小众软件
小众软件
博客园_首页
博客园 - 聂微东
V
V2EX
WordPress大学
WordPress大学
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
罗磊的独立博客
酷 壳 – CoolShell
酷 壳 – CoolShell
博客园 - 司徒正美
博客园 - 三生石上(FineUI控件)
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
S
SegmentFault 最新的问题
J
Java Code Geeks
Last Week in AI
Last Week in AI
The Cloudflare Blog
月光博客
月光博客
雷峰网
雷峰网
宝玉的分享
宝玉的分享
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
Hugging Face - Blog
Hugging Face - Blog
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
有赞技术团队
有赞技术团队
人人都是产品经理
人人都是产品经理
博客园 - Franky
腾讯CDC
Jina AI
Jina AI
博客园 - 叶小钗
大猫的无限游戏
大猫的无限游戏
阮一峰的网络日志
阮一峰的网络日志
量子位
爱范儿
爱范儿
美团技术团队
T
Tailwind CSS Blog
博客园 - 【当耐特】
D
Docker
IT之家
IT之家
V
Visual Studio Blog
P
Proofpoint News Feed
L
LangChain Blog
Engineering at Meta
Engineering at Meta
C
Check Point Blog
G
Google Developers Blog
Google DeepMind News
Google DeepMind News
云风的 BLOG
云风的 BLOG
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
Microsoft Azure Blog
Microsoft Azure Blog
B
Blog RSS Feed
Recorded Future
Recorded Future

mafeifan 的编程技术分享

mafengwo-mp3-downloader | mafeifan 的编程技术分享 示例页面 | mafeifan 的编程技术分享 mafeifan 的编程技术分享 mafeifan 的编程技术分享 mafeifan 的编程技术分享 mafeifan 的编程技术分享 mafeifan 的编程技术分享 mafeifan 的编程技术分享 mafeifan 的编程技术分享 mafeifan 的编程技术分享 mafeifan 的编程技术分享 查看 default namespace 下的 default service account名称 mafeifan 的编程技术分享 检查日志 | mafeifan 的编程技术分享 bridge fdb show dev flannel.1 mafeifan 的编程技术分享 mafeifan 的编程技术分享 mafeifan 的编程技术分享 mafeifan 的编程技术分享 mafeifan 的编程技术分享 mafeifan 的编程技术分享 mafeifan 的编程技术分享 mafeifan 的编程技术分享 mafeifan 的编程技术分享 mafeifan 的编程技术分享 mafeifan 的编程技术分享 mafeifan 的编程技术分享 mafeifan 的编程技术分享 mafeifan 的编程技术分享 mafeifan 的编程技术分享 数据收集原理分析 | mafeifan 的编程技术分享 mafeifan 的编程技术分享 mafeifan 的编程技术分享 mafeifan 的编程技术分享 mafeifan 的编程技术分享 mafeifan 的编程技术分享 mafeifan 的编程技术分享 mafeifan 的编程技术分享 mafeifan 的编程技术分享 mafeifan 的编程技术分享 mafeifan 的编程技术分享 mafeifan 的编程技术分享 mafeifan 的编程技术分享 mafeifan 的编程技术分享 mafeifan 的编程技术分享 几种方法 | mafeifan 的编程技术分享 mafeifan 的编程技术分享 mafeifan 的编程技术分享 mafeifan 的编程技术分享 mafeifan 的编程技术分享 mafeifan 的编程技术分享 mafeifan 的编程技术分享 mafeifan 的编程技术分享 mafeifan 的编程技术分享 mafeifan 的编程技术分享 mafeifan 的编程技术分享 mafeifan 的编程技术分享 mafeifan 的编程技术分享 mafeifan 的编程技术分享 mafeifan 的编程技术分享 mafeifan 的编程技术分享 mafeifan 的编程技术分享 mafeifan 的编程技术分享 mafeifan 的编程技术分享 mafeifan 的编程技术分享 mafeifan 的编程技术分享 mafeifan 的编程技术分享 mafeifan 的编程技术分享 mafeifan 的编程技术分享 mafeifan 的编程技术分享 mafeifan 的编程技术分享 mafeifan 的编程技术分享 mafeifan 的编程技术分享 mafeifan 的编程技术分享 mafeifan 的编程技术分享 mafeifan 的编程技术分享 mafeifan 的编程技术分享 mafeifan 的编程技术分享 mafeifan 的编程技术分享 mafeifan 的编程技术分享 mafeifan 的编程技术分享 mafeifan 的编程技术分享 mafeifan 的编程技术分享 mafeifan 的编程技术分享 mafeifan 的编程技术分享 mafeifan 的编程技术分享 mafeifan 的编程技术分享 mafeifan 的编程技术分享 mafeifan 的编程技术分享 mafeifan 的编程技术分享 mafeifan 的编程技术分享 mafeifan 的编程技术分享 mafeifan 的编程技术分享 check the export on the very top of this document so we can use $do mafeifan 的编程技术分享 mafeifan 的编程技术分享 mafeifan 的编程技术分享 mafeifan 的编程技术分享 延伸 -- 关于前端路由 xdebug 3 和 2 的区别
mafeifan 的编程技术分享
2026-01-16 · via mafeifan 的编程技术分享

单一职责原则

一个类和一个方法应该只有一个责任。

例如:

php

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;
    }
}

更优的写法:

php

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

public function isVerifiedClient()
{
    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;
}

🔝 返回目录

保持控制器的简洁

如果您使用的是查询生成器或原始SQL查询,请将所有与数据库相关的逻辑放入Eloquent模型或Repository类中。

例如:

php

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

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

更优的写法:

php

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();
    }
}

🔝 返回目录

使用自定义Request类来进行验证

把验证规则放到 Request 类中.

例子:

php

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

    ....
}

更优的写法:

php

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',
        ];
    }
}

🔝 返回目录

业务代码要放到服务层中

控制器必须遵循单一职责原则,因此最好将业务代码从控制器移动到服务层中。

例子:

php

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

更优的写法:

php

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');
        }
    }
}

🔝 返回目录

DRY原则 不要重复自己

尽可能重用代码,SRP可以帮助您避免重复造轮子。 此外尽量重复使用Blade模板,使用Eloquent的 scopes 方法来实现代码。

例子:

php

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();
}

更优的写法:

php

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();
}

🔝 返回目录

使用ORM而不是纯sql语句,使用集合而不是数组

使用Eloquent可以帮您编写可读和可维护的代码。 此外Eloquent还有非常优雅的内置工具,如软删除,事件,范围等。

例子:

sql

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

更优的写法:

php

Article::has('user.profile')->verified()->latest()->get();

🔝 返回目录

集中处理数据

例子:

php

$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();

更优的写法:

php

$category->article()->create($request->validated());

🔝 返回目录

不要在模板中查询,尽量使用惰性加载

例子 (对于100个用户,将执行101次DB查询):

php

@foreach (User::all() as $user)
    {{ $user->profile->name }}
@endforeach

更优的写法 (对于100个用户,使用以下写法只需执行2次DB查询):

php

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

...

@foreach ($users as $user)
    {{ $user->profile->name }}
@endforeach

🔝 返回目录

注释你的代码,但是更优雅的做法是使用描述性的语言来编写你的代码

例子:

php

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

加上注释:

php

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

更优的写法:

php

if ($this->hasJoins())

🔝 返回目录

不要把 JS 和 CSS 放到 Blade 模板中,也不要把任何 HTML 代码放到 PHP 代码里

例子:

php

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

更好的写法:

php

<input id="article" type="hidden" value='@json($article)'>

Or

<button class="js-fav-article" data-article='@json($article)'>{{ $article->name }}<button>

在Javascript文件中加上:

javascript

let article = $('#article').val();

当然最好的办法还是使用专业的PHP的JS包传输数据。

🔝 返回目录

在代码中使用配置、语言包和常量,而不是使用硬编码

例子:

php

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

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

更优的写法:

php

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

return back()->with('message', __('app.article_added'));

🔝 返回目录

使用社区认可的标准Laravel工具

强力推荐使用内置的Laravel功能和扩展包,而不是使用第三方的扩展包和工具。 如果你的项目被其他开发人员接手了,他们将不得不重新学习这些第三方工具的使用教程。 此外,当您使用第三方扩展包或工具时,你很难从Laravel社区获得什么帮助。 不要让你的客户为额外的问题付钱。

想要实现的功能标准工具第三方工具
权限PoliciesEntrust, Sentinel 或者其他扩展包
资源编译工具Laravel MixGrunt, Gulp, 或者其他第三方包
开发环境HomesteadDocker
部署Laravel ForgeDeployer 或者其他解决方案
自动化测试PHPUnit, MockeryPhpspec
页面预览测试Laravel DuskCodeception
DB操作EloquentSQL, Doctrine
模板BladeTwig
数据操作Laravel集合数组
表单验证Request classes他第三方包,甚至在控制器中做验证
权限Built-in他第三方包或者你自己解决
API身份验证Laravel Passport, Laravel Sanctum第三方的JWT或者 OAuth 扩展包
创建 APIBuilt-inDingo API 或者类似的扩展包
创建数据库结构Migrations直接用 DB 语句创建
本土化Built-in第三方包
实时消息队列Laravel Echo, Pusher使用第三方包或者直接使用WebSockets
创建测试数据Seeder classes, Model Factories, Faker手动创建测试数据
任务调度Laravel Task Scheduler脚本和第三方包
数据库MySQL, PostgreSQL, SQLite, SQL ServerMongoDB

🔝 返回目录

遵循laravel命名约定

来源 PSR standards.

另外,遵循Laravel社区认可的命名约定:

对象规则更优的写法应避免的写法
控制器单数ArticleControllerArticlesController
路由复数articles/1article/1
路由命名带点符号的蛇形命名users.show_activeusers.show-active, show-active-users
模型单数UserUsers
hasOne或belongsTo关系单数articleCommentarticleComments, article_comment
所有其他关系复数articleCommentsarticleComment, article_comments
表单复数article_commentsarticle_comment, articleComments
透视表按字母顺序排列模型article_useruser_article, articles_users
数据表字段使用蛇形并且不要带表名meta_titleMetaTitle; article_meta_title
模型参数蛇形命名$model->created_at$model->createdAt
外键带有_id后缀的单数模型名称article_idArticleId, id_article, articles_id
主键-idcustom_id
迁移-2017_01_01_000000_create_articles_table2017_01_01_000000_articles
方法驼峰命名getAllget_all
资源控制器tablestoresaveArticle
测试类驼峰命名testGuestCannotSeeArticletest_guest_cannot_see_article
变量驼峰命名$articlesWithAuthor$articles_with_author
集合描述性的, 复数的$activeUsers = User::active()->get()$active, $data
对象描述性的, 单数的$activeUser = User::active()->first()$users, $obj
配置和语言文件索引蛇形命名articles_enabledArticlesEnabled; articles-enabled
视图短横线命名show-filtered.blade.phpshowFiltered.blade.php, show_filtered.blade.php
配置蛇形命名google_calendar.phpgoogleCalendar.php, google-calendar.php
内容 (interface)形容词或名词AuthenticatableAuthenticationInterface, IAuthentication
Trait使用形容词NotifiableNotificationTrait

🔝 返回目录

尽可能使用简短且可读性更好的语法

例子:

php

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

更优的写法:

php

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) ? null : $object->relation->idoptional($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容器来创建实例 而不是直接new一个实例

创建新的类会让类之间的更加耦合,使得测试越发复杂。请改用IoC容器或注入来实现。

例子:

php

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

更优的写法:

php

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

....

$this->user->create($request->validated());

🔝 返回目录

避免直接从 .env 文件里获取数据

将数据传递给配置文件,然后使用config()帮助函数来调用数据

例子:

php

$apiKey = env('API_KEY');

更优的写法:

php

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

// Use the data
$apiKey = config('api.key');

🔝 返回目录

使用标准格式来存储日期,用访问器和修改器来修改日期格式

例子:

php

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

更优的写法:

php

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

// View
{{ $object->ordered_at->toDateString() }}
{{ $object->ordered_at->some_date }}

🔝 返回目录

其他的一些好建议

永远不要在路由文件中放任何的逻辑代码。

尽量不要在Blade模板中写原始 PHP 代码。

🔝 返回目录

原文