I currently have a single search field searching against multiple columns using this code:

$searchArray = explode(" ", $searchVal);
$query="SELECT * FROM users WHERE ";
$i=0;
foreach ($searchArray as $word) {
    if ($i != 0) $query .= " OR ";
    $query .= " MATCH (`first_name`, `last_name`, `email`) AGAINST ('".$word."*'  IN BOOLEAN MODE)";
    $i++;
}

Lets say I have these two rows in the table:

id | last_name | first_name | email
1  | Smith     | John       | john_smith@js.com
2  | Smith     | Bob        | bob_smith@js.com

If I type in "John S", only the first result shows which is the desired behavior.

If I type in "John Smith", only the first result shows which is the desired behavior.

If I type "Smith J", both results show even though Bob is not a match.

If I type "Smith John", both results show even though Bob is not a match.

Lastly, if I type "Jo S", no results are returned despite the partial match on "Jo" and "S".

Can anyone help me fix my query to deal with the desired functionality of the order not being important and partial results matching? If it can be sorted by the best matches (i.e. the longest part of the word, starting from the first letter only not a section in the middle, in the highest number of columns), that would be a huge help also.

UPDATE:

Just wanted to post the final code that worked based on the solution. My loop creating multiple match statements was incorrect as was my ft_min_word_len.

My code is now:

$searchArray = explode(" ", $searchVal);
$query="SELECT * FROM users WHERE  MATCH (`first_name`, `last_name`, `email`) AGAINST ('";
$i=0;
foreach ($searchArray as $word) {
    $query .= "+".$word."* ";
}
$query .= "' IN BOOLEAN MODE)";
Edit
Report