我试图根据主键从表中返回一行。

    $product = Product::where('id', '=', $idOrSKU)
        ->orWhere('sku', '=', $idOrSKU)
        ->take(1)->get();

因为某些原因 $idorSKU 正在转换为 和 (int) 在比较发生之前。例如,当 $isOrSKU = "9dfghfd", ,返回 ID=9 的行。为什么是这样?它应该什么也不返回!有人可以解释一下吗?

这是相关的表格方案

| id                         | int(10) unsigned | NO   | PRI | NULL      
| name                       | varchar(255)     | NO   |     | NULL                
| sku                        | varchar(255)     | NO   |     | NULL 
有帮助吗?

解决方案

这与数据库有关,而不是 Laravel,对字符串进行类型转换。因为您正在执行查询 int(10) 列,mySQL 正在强制将您的搜索字符串更改为 int, ,导致您的查询变成 9.

我可以确认以下几点:

$test1 = Test::find('1');
echo $test1->id; // gives 1

$test2 = Test::find('1example');
echo $test2->id; // gives 1

因此你的变量 9dfghfd 因为类型转换为 int (9). 。但如果你的变量是“df9ghfd” - 它不会被类型转换,并且不会匹配。

编辑:该问题会影响其他方面,例如路由模型绑定:

domain.com/product/1

domain.com/product/1thisalsoworks // takes you to the page of ID 1

我已经在 Github 上开了一张票来进一步讨论它 - 所以请查看此处以获取更多信息/讨论。

但总的来说,这个问题并不是 Laravel 的直接错误。

编辑:看来这个问题影响了 GitHub 本身:

这有效: https://github.com/laravel/framework/issues/5254

这也是如此: https://github.com/laravel/framework/issues/5254typecast

其他提示

事实证明,这里使用 PostgreSQL,它的工作方式与你的数据库不同,当我这样做时:

Route::any('test', function()
{
    $code = '181rerum';

    return Ad::where('id', $code)->orWhere('company_code', $code)->first();
});

我收到此错误:

SQLSTATE[22P02]: Invalid text representation: 7 ERROR: invalid input 
syntax for integer: "181rerum" (SQL: select * from "ads" where 
"id" = 181rerum or "company_code" = 181rerum limit 1)

因此,Laravel 知道它是一个整数列,因此不带引号将其直接传递到数据库,这会生成数据库异常,因为 PostgreSQL 甚至不会尝试将该字符串转换为整数。

因此,即使您从 Laravel 核心开发人员那里获得了一些帮助,我认为您也应该始终执行类似的操作来帮助您完成这些混合搜索:

Route::any('test/{id}', function($id)
{
    /// You can always filter by a string here

    $q = Ad::where('company_code', $id);

    /// You just try to filter by id if the search string is entirely numeric

    if (is_numeric($id))
    {
        $q->orWhere('id', $id);
    }

    return $q->first();
});
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top