Maison > cadre php > Laravel > le corps du texte

Comment démarrer rapidement avec Laravel ? 100 conseils pratiques à partager

青灯夜游
Libérer: 2022-09-27 20:26:23
avant
2503 Les gens l'ont consulté

Comment démarrer rapidement avec Laravel ? 100 conseils pratiques à partager

Pour vous donner quelques conseils sur l'utilisation de Laravel, vous êtes bien sûr les bienvenus sur PR si vous avez des idées !

Adresse Github : https://github.com/LaravelDaily/laravel-tips

Contrôleur

Contrôleur à comportement unique

Lorsque votre contrôleur n'a qu'une seule méthode, vous pouvez aussi bien essayer la méthode __invoke() pour transformer le contrôleur actuel en un contrôleur "invocable". __invoke() 方法来,让当前控制器变身为 “invokable” 控制器。

想要了解单行为控制器的好处以及用法请参考:

单行为控制器的简单使用:

定义路由,如下:

Route::get('user/{id}', 'ShowProfile');
Copier après la connexion

通过命令创建单行为控制器:

php artisan make:controller ShowProfile --invokable
Copier après la connexion

修改控制器代码,如下:

class ShowProfile extends Controller
{
    public function __invoke($id)
    {
        return view('user.profile', [
            'user' => User::findOrFail($id)
        ]);
    }
}
Copier après la connexion

重定向到指定控制器的指定方法

你可以通过 redirect() 重定向到某个路由或者某个链接,但是当你希望重定向到一个特定方法,并且需要携带一些参数的时候,action 方法可以帮你实现,代码如下:

return redirect()->action('SomeController@method', ['param' => $value]);
Copier après la connexion

接口操作成功而无返回的简单处理

当你在接口执行了某些逻辑,但是不需要返回内容的时候,你可以直接返回 204 状态码。 在 Laravel 中这很容易实现:

Tips: 204 状态码说明

public function reorder(Request $request)
{
    foreach ($request->input('rows', []) as $row) {
        Country::find($row['id'])->update(['position' => $row['position']]);
    }

    return response()->noContent();
}
Copier après la connexion

模型

Eloquent 的日期筛选

Laravel 的 Eloquent Orm 提供了 whereDay(), whereMonth(), whereYear(), whereDate()whereTime() 供你对日期进行筛选。简单例子:

$products = Product::whereDate('created_at', '2018-01-31')->get();
$products = Product::whereMonth('created_at', '12')->get();
$products = Product::whereDay('created_at', '31')->get();
$products = Product::whereYear('created_at', date('Y'))->get();
$products = Product::whereTime('created_at', '=', '14:13:58')->get();
Copier après la connexion

Inter 类型数据的便捷操作 Increments(增加) 和 decrements(减少)

你如果仅仅是操作数字类型字段的增加(减少),你可以尝试下  increment()decrement()) 方法:

Post::find($post_id)->increment('view_count');
User::find($user_id)->increment('points', 50);
Copier après la connexion

获取设置当前用户登录的信息

你可以使用 make:observer 来创建一个观察者,然后通过修改模型事件 creating() 来设定当前用户的信息,代码如下 :<br>详细使用可以查阅 Laravel 中的模型事件与 Observer

class PostObserver
{
    public function creating(Post $post)
    {
        $post->user_id = auth()->id();
    }
}
Copier après la connexion

软删除后的数据批量恢复

当使用软删除删除数据之后,你可以通过以下方法批量恢复删除的数据:

Post::withTrashed()->where('author_id', 1)->restore();
Copier après la connexion

特定模型字段的返回

默认的 Model::all() 会返回所有字段,不管你是否有需要,当然你也可以通过给 all() 传递参数来指定返回的列。如下:

$users = User::all(['id', 'name', 'email']);
Copier après la connexion

失败或者成功的查询

findOrFail() 方法,可以在查询没有符合条件数据的时候直接抛出异常。

$user = User::where('email', 'povilas@laraveldaily.com')->firstOrFail();
Copier après la connexion

数据返回的列名称的自定义

在 Eloquent 查询中使用 select 可以设置查询的字段,然后你可以通过 “as” 给字段重命名为你想要的名称:

$users = DB::table('users')->select('name', 'email as user_email')->get();
Copier après la connexion

查询结果的 Map 处理

由于 Eloquent 中,get 方法将返回 Collection 类型的数据,所以在通过 get 方法获取数据之后,你可以直接通过 map() 方法来处理:

$users = User::where('role_id', 1)->get()->map(function (User $user) {
    $user->some_column = some_function($user);
    return $user;
});
Copier après la connexion

不使用 timestamps 相关字段

默认的,laravel 会在 migration 以及 model 中添加 timestamps 相关字段(created_at,updated_at),如果你不想使用他,你可以在migrate 中移除相关字段,或者在 model 中设置 timestamps属性,将该属性设置为 false

Si vous souhaitez connaître les avantages et l'utilisation d'un contrôleur de comportement unique, veuillez vous référer à :

Utilisation simple des contrôleurs à comportement unique :

Définissez les itinéraires comme suit :

class Company extends Model
{
    public $timestamps = false;
}
Copier après la connexion
Créez des contrôleurs à comportement unique via commandes :🎜
class Role extends Model{
    const CREATED_AT = 'create_time';
    const UPDATED_AT = 'update_time';
}
Copier après la connexion
Copier après la connexion
🎜Modifier Le code du contrôleur est le suivant : 🎜
User::orderBy('created_at', 'desc')->get();
Copier après la connexion
Copier après la connexion
🎜🎜🎜Redirection vers la méthode spécifiée du contrôleur spécifié🎜🎜Vous pouvez rediriger vers une route ou un lien via redirect(), mais quand vous le souhaitez Lors de la redirection vers une méthode spécifique et que vous devez transporter certains paramètres, la méthode d'action peut vous aider à l'implémenter. Le code est le suivant : 🎜
User::latest()->get();
Copier après la connexion
Copier après la connexion
🎜🎜🎜Traitement simple d'une opération d'interface réussie sans retour🎜🎜Lorsque vous exécutez certaines opérations. logique sur l'interface, mais lorsque vous n'avez pas besoin de renvoyer du contenu, vous pouvez directement renvoyer le code d'état 204. C'est facile à faire dans Laravel : 🎜🎜🎜Conseils : 204 status Description du code🎜🎜
User::oldest()->get();
Copier après la connexion
Copier après la connexion
🎜🎜🎜Modèle🎜🎜🎜🎜Filtre de date d'Eloquent🎜🎜L'Orm éloquent de Laravel fournit whereDay(), whereMonth() , whereYear(), whereDate() et whereTime() vous permettent de filtrer les dates. Exemple simple : 🎜
$lastUpdatedUser = User::newest('updated_at')->first();
Copier après la connexion
Copier après la connexion
🎜🎜🎜 Opérations pratiques pour les données de type Inter Incréments (augmentation) et décréments (diminution) 🎜🎜Si vous n'opérez que l'augmentation (diminution) des champs de type numérique, vous pouvez essayer increment()(<code>decrement()) Méthode : 🎜
class Country extends Model {
    protected static function boot()
    {
        parent::boot();

        Country::creating(function($model) {
            $model->position = Country::max('position') + 1;
        });
    }
}
Copier après la connexion
Copier après la connexion
🎜🎜🎜Obtenir et définir les informations de connexion de l'utilisateur actuel🎜🎜Vous pouvez utiliser make:observer pour créer un observateur, puis définissez les informations de l'utilisateur actuel en modifiant l'événement de modèle creating(). Le code est le suivant :<br>Pour une utilisation détaillée, vous pouvez vous référer au modèle events et Observer dans Laravel🎜
User::where('active', 1)
    ->whereRaw('TIMESTAMPDIFF(DAY, created_at, updated_at) > ?', 30)
    ->get();
Copier après la connexion
Copier après la connexion
🎜🎜🎜Récupération par lots des données après suppression logicielle🎜🎜Quand utiliser la suppression logicielle pour supprimer des données Après cela, vous pouvez restaurer les données supprimées par lots via les méthodes suivantes : 🎜
public function scopeActive($query) {
    return $query->where('active', 1);
}

public function scopeRegisteredWithinDays($query, $days) {
    return $query->where('created_at', '>=', now()->subDays($days));
}
Copier après la connexion
Copier après la connexion
🎜🎜🎜Retour de champs de modèle spécifiques🎜🎜Le Model::all() par défaut reviendra tous les champs, que vous en ayez besoin ou non, bien sûr, vous pouvez également spécifier les colonnes renvoyées en passant des paramètres à all(). Comme suit : La méthode 🎜
$users = User::registeredWithinDays(30)->active()->get();
Copier après la connexion
Copier après la connexion
🎜🎜🎜Requête échouée ou réussie🎜🎜findOrFail() peut directement lever une exception lorsque la requête ne répond pas aux données conditionnelles. 🎜
// Instead of
$todayUsers = User::whereDate('created_at', now()->toDateString())->get();
// 不需要转换 now()
$todayUsers = User::whereDate('created_at', now())->get();
Copier après la connexion
Copier après la connexion
🎜🎜🎜Personnalisation des noms de colonnes renvoyés par les données🎜🎜Utilisez select dans une requête Eloquent pour définir les champs de la requête, puis vous pouvez renommer le champ avec le nom de votre choix via "as": 🎜
$users = User::all()->groupBy(function($item) {
    return $item->name[0];
});
Copier après la connexion
Copier après la connexion
🎜🎜🎜 Traitement cartographique des résultats de la requête🎜🎜Étant donné que dans Eloquent, la méthode get renverra des données de type Collection, donc après avoir obtenu les données via la méthode get, vous pouvez les traiter directement via la méthode map() : 🎜
class User extends Model
{
    public function setEmailAttribute($value)
    {
        if ($this->email) {
            return;
        }

        $this->attributes['email'] = $value;
    }
}
Copier après la connexion
Copier après la connexion
🎜 🎜🎜N'utilisez pas de champs liés aux horodatages🎜🎜Par défaut, laravel ajoutera des champs liés aux horodatages (created_at, update_at) dans la migration et le modèle. Si vous ne souhaitez pas l'utiliser, vous pouvez supprimer les champs associés dans migrate, ou. définissez-le dans l'attribut timestamps du modèle, définissez cet attribut sur false pour obtenir : 🎜
// Will return Eloquent Model
$user = User::find(1);
// Will return Eloquent Collection
$users = User::find([1,2,3]);
Copier après la connexion
Copier après la connexion
🎜🎜🎜Modifier le champ d'heure par défaut🎜🎜Lorsque vous souhaitez utiliser Laraevl dans un fichier existant base de données Lorsque vous utilisez Eloquent Orm, votre champ horaire est différent du champ par défaut de Laravel. Comment gérer cela ? Vous pouvez définir le champ d'horodatage actuellement utilisé en réaffectant la constante suivante : 🎜
class Role extends Model{
    const CREATED_AT = 'create_time';
    const UPDATED_AT = 'update_time';
}
Copier après la connexion
Copier après la connexion

快速通过 created_at 排序

在此之前你是这样实现的:

User::orderBy('created_at', 'desc')->get();
Copier après la connexion
Copier après la connexion

当然,你也可以使用更简单的方式:

User::latest()->get();
Copier après la connexion
Copier après la connexion

默认 latest() 会通过 created_at 进行排序。

这里还有个反方法可以用: oldest()  将会通过 created_at 字段进行升序排序。

User::oldest()->get();
Copier après la connexion
Copier après la connexion

当然你也可以通过传递参数来执行想要进行排序的字段,如下:

$lastUpdatedUser = User::newest('updated_at')->first();
Copier après la connexion
Copier après la connexion

创建记录时的自增

当你在创建记录的时候,你同时希望对某个字段进行自增操作的时候,你可以在  boot()  方法中注册 creating 方法来实现。举个例子,现在你有个 “position” 字段,你希望在你完成新增操作的时候同时对该字段 +1 ,实现代码如下:

class Country extends Model {
    protected static function boot()
    {
        parent::boot();

        Country::creating(function($model) {
            $model->position = Country::max('position') + 1;
        });
    }
}
Copier après la connexion
Copier après la connexion

使用 whereRaw() 使查询效率更快

使用 whereRaw() 方法,通常可以使查询效率更高。例如你想获取 30+ 天未登录的用户,你可以通过以下实现:

User::where('active', 1)
    ->whereRaw('TIMESTAMPDIFF(DAY, created_at, updated_at) > ?', 30)
    ->get();
Copier après la connexion
Copier après la connexion

多个作用域

你可以同时创建多个作用域,当然可以在一个查询中使用多个作用域。

模型中定义:

public function scopeActive($query) {
    return $query->where('active', 1);
}

public function scopeRegisteredWithinDays($query, $days) {
    return $query->where('created_at', '>=', now()->subDays($days));
}
Copier après la connexion
Copier après la connexion

controller 中使用:

$users = User::registeredWithinDays(30)->active()->get();
Copier après la connexion
Copier après la connexion

Carbon自动转换

如果你想使用 whereDate() 查询今天的记录,你可以通过直接 now() 而无需进行 ->toDateString(),因为他会自动转换。

// Instead of
$todayUsers = User::whereDate('created_at', now()->toDateString())->get();
// 不需要转换 now()
$todayUsers = User::whereDate('created_at', now())->get();
Copier après la connexion
Copier après la connexion

通过首字符分组

你可以通过任意你想实现的方式进行分组,下面是通过对姓名首字符的分组方法:

$users = User::all()->groupBy(function($item) {
    return $item->name[0];
});
Copier après la connexion
Copier après la connexion

限制数据列的更新

如果你希望设置一个不可更新的列,你可以通过以下方式实现:

class User extends Model
{
    public function setEmailAttribute($value)
    {
        if ($this->email) {
            return;
        }

        $this->attributes['email'] = $value;
    }
}
Copier après la connexion
Copier après la connexion

查询多个

Eloquent 方法 find() 可以通过传递数组参数实现多个记录的查询:

// Will return Eloquent Model
$user = User::find(1);
// Will return Eloquent Collection
$users = User::find([1,2,3]);
Copier après la connexion
Copier après la connexion

使用 UUID 替代 自增列

如果你不想在数据表中使用自增列要怎么办?下面叫你如何实现

数据迁移:

Schema::create('users', function (Blueprint $table) {
    // $table->increments('id');
    $table->uuid('id')->unique();
});
Copier après la connexion

模型:

class User extends Model
{
    public $incrementing = false;
    protected $keyType = 'string';

    protected static function boot()
    {
        parent::boot();

        User::creating(function ($model) {
            $model->setId();
        });
    }

    public function setId()
    {
        $this->attributes['id'] = Str::uuid();
    }
}
Copier après la connexion

模型关联

可排序的模型关联

你可以在你的关联中使用 orderBy对关联进行排序:

public function products()
{
    return $this->hasMany(Product::class);
}

public function productsByName()
{
    return $this->hasMany(Product::class)->orderBy('name');
}
Copier après la connexion

有条件的模型关联

如果你在使用模型关联的时候经常需要额外的进行 where 查询,你可以直接通过对关联进行条件查询,实现方式如下:

Model:

public function comments()
{
    return $this->hasMany(Comment::class);
}

public function approved_comments()
{
    return $this->hasMany(Comment::class)->where('approved', 1);
}
Copier après la connexion

对结果的筛选:havingRaw()

你可以在各种地方使用 RAW DB 查询,包括  groupBy()  和 havingRaw() 后面:

Product::groupBy('category_id')->havingRaw('COUNT(*) > 1')->get();
Copier après la connexion

Eloquent has() 方法可以作用于深层的关联

Eloquent has() 方法可以通过 books.ratings 的方式,而使查询可以做用于更深层的关联上!

// Author -> hasMany(Book::class);
// Book -> hasMany(Rating::class);
$authors = Author::has('books.ratings')->get();
Copier après la connexion

通过 Has 方法对 hasMany 数据限制

在一对多关联中, hasMany() 允许通过 has() 方法进行关联数据条数的限制:

// Author -> hasMany(Book::class)
$authors = Author::has('books', '>', 5)->get();
Copier après la connexion

模型默认值

你可以通过 belongsTo 关联, to avoid fatal errors when calling it like {{ $post->user->name }} if $post->user doesn’t exist.

public function user()
{
    return $this->belongsTo('App\User')->withDefault();
}
Copier après la connexion

一次性创建多条关联记录

如果你定义了 hasMany()  关联,你可以通过 saveMany() 来一次性创建多条关联数据:

$post = Post::find(1);
$post->comments()->saveMany([
    new Comment(['message' => 'First comment']),
    new Comment(['message' => 'Second comment']),
]);
Copier après la connexion

快速且精确的加载

通过 with 你可以获取关联表甚至特定字段信息:

$users = App\Book::with('author:id,name')->get();
Copier après la connexion

你可以使用他获取更深一层次的关联:

$users = App\Book::with('author.country:id,name')->get();
Copier après la connexion

上级信息的级联更新

例如你想在更新评论信息的时候想同时更新上级关联的帖子信息的 updated_at 字段,你可以通过指定 $touch 属性实现:

class Comment extends Model{
    protected $touches = ['post'];
 }
Copier après la connexion

总是检测关联是否存在

永远不要在未检测关联是否存在的情况下使用 $model->relationship->field

It may be deleted for whatever reason, outside your code, by someone else’s queued job etc.

可以通过 if-else,在 Blade 中使用 {{ $model->relationship->field ?? '' }} , 或者 {{ optional($model->relationship)->field }} 进行检测。

使用 withCount() 获取记录条数

如果你定义了 hasMany() 关联,当你想要统计关联数据的数量的时候,尝试下 withCount 吧。例子, 假如你有一个 Post 模型,该模型会有多个 Comments 关联,看下如何使用 withCount() 吧:

public function index(){
    $users = User::withCount(['posts', 'comments'])->get();
    return view('users', compact('users'));
 }
Copier après la connexion

然后在模板文件中使用  {relationship}_count 属性就可以获取相应的数据统计了:

@foreach ($users as $user)
<tr>
    <td>{{ $user->name }}</td>
    <td class="text-center">{{ $user->posts_count }}</td>
    <td class="text-center">{{ $user->comments_count }}</td>
</tr>
@endforeach
Copier après la connexion

关联查询的筛选条件

如果你想要在加载关联的时候做一些条件限制,可以通过回调函数实现。例如你想获取国家的前3个城市,可以通过以下代码实现:

$countries = Country::with(['cities' => function($query) {
    $query->orderBy('population', 'desc');
    $query->take(3);}])->get();
Copier après la connexion

始终加载关联

你即可以通过 $with 属性设置模型始终会加载的关联,也可以在构造函数中动态处理加载项:

class ProductTag extends Model
{
    protected $with = ['product'];

    public function __construct() {
        parent::__construct();
        $this->with = ['product'];

        if (auth()->check()) {
            $this->with[] = 'user';
        }
    }
}
Copier après la connexion

belongsTo 和 hasMany 的使用

定义 belongsTo 关联和 hasMany 关联,这样可以在创建关联数据的时候有由系统填充关联字段信息:

// 如果定义了 Post -> belongsTo(User), and User -> hasMany(Post)...
// 以前你需要这样创建文章信息...
Post::create([
    'user_id' => auth()->id(),
    'title' => request()->input('title'),
    'post_text' => request()->input('post_text'),
]);

// 现在,你可以这样
auth()->user()->posts()->create([
    'title' => request()->input('title'),
    'post_text' => request()->input('post_text'),
]);
Copier après la connexion

自定义归属关联名称

使用 as 可以重命名您的关联:

模型中定义:

public function podcasts() {
    return $this->belongsToMany('App\Podcast')
        ->as('subscription')
        ->withTimestamps();
}
Copier après la connexion

控制器中使用:

$podcasts = $user->podcasts();foreach ($podcasts as $podcast) {
    // instead of $podcast->pivot->created_at ...
    echo $podcast->subscription->created_at;
}
Copier après la connexion

数据迁移

迁移执行顺序

通过修改迁移文件的时间戳前缀可以达到排序迁移执行数据的目的。例如:将2018_08_04_070443_create_posts_table.php 修改为 2018_07_04_070443_create_posts_table.php ( 修改 2018_08_042018_07_04 ).

Migration 设定时间戳时区

迁移中 timestamps()timestampsTz() 都可以设定时区。

Schema::create('employees', function (Blueprint $table) {
    $table->increments('id');
    $table->string('name');
    $table->string('email');
    $table->timestampsTz();
});
Copier après la connexion

另外还有 dateTimeTz(), timeTz(), timestampTz(), softDeletesTz().

数据 Migrations 类型

一些特定值得迁移类型:

$table->geometry('positions');
$table->ipAddress('visitor');
$table->macAddress('device');
$table->point('position');
$table->uuid('id');
Copier après la connexion

更多类型查阅: official documentation.

默认时间戳

通过 timestamp() 设定列为时间戳类型,通过<br>useCurrent() 设定该列的默认值。

$table->timestamp('created_at')->useCurrent();
$table->timestamp('updated_at')->useCurrent();
Copier après la connexion

视图

foreach 中 $loop 的使用

通过 $loop 判断该数据是否是最先/最后的数据:

@foreach ($users as $user)
     @if ($loop->first)
        This is the first iteration.
     @endif

     @if ($loop->last)
        This is the last iteration.
     @endif

     <p>This is user {{ $user->id }}</p>
@endforeach
Copier après la connexion

当然他还有其他可用属性例如: $loop->iteration$loop->count.<br>详情阅读: official documentation.

如何判断 View 是否存在?

在你加载 view 之前你可以判断 view 是否存在,从而避免不必要的错误显示。

if (view()->exists('custom.page')) {
 // Load the view
 }
Copier après la connexion

你可以提供多个 view 供选择:

return view()->first(['custom.dashboard', 'dashboard'], $data);
Copier après la connexion

错误模板页面

快速创建特定错误的页面,你只要以该错误code命名并创建相应的 blade 即可。例如: 500(resources/views/errors/500.blade.php)/403(resources/views/errors/403.blade.php),系统会通过相应的 code 自动匹配错误显示页面。

直接使用 view

可以直接在路由中绑定需要显示的 view:

// 在 controller 绑定 view
Route::get('about', 'TextsController@about');
class TextsController extends Controller
{
    public function about()
    {
        return view('texts.about');
    }
}
// 直接在路由中绑定
Route::view('about', 'texts.about');
Copier après la connexion

Blade @auth

在 Blade 中直接使用 auth() 可以判断以及获取当前登录的用户信息:

例子:

@if(auth()->user())
    // 用户已登录
@endif
Copier après la connexion

或者更简单的方式:

@auth
    // 鉴权通过
@endauth
Copier après la connexion

相反的方法 @guest

@guest    
// 鉴权未通过
@endguest
Copier après la connexion

Blade中循环嵌套中使用 $loop

Blade 循环嵌套,可以通过 $loop 获取上层数据:

@foreach ($users as $user)
    @foreach ($user->posts as $post)
        @if ($loop->parent->first)
            This is first iteration of the parent loop.
        @endif
    @endforeach
@endforeach
Copier après la connexion

自定义 Blade 指令

Laravel 提供了简单的方式自定义 Blade 指令,只需在  app/Providers/AppServiceProvider.php 注册自己的指令即可。例子:你想要使用新的标签替换 <br> 标签:

<textarea>@br2nl($post->post_text)</textarea>
Copier après la connexion

将该指令添加到 AppServiceProvider 的  boot() 方法中:

public function boot()
{
    Blade::directive('br2nl', function ($string) {
        return "<?php echo preg_replace(&#39;/\<br(\s*)?\/?\>/i', \"\n\", $string); ?>";
    });
}
Copier après la connexion

Blade 指令说明: IncludeIf, IncludeWhen, IncludeFirst

当你不确定 Blade 的组件是否存在的时候可以使用一下方法:

仅仅在存在时加载该组件:

@includeIf('partials.header')
Copier après la connexion

仅仅在有权限的时候加载该组件

@includeWhen(auth()->user()->role_id == 1, 'partials.header')
Copier après la connexion

当该组件不存在时,会加载默认组件:

@includeFirst('adminlte.header', 'default.header')
Copier après la connexion

路由

路由组嵌套

路由组可以使用嵌套:

Route::group(['prefix' => 'account', 'as' => 'account.'], function() {
    Route::get('login', 'AccountController@login');
    Route::get('register', 'AccountController@register');

    Route::group(['middleware' => 'auth'], function() {
        Route::get('edit', 'AccountController@edit');
    });
});
Copier après la connexion

子域通配符

你可以通过动态子域名创建相应的路由:

Route::domain('{username}.workspace.com')->group(function () {
    Route::get('user/{id}', function ($username, $id) {
        //
    });
});
Copier après la connexion

What’s behind the routes?

Auth::routes() 下包含了那些路由呢?<br>你可以在 /vendor/laravel/ui/src/AuthRouteMethods.php 找到:

public function auth()
{
    return function ($options = []) {
        // Authentication Routes...
        $this->get('login', 'Auth\LoginController@showLoginForm')->name('login');
        $this->post('login', 'Auth\LoginController@login');
        $this->post('logout', 'Auth\LoginController@logout')->name('logout');
        // Registration Routes...
        if ($options['register'] ?? true) {
            $this->get('register', 'Auth\RegisterController@showRegistrationForm')->name('register');
            $this->post('register', 'Auth\RegisterController@register');
        }
        // Password Reset Routes...
        if ($options['reset'] ?? true) {
            $this->resetPassword();
        }
        // Password Confirmation Routes...
        if ($options['confirm'] ?? class_exists($this->prependGroupNamespace('Auth\ConfirmPasswordController'))) {
            $this->confirmPassword();
        }
        // Email Verification Routes...
        if ($options['verify'] ?? false) {
            $this->emailVerification();
        }
    };
}
Copier après la connexion

Laravel 7 之前, 存在与文件 /vendor/laravel/framework/src/illuminate/Routing/Router.php

路由注入绑定

你可以通过绑定 user 参数 Route::get('api/users/{user}', function (App\User $user) { … } - 不仅仅可以通过自增 ID 字段筛选,也可以使用 {user}username 字段筛选,只要在模型中这样处理即可:

public function getRouteKeyName() {
    return 'username';
}
Copier après la connexion

快速定义路由控制器

在此之前,你可能这样写:

Route::get('page', 'PageController@action');
Copier après la connexion

上面写法在编辑器中无法从 route 直接跳转到相应的 controller 中,尝试一下方法:

Route::get('page', [\App\Http\Controllers\PageController::class, 'action']);
Copier après la connexion

现在你可以在编辑器中直接点击 PageController 编辑器会根据路径自动找到相关文件(这需要你的编辑器支持,像 phpstorm)。

路由默认值

如果你你不想在路由匹配失败时显示 404 错误页面,你可以通过回调函数设置默认显示内容,这样在路由匹配失败的时候会直接显示你自定义的内容:

Route::group(['middleware' => ['auth'], 'prefix' => 'admin', 'as' => 'admin.'], function () {
    Route::get('/home', 'HomeController@index');
    Route::resource('tasks', 'Admin\TasksController');
});

// 其他路由
Route::fallback(function() {
    return 'Hm, why did you land here somehow?';
});
Copier après la connexion

使用正则验证路由参数

我们可以直接在路由定义时使用  “where” 方法验证路由参数。一个非常典型的情况是在路由的前面加上语言设置, 像 fr/blogen/article/333 这样。我们如何确保这两个首字母不用于语言以外的其他字符串?

routes/web.php:

Route::group([
    'prefix' => '{locale}',
    'where' => ['locale' => '[a-zA-Z]{2}']
], function () {
    Route::get('/', 'HomeController@index');
    Route::get('article/{id}', 'ArticleController@show');
});
Copier après la connexion

全局,访客,用户的限流

你可以通过 throttle:60,1 来限制单位时间内请求某个可连接的此处:

Route::middleware('auth:api', 'throttle:60,1')->group(function () {
    Route::get('/user', function () {
        //
    });
});
Copier après la connexion

你可以针对不同用户组进行不同限制:

// maximum of 10 requests for guests, 60 for authenticated users
Route::middleware('throttle:10|60,1')->group(function () {
    //
});
Copier après la connexion

Also, you can have a DB field users.rate_limit and limit the amount for specific user:

Route::middleware('auth:api', 'throttle:rate_limit,1')->group(function () {
    Route::get('/user', function () {
        //
    });
});
Copier après la connexion

路由的Query params 参数设置

你可以通过 route 方法第二个参数,以数组的形式将query 参数绑定到路由:

Route::get('user/{id}/profile', function ($id) {
    //
})->name('profile');

$url = route('profile', ['id' => 1, 'photos' => 'yes']); // Result: /user/1/profile?photos=yes
Copier après la connexion

验证

图片验证

你可以验证上传图片的尺寸:

['photo' => 'dimensions:max_width=4096,max_height=4096']
Copier après la connexion

自定义验证错误消息

可以自定义现有规则的错误消息,只需要创建相应的语言文件即可 resources/lang/xx/validation.php

'custom' => [
     'email' => [
        'required' => 'We need to know your e-mail address!',
     ],
],
Copier après la connexion

时间验证中的 “now” 和 “yesterday”关键字

您可以通过 before/after 规则来验证日期,并将各种字符串作为参数传递,例如:tomorrow, now, yesterday。 例如:'start_date' => 'after:now'。 它在底层使用 strtotime() 验证。

$rules = [
    'start_date' => 'after:tomorrow',
    'end_date' => 'after:start_date'
];
Copier après la connexion

有条件的验证规则

如果你的验证规则需要同时满足额外的条件,在  FormRequest 方法中定义 withValidator()  添加你的条件即可:

use Illuminate\Validation\Validator;
class StoreBlogCategoryRequest extends FormRequest {
    public function withValidator(Validator $validator) {
        if (auth()->user()->is_admin) {
            $validator->addRules(['some_secret_password' => 'required']);
        }
    }
}
Copier après la connexion

自定义验证消息

通过FormRequestmessages() 方法,你可以自定义验证错误提示信息:

class StoreUserRequest extends FormRequest
{
    public function rules()
    {
        return ['name' => 'required'];
    }

    public function messages()
    {
        return ['name.required' => 'User name should be real name'];
    }
}
Copier après la connexion

验证前置操作

验证前置操作,如果你需要在验证之前对某些字段做一些处理, prepareForValidation() 可以实现该功能:

protected function prepareForValidation()
{
    $this->merge([
        'slug' => Illuminate\Support\Str::slug($this->slug),
    ]);
}
Copier après la connexion

遇到错误时终止验证

默认情况下,laraevl 会在处理完成所有验证规则之后,将错误信息一并返回;当然如果你想在遇到第一个错误的时候就终止继续往下的验证你可以通过添加一下规则: bail

$request->validate([
    'title' => 'bail|required|unique:posts|max:255',
    'body' => 'required',
]);
Copier après la connexion

Policies

一次性检测多个权限

@can Blade 指令可以检测当前用户是否有某个权限,但是当场景复杂点要怎么处理?比如当我在同时拥有多个权限才能进行某个操作的时候? @canany 指令了解下:

@canany(['update', 'view', 'delete'], $post)
    // 当前用户拥有以下其权限: 更新,显示或者删除文章
    @elsecanany(['create'], \App\Post::class)
    // 当前用户无法创建文章
    @endcanany
Copier après la connexion

集合

不要在集合过滤中使用 NULL

你可以在 Eloquent 中使用 Null  过滤,但是在集合( collection )中,Null 过滤将不会生效:

// 这样可以
$messages = Message::where('read_at is null')->get();

// 这样无法正常返回
$messages = Message::all();
$unread_messages = $messages->where('read_at is null')->count();

// 这样也可以
$unread_messages = $messages->where('read_at', '')->count();
Copier après la connexion

在集合上使用自定义 groupBy 回调

如果你想根据某些条件对结果进行分组处理,并且该条件列并非数据库字段,你可以通过 GroupBy 回调实现。

例如,如果你想按注册日期对用户进行分组,代码如下:

$users = User::all()->groupBy(function($item) {
    return $item->created_at->format('Y-m-d');
});
Copier après la connexion

⚠️ Notice: User::all() 将返回集合类型数据,因此这是在集合上进行的 GroupBy 操作

集合的复用

当你在查询结果上使用  ->all() 或者 ->get() 方法的时候,该操作是针对结果集合进行的操作,不会再额外的进行查询操作。

$users = User::all();
echo 'Max ID: ' . $users->max('id');
echo 'Average age: ' . $users->avg('age');
echo 'Total budget: ' . $users->sum('budget');
Copier après la connexion

鉴权

你链接 Auth::once() 吗?

Auth::once() 可以用于构建无状态请求,他不会产生任何 cookie信息,这很有利于接口的开发:

if (Auth::once($credentials)) {
    //
}
Copier après la connexion

更新密码同时更新用户 token

在更新用户密码的同时更新用户 token 很有必要:

模型:

public function setPasswordAttribute($value){
    $this->attributes['password'] = $value;
    $this->attributes['api_token'] = Str::random(100);
}
Copier après la connexion

邮件

将测试邮件存储到 laravel.log

开发过程中,你可能需要测试邮件发送,但是你有不希望测试邮件真正发送到客户邮箱,这时候你可以通过配置 .env 参数 MAIL_DRIVER=log 这样,邮件将会以文本的形式存储到 storage/logs/laravel.log ,而不会真正发送出去。

邮件预览

如果你使用 Mailables 为发送邮件提供服务,那么你可以直接在浏览器中浏览邮件预览,而不必真正的发送:

Route::get('/mailable', function () {
    $invoice = App\Invoice::find(1);
    return new App\Mail\InvoicePaid($invoice);
});
Copier après la connexion

Laravel 通知的默认主题(subject)

如果你在使用 toMail() 发送邮件通知的时候,未指定相关主题(subject)laravel 提供了默认参数可以使用:

因此,你只需要有:

class UserRegistrationEmail extends Notification {
    //
 }
Copier après la connexion

然后你就可以在注册完成收到一封注册邮件提醒。

发送通知

你可以通过 $user->notify() 发送通知给特定用户,你也可以通过 Notification::route() 发送给任何其他需要通知的地方:

Notification::route('mail', 'taylor@example.com')
        ->route('nexmo', '5555555555')
        ->route('slack', 'https://hooks.slack.com/services/...')
        ->notify(new InvoicePaid($invoice)
);
Copier après la connexion

Artisan

Artisan 命令参数

当我们创建我们的 Artisan 命令的时候,可以通过 $this->confirm(), $this->anticipate(), $this->choice()  等方法询问并要求输入参数:

// 确认框
if ($this->confirm('Do you wish to continue?')) {
    //
}

// 附加可选项
$name = $this->anticipate('What is your name?', ['Taylor', 'Dayle']);

// 附加默认值
$name = $this->choice('What is your name?', ['Taylor', 'Dayle'], $defaultIndex);
Copier après la connexion

维护模式

页面维护模式实现如下:

php artisan down
Copier après la connexion

执行上面命令后,再访问站点的时候会得到 503 错误信息。

你也可以通过提供参数实现而外的效果:

  • message 参数指定显示信息
  • retry 参数设定页面重载时间
  • allow 允许访问的 IP
    php artisan down --message="Upgrading Database" --retry=60 --allow=127.0.0.1
    Copier après la connexion

当维护完成,运行一下命令上线吧!

php artisan up
Copier après la connexion

数据工厂

Factory 的回调方法

有时候,你某些数据的插入/修改需要基于其他数据的完成,这时你可以通过回调方法实现,例子如下:

$factory->afterCreating(App\User::class, function ($user, $faker) {
    $user->accounts()->save(factory(App\Account::class)->make());
});
Copier après la connexion

通过 Seeds/Factories 生成图片

Faker能生成的不仅仅是文本,还可以生成指定大小的图像:

$factory->define(User::class, function (Faker $faker) {
    return [
        'name' => $faker->name,
        'email' => $faker->unique()->safeEmail,
        'email_verified_at' => now(),
        'password' => bcrypt('password'),
        'remember_token' => Str::random(10),
        'avatar' => $faker->image(storage_path('images'), 50, 50)
    ];
});
Copier après la connexion

日志和调试

给日志记录传递参数

你可以通过 Log::info() 来记录日志,或者 info() 快捷方法可以实现同样的效果。

Log::info('User failed to login.', ['id' => $user->id]);
Copier après la connexion

更方便的方法 DD

你可以直接通过在查询结果之后的 ->dd() 操作来打印结果。

// Instead of
$users = User::where('name', 'Taylor')->get();
dd($users);
// Do this
$users = User::where('name', 'Taylor')->get()->dd();
Copier après la connexion

【相关推荐:laravel视频教程

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Étiquettes associées:
source:learnku.com
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal
À propos de nous Clause de non-responsabilité Sitemap
Site Web PHP chinois:Formation PHP en ligne sur le bien-être public,Aidez les apprenants PHP à grandir rapidement!