我的方法是这样的:
public function getTopProduct($num, $category_id, $price)
{
if($category_id) {
$cache_category_key = 'top-product-category-'.$category_id;
if(cache($cache_category_key))
return cache($cache_category_key);
$category_condition = 'AND d.category_id = :category_id';
$price_condition = '';
$param = ['category_id'=>$category_id, 'num'=>$num];
}
else {
if($price)
$price_cache = $price['min'].$price['max'];
else
$price_cache = '';
$cache_price_key = 'top-product-price-'.$price_cache;
if(cache($cache_price_key))
return cache($cache_price_key);
$category_condition = '';
if($price) {
$price_condition = 'AND x.price >= :price_min AND x.price <= :price_max';
$param = ['price_min'=>$price['min'], 'price_max'=>$price['max'], 'num'=>$num];
}
else{
$price_condition = '';
$param = ['num'=>$num];
}
}
$query_top_product = '
SELECT x.id, x.store_id, x.name, x.photo, x.price, x.total_sold, y.name AS store_name, y.address
FROM products x
JOIN stores y ON y.id = x.store_id
WHERE x.id = (
SELECT a.id
FROM products a
JOIN stores b ON b.id = a.store_id
JOIN users c ON c.id = b.user_id
JOIN products_categories d ON d.product_id = a.id
WHERE a.status = 1 AND a.stock > 0 AND a.deleted_at IS NULL AND b.status = 1 '.$category_condition.' AND a.store_id = x.store_id AND c.updated_at >= DATE(NOW()) - INTERVAL 3 DAY
ORDER BY a.created_at DESC, a.updated_at DESC
LIMIT 1
)
'.$price_condition.'
LIMIT :num
';
//see for protection in db raw http://fideloper.com/laravel-raw-queries
$products = DB::select(DB::raw($query_top_product),$param);
if($category_id)
Cache::forever('top-product-category-'.$category_id,$products);
else {
if($price)
$price_cache = $price['min'].$price['max'];
else
$price_cache = '';
Cache::forever('top-product-price-'.$price_cache,$products);
}
return $products;
}
上面的方法有效。但是当我使用 https://insight.sensiolabs.com 检查我的项目时,存在这样的错误:
If provided by the user, the value of $category_condition may allow an SQL injection attack. Avoid concatenating parameters to SQL query strings, and use parameter binding instead.
而我使用参数绑定(bind)
我仍然很困惑如何解决我的问题。因为从我的案例来看需要这样的代码。我想使用 laravel eloquent。但从我的查询来看,这似乎很难
从上面的代码中,我还使用了缓存。所以如果它的缓存已经存在,它就会从缓存中抓取
如何解决该错误?
最佳答案
Laravel 默认带有 Mysql 注入(inject)保护,你只需要使用 Eloquent 或 Query Builder,例如:
$users = User::select('*');
if ($request->has('only_active')) {
$users->where('active', true);
}
if ($request->has('search')) {
$users->where('name', 'like', '%'.$request->search.'%');
}
// a lot of more filters you can add...
return $users->get();
Laravel 还提供 support for joins您可以使用 Eloquent 或查询生成器进行申请
关于mysql - 如何在 Laravel 查询上添加条件而不可能允许 SQL 注入(inject)攻击?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47513821/