为什么 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 个混淆点是如何解决的:
- 通过将我的 Homestead 指向生产数据库,解决了我的代码在生产环境和 Homestead 开发环境之间的差异。我不确定有什么区别(可能是排序规则或 table 格式),但它让我很快就明白了。
- 我试图过滤数据库中的元素列表,但我构建它的逻辑错误 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();
(整数)必须在 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 个混淆点是如何解决的:
- 通过将我的 Homestead 指向生产数据库,解决了我的代码在生产环境和 Homestead 开发环境之间的差异。我不确定有什么区别(可能是排序规则或 table 格式),但它让我很快就明白了。
- 我试图过滤数据库中的元素列表,但我构建它的逻辑错误 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();