为什么 Laravel Controller 需要在 Homestead 中进行(整数)转换,而不是在生产服务器中

Why does Laravel Controller needs (integer) cast in Homestead, but not in production server

(整数)必须在 Homestead 中为控制器参数进行转换

我很难找到本地开发环境 (Homestead) 与托管环境之间存在差异的原因。 我这样定义路线:

Route::get('group/{id}/data', 'GroupDataController@index');

控制器中的代码如下所示:

public function index($id)
{
    return Grouping::all()->where('group_id', $id);
}

这在生产环境(托管环境)中运行良好,但是当我在本地执行它时它抛出并清空数组 [] 除非我将我的控制器函数修改为如下所示:

public function index($id)
{
    return Grouping::all()->where('group_id', (integer)$id);
}

我不知道这里发生了什么,我厌倦了对我的控制器进行更改以使其在两种环境下都能工作。 我在几个地方搜索过,但也许我在搜索时使用了不正确的标记,因为我一无所获。 非常感谢任何帮助。

这里的问题是您没有使用正确的函数集。

当您调用 Grouping::all() 时,这实际上是 returning 一个 Eloquent Collection 对象,其中包含分组 table 中的每条记录。然后,您将在此 Collection 上调用 where() 方法。这会导致两个问题:一是效率极低;二是效率低下。第二,Collection 上的 where() 方法与查询生成器上的 where() 方法不同。

Collection 上的 where() 方法采用三个参数:字段名称、要过滤的字段中的值,最后是一个布尔值,告诉它是否过滤进行严格比较 (===) 或松散比较 (==)。第三个参数默认为strict。这种严格的比较是您遇到问题的原因,但我无法解释为什么一种环境将 $id 视为整数而另一种环境则不然。

查询生成器对象上的 where() 方法实际上会向正在执行的 SQL 语句添加一个 where 子句,这是一种更有效的数据过滤方式。它还具有更大的灵活性,因为它不仅限于等于比较(第二个参数是 where 子句的比较运算符,但如果省略则默认为“=”)。

您有两种选择来解决您的问题。您可以将 false 作为第三个参数传递给当前代码中的 where() 方法(错误),或者您可以更新代码以使用查询实际过滤而不是过滤整个 Collection(好)。

我建议将您的代码更新为:

public function index($id) {
    return Grouping::where('group_id', '=', $id)->get();
}

在上面的代码中,Grouping::where('group_id', '=', $id) 将生成一个具有给定 where 子句的查询构建器对象,然后 get() 将执行查询,return Collection 的结果。

我将@patricus(非常感谢!)标记为正确答案,因为他确实为我指出了正确的方向,让我明白有些关键字在不同的上下文中有不同的作用(比如 get()) ,但我还要指出,在我的案例中我的 2 个混淆点是如何解决的:

  1. 通过将我的 Homestead 指向生产数据库,解决了我的代码在生产环境和 Homestead 开发环境之间的差异。我不确定有什么区别(可能是排序规则或 table 格式),但它让我很快就明白了。
  2. 我试图过滤数据库中的元素列表,但我构建它的逻辑错误 Laravel。

为了清楚我在第二点中提到的内容,我使用了以下代码:

Grouping::all(['id', 'name_id', 'product_id', 'ship_id'])->where('name_id', '=', $id);

我认为这可行,因为它会选择所有项目和选定的列,然后使用 where 子句过滤这些项目。但是我 错了 ,因为我后来发现,正确的写法是:

Grouping::where('name_id', $id)->select('id', 'name_id', 'product_id', 'ship_id')->get();

这是因为我完全忘记了我是在组合查询,而不是编写我希望程序执行的操作。 第二种语法有更多的逻辑,因为我指定了过滤器,然后将列放在过滤的内容上,最后使用 get() 子句执行查询。

当然也可以反着写,读起来更清晰流畅:

Grouping::select('id', 'name_id', 'product_id', 'ship_id')->where('name_id', $id)->get();