Laravel-Eloquent преобразует параметр запроса в целое число перед сравнением

Я пытаюсь вернуть одну строку из таблицы на основе первичного ключа.

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

почему-то $idorSKU преобразуется в and (int) прежде чем сравнение произойдет. Например, когда $isOrSKU = "9dfghfd", возвращается строка с ID=9. Почему так? Он вообще ничего не должен возвращать! Кто-нибудь может это объяснить?

вот соответствующая таблица scheme

| id                         | int(10) unsigned | NO   | PRI | NULL      
| name                       | varchar(255)     | NO   |     | NULL                
| sku                        | varchar(255)     | NO   |     | NULL 

2 ответов


это связано с базой данных, а не Laravel, типизация вашей строки. Потому что вы делаете запрос на :

это работает: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 core, я думаю, вы всегда должны делать что - то вроде это, чтобы помочь вам сделать эти смешанное поиск:

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();
});