Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Laravel - Eloquent converts query parameter to integer before comparison

I'm trying to return a single row from a table based on the primary key.

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

For some reason $idorSKU is being converted to and (int) before the comparison happens. For example, when $isOrSKU = "9dfghfd", the row with ID=9 is returned. Why is this? It should return nothing at all! Can someone explain this?

Here is the relevant table scheme

| id                         | int(10) unsigned | NO   | PRI | NULL      
| name                       | varchar(255)     | NO   |     | NULL                
| sku                        | varchar(255)     | NO   |     | NULL 
like image 206
Jen Zhang Avatar asked Jul 29 '14 03:07

Jen Zhang


Video Answer


1 Answers

This is related to the database, not Laravel, typecasting your string. Because you are doing a query on an int(10) column, mySQL is forcably changing your search string to an int, causing your query to become 9.

I can confirm the following:

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

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

Therefore your variable of 9dfghfd because typecast to int (9). But if your variable was "df9ghfd" - it would not be typecast, and it wont match.

Edit: The issue affects other things, like Route model binding:

domain.com/product/1

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

I've opened a ticket on Github to discuss it further - so check here for further information/discussion.

But overall the issue is not a direct fault of Laravel.

Edit: seems the issue affects GitHub itself:

This works: https://github.com/laravel/framework/issues/5254

And so does this: https://github.com/laravel/framework/issues/5254typecast

like image 166
Laurence Avatar answered Sep 28 '22 04:09

Laurence