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

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

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

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

Вот соответствующая схема таблицы

| id                         | int(10) unsigned | NO   | PRI | NULL      
| name                       | varchar(255)     | NO   |     | NULL                
| sku                        | varchar(255)     | NO   |     | NULL 
7 голосов | спросил Jen Zhang 29 J000000Tuesday14 2014, 07:56:21

2 ответа


0

Это относится к базе данных, а не к 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

ответил Laurence 29 J000000Tuesday14 2014, 09:19:11
0

Оказывается, что здесь, используя 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();
});
ответил Antonio Carlos Ribeiro 29 J000000Tuesday14 2014, 20:36:48

Похожие вопросы

Популярные теги

security × 330linux × 316macos × 2827 × 268performance × 244command-line × 241sql-server × 235joomla-3.x × 222java × 189c++ × 186windows × 180cisco × 168bash × 158c# × 142gmail × 139arduino-uno × 139javascript × 134ssh × 133seo × 132mysql × 132