Skip to content

A PHP search function that searches through an array (usually the result of a database query) at 6 depth levels

License

Notifications You must be signed in to change notification settings

dan-barbulescu-dev/php-search-engine

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

10 Commits
 
 
 
 
 
 

Repository files navigation

PHP Search Engine

A PHP search function that searches through an array (usually the result of a database query) at 6 depth levels:

  1. Full phrase – direct match
  2. Full phrase – similar pronunciation
  3. Full phrase – similar spelling
  4. Each individual word – direct match
  5. Each individual word – similar pronunciation
  6. Each individual word – similar spelling

Search engine

function add_result($result_to_add, &$results, &$found_already)
{
 // If this is the first time you find this search result, add it to the results array
 if (!isset($found_already[$result_to_add]))
 {
  $found_already[$result_to_add] = true;
  $results[] = $result_to_add;
 }
}
 
function custom_search($search_database, $search_query, $depth = 3)
{
 /*
 $search_database - array containing what you want to search through
 $search_query - string search query
 $depth - from 1 to 6
 1. Full phrase - direct match
 2. Full phrase - similar pronunciation
 3. Full phrase - similar spelling
 4. Each individual word - direct match
 5. Each individual word - similar pronunciation
 6. Each individual word - similar spelling
  
 returns array $results;
 */
  
  
 $search_query = strtolower($search_query);
 foreach($search_database as $key => $value)
 {
  $search_database[$key] = strtolower($search_database[$key]);
 }
  
 // note, when translating the project into multiple languages, one should also try to acquire metaphone 3 or other similar algorithms
 
 $results = null;
 $found_already = null;
   
   
 // step 1 = first look for the full match
 if ($depth >= 1)
 {
     foreach($search_database as $key => $value)
     {
      if (stripos($value, $search_query) !== false)
      {
       add_result($key, $results, $found_already);
      }
     }   
 }
 // step 2 = look for metaphone (pronounciation match)
 // add_result("STEP 2", $results, $found_already);
 
 if ($depth >= 2) 
 {
     $search_query_metaphone = metaphone($search_query);
     foreach($search_database as $key => $value)
     {
      if (metaphone($value) == metaphone($search_query_metaphone)) add_result($key, $results, $found_already);
     }
 }   
 // step 3 = look for levenshtein (similar phrase match, 25%)
 //add_result("STEP 3", $results, $found_already);
 
 if ($depth >=3)
 {
     foreach($search_database as $key => $value)
     {
      if ((strlen($search_query) <= 255) && (strlen($value) <= 255))
      {
          $lev = levenshtein($value, $search_query, 1, 1, 1);
               
          $max_char = strlen($search_query) / 2;
          $max_char = (int)$max_char;
          $max_char++;
           
          if (($lev <= $max_char) && ($lev != -1))
          {
           add_result($key, $results, $found_already);
          }
      }
     }
 }
 // step 4 - look for individual words from the search query (at least 4 letters), order results by number of words found;
 //add_result("STEP 4", $results, $found_already);
  
 if ($depth >= 4)
 {
     $words_matched = null;
     $query_words = get_words_from_string($search_query, 4);
     foreach($search_database as $key => $value)
     {
      $words_matched[$key] = 0;
      for ($i = 0; $i < count($query_words); $i++)
      {
       if (stripos($value, $query_words[$i]) !== false) $words_matched[$key]++;
      } 
      }
      arsort($words_matched);
       
      foreach($words_matched as $key => $value)
      {
       if ($value > 0) add_result($key, $results, $found_already);
      }
 }
  
 // step 5 - take each individual word, and compare it to each individual word from database, phonetically;
 if ($depth >= 5)
 {
     $words_matched = null;
     $search_query_metaphone = metaphone($search_query);
      
     foreach($search_database as $key => $value)
     {
      $words_matched[$key] = 0;
      $current_value_words = get_words_from_string($value, 4);
      if (count($current_value_words) > 0)
      {
          foreach ($current_value_words as $key2 => $word)
          {
           if (metaphone($word) == $search_query_metaphone) $words_matched[$key]++;
          }
      }
     }
     
    arsort($words_matched);
       
    foreach($words_matched as $key => $value)
    {
     if ($value > 0) add_result($key, $results, $found_already);
    }
 }
  
 // step 6 - take each individual word, and compare it to each individual word from database, writing-wise;
 if ($depth >= 6)
 {   
     $words_matched = null;
     foreach($search_database as $key => $database_value)
     {
      $words_matched[$key] = 0;
      $current_value_words = get_words_from_string($database_value, 4);
      if (count($current_value_words) > 0)
      {
          foreach ($current_value_words as $key2 => $database_value_word)
          {
               if ((strlen($search_query) <= 255) && (strlen($database_value_word) <= 255))
               {
                   $lev = levenshtein($database_value_word, $search_query, 1, 1, 1);
                    
                   // if ($key == 396) echo $database_value_word. ' - '.$search_query. ' - '.$lev.' <br />';
                   $max_char = strlen($search_query) / 4;
                   $max_char = (int)$max_char;
                   $max_char++;
                   
                   if (($lev <= $max_char) && ($lev != -1))
                   {
                    $words_matched[$key]++;
                   }
               }
          }
      }
     }
     
    arsort($words_matched);
       
    foreach($words_matched as $key => $value)
    {
     if ($value > 0) add_result($key, $results, $found_already);
    }
 }
  
  
 return $results; 
}

Sample usage

$search_database = ['Ludwig van Beethoven', 'Johann Sebastian Bach', 'Wolfgang Amadeus Mozart', 'Antonio Vivaldi']; // search database that contains the name of composers

$search_level = 6; // search level is set to 6 out of 6 since the database we are searching through is relatively small

$search_query = 'mozart';
 
if ($search_query != "") $composers_results = custom_search($search_database, $search_query, $search_level);
else
{
 $composers_results = null;
 foreach ($search_database as $id_composer => $name)
 {
  $composers_results[] = $id_composer;
 }
}
 
$composers_found = count($composers_results);
if ($composers_found == 0) echo '<p>No composers found.</p>';
if ($composers_found == 1) echo '<p>1 composer found:</p>';
if ($composers_found > 1) echo '<p>'.$composers_found.' composers found:</p>';
 
if ($composers_found > 0)
{
    echo '<ul>';
    foreach ($composers_results as $key => $id_composer)
    {
     echo '<li><a href="https://www.hdclassicalmusic.com/browse/?by=composer&id_composer='.$id_composer.'">'.$sd_composers_name[$id_composer].'</a></li>';
    }
    echo '</ul>';
}

About

A PHP search function that searches through an array (usually the result of a database query) at 6 depth levels

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages