许多PHP开发人员已经知道Laravel编写优雅、可工作和可调试的代码。它还支持很多很多特性,这些特性有时没有列在文档中,或者曾经列在文档中,但是由于各种原因被删除了。

我在工作中使用Laravel开发产品已经2年了,我一直学习从编写糟糕的代码到优雅的代码,自从第一次使用Laravel编写代码以来,我就一直在从中受益,我将向您展示在使用Laravel编写代码时可能会帮助您的神秘技巧。

当您需要查询内容时,请使用local scopes

Laravel有一种很好的方法,可以使用Query Builder为数据库驱动程序编写查询,像这样:

1
$orders = Order::where('status', 'delivered')->where('paid', true)->get();

这段代码看起来很好。这让我放弃了SQL,专注于编写对我来说更容易理解的代码。但是如果我们使用局部作用域(local scopes),这段代码可以写得更好。

局部作用域(local scopes)允许我们创建自己的查询生成器(Query Builder)方法,当我们试图检索数据时,我们可以使用这些方法来进行链接。例如,我们可以使用->delivered()->paid()方法以更简洁的方式替换掉->where()语句。

首先,在我们的Order模型,我们应该添加如下方法:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
class Order extends Model
{
   ...
   public function scopeDelivered($query) {
      return $query->where('status', 'delivered');
   }
   public function scopePaid($query) {
      return $query->where('paid', true);
   }
}

在使用local scopes时,应该使用scope[Something]为前缀命名方法名。通过这种方式,Laravel将知道这是一个scope修饰的方法,并将在查询生成器(Query Builder)中使用它。确保包含的第一个参数是被Laravel自动注入并且是Query Builder的实例。

1
$orders = Order::delivered()->paid()->get();

对于更多动态的检索,可以使用动态局部作用域(dynamic local scopes)。每个作用域(scope )允许您提供参数。

1
2
3
4
5
6
7
8
class Order extends Model
{
   ...
   public function scopeStatus($query, string $status) {
      return $query->where('status', $status);
   }
}
$orders = Order::status('delivered')->paid()->get();

在后面的文章,您将了解为什么应该对数据库字段使用snake_case,这是第一个原因:Laravel默认使用where[Something]来替换前面的作用域。所以你可以做的是:

1
Order::whereStatus('delivered')->paid()->get();

Laravel将要从where[Something]中搜索snake_case版本。如果您的数据表中有状态,您可以使用前面的示例。如果你有shipping_status字段,你也可以使用如下方式:

1
Order::whereShippingStatus('delivered')->paid()->get();

这是你的选择!