数据库查询中对 like 的值进行转义 
                            
                                                    
                        
                    
                    
  
                    
                    在laravel中,如果要进行数据库的like模糊查询,可以这么做:
$query->where('title','like' , "%".$keyword."%");
不过这种做法却有几个问题:
- 重复书写like
 $keyword可能包含%和_,这两个特殊字符将能够把数据库中所有的记录都能查找出来。
Laravel China社区的做法是直接把%和_去掉了。
为了避免这种情况,我们可以自定义一个函数将我们的字符进行转义。
function escape_like_str($str)
{
    $like_escape_char = '!';
    return str_replace([$like_escape_char, '%', '_'], [
        $like_escape_char.$like_escape_char,
        $like_escape_char.'%',
        $like_escape_char.'_',
    ], $str);
}
使用时像这样
$query->where('title','like' , "%".escape_like_str($keyword)."%");
或者参考这个trait
<?php
namespace App\Models\Traits;
trait LikeScope
{
    /**
     * @param   \Illuminate\Database\Eloquent\Builder $query
     * @param     $column
     * @param     $value
     * @param     $side
     * @param     $isNotLike
     * @param     $isAnd
     * @return    \Illuminate\Database\Eloquent\Builder
     */
    public function scopeLike($query, $column, $value, $side = 'both', $isNotLike = false, $isAnd = true)
    {
        $operator = $isNotLike ? 'not like' : 'like';
        $escape_like_str = function ($str) {
            $like_escape_char = '!';
            return str_replace([$like_escape_char, '%', '_'], [
                $like_escape_char.$like_escape_char,
                $like_escape_char.'%',
                $like_escape_char.'_',
            ], $str);
        };
        switch ($side) {
            case 'none':
                $value = $escape_like_str($value);
                break;
            case 'before':
            case 'left':
                $value = "%{$escape_like_str($value)}";
                break;
            case 'after':
            case 'right':
                $value = "{$escape_like_str($value)}%";
                break;
            case 'both':
            case 'all':
            default:
                $value = "%{$escape_like_str($value)}%";
                break;
        }
        return $isAnd ? $query->where($column, $operator, $value) : $query->orWhere($column, $operator, $value);
    }
    public function scopeOrLike($query, $column, $value, $side = 'both', $isNotLike = false)
    {
        return $query->like($column, $value, $side, $isNotLike, false);
    }
    public function scopeNotLike($query, $column, $value, $side = 'both', $isAnd = true)
    {
        return $query->like($column, $value, $side, true, $isAnd);
    }
    public function scopeOrNotLike($query, $column, $value, $side = 'both')
    {
        return $query->like($column, $value, $side, true, false);
    }
}
使用方法
<?php
use App\Models\Traits\LikeScope;
use Illuminate\Database\Eloquent\Model;
class MyModel extends Model
{
    use LikeScope;
    public function scopeSearch($query, $keyword)
    {
        return $query->like('title', $keyword);
    }
}
我的代码参考了codeigniter的代码实现,欢迎各位批评或提出建议。如果有更好的方法也请多多指教
           本帖已被设为精华帖!
        
      
                      本帖由系统于 5年前 自动加精
            
                
          
            
            
                    
                    
          
          
                关于 LearnKu
              
                    
                    
                    
 
推荐文章: