我试图根据主键从表中返回一行。
$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
答案 0 :(得分:4)
这与数据库有关,而不是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
I've opened a ticket on Github to discuss it further - 请点击此处查看更多信息/讨论。
但总体而言,这个问题不是Laravel的直接错误。
编辑:似乎问题会影响GitHub 本身:
这有效:https://github.com/laravel/framework/issues/5254
这样做:https://github.com/laravel/framework/issues/5254typecast
答案 1 :(得分:1)
事实证明,在这里,当我这样做时,使用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();
});