0

I'm trying to create simple search query in db with multiple conditions.

I would like to search in db posts checking tags attached to posts and check searching word in posts title.

So far I made query that checks multiple tags for posts, but I'm struggling now how to check multiple words in post title.

$search = $request['search'];
$searchArr = explode(' ',$request['search']);
$searchTitle = [];

foreach ($searchArr as $search){
    $searchTitle[] = ['title','like', "%$search%"];
}

echo Post::with(['allTags'])->whereHas('allTags', function($query) use ($searchArr) {
    for ($i=0; $i < count($searchArr); $i++) {
        if($i==0) {
            $query->Where('name', $searchArr[$i]);
        }else{
            $query->orWhere('name', $searchArr[$i]);
        }

    }
})->where(['published'=>1])->orWhere([['title','like', "%$search%"],['published','=','1']])->get();

As you see I use the "for" loop to check multiple tags but I can't find a way how to do it in this part of code ->orWhere([['title','like', "%$search%"],['published','=','1']])->get();

Could someone tell me how to do it?

Thank you.

2
  • Small tip for the ->whereHas('allTags' closure: You don't need to use $query->where( for the first constraint, you can use $query->orWhere( for all constraints. Commented May 4, 2018 at 12:30
  • I followed your tip, then query pull out from DB all records from table "post". When I use "Where" for first constraint then everything is fine. Commented May 4, 2018 at 14:35

2 Answers 2

1

As far as i understand you need to use whereRaw method.

Be careful this can lead to SQL Injection

foreach ($searchArr as $search) {
    $searchTitle[] = ['title','like', "%$search%"];
}

You should probably build SQL and then bind using underlying PDO object with whereRaw method:

$searchQuery = implode(',', array_map(function($item) { return 'title like \"?\"'; }, $searchArray));

And then in your query string:

...->whereHas('allTags', function($query) use ($searchQuery, $searchArray) {
    $query->whereRaw($searchQuery, $searchArray, 'or');
})

Even easier if you actually are checking against title on Post

...->whereRaw($searchQuery, $searchArray, 'or')

Also make sure to check comments.

Sign up to request clarification or add additional context in comments.

1 Comment

Thank you for answer. If I use this method am I prof from SQL Injections? foreach ($searchWords as $i){ $searchQuery[] = "title like ?"; } "orWhereRaw($searchQuery,$searchWordsArray)->get()" Is it that underlay PDO statements?
-1

as per my understanding you want to break the words in your search string if it contains multiple words as in the following example:

<?php
$search_term = 'test1 test2 test3';
$keywords = explode(" ", preg_replace("/\s+/", " ", $search_term));
foreach($keywords as $keyword){
 $wherelike[] = "title LIKE '%$keyword%' ";
}
$where = implode(" and ", $wherelike);

$query = "select * from table where $where";

echo $query;

and use Laravel whereRaw() method to execute this as a raw query

1 Comment

Thank you for answer. Why do you use "preg_replace"?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.