2016-06-13 45 views
0

首先,我是開發新手,所以需要一個小小的手持。(PHP)將用戶搜索與數組匹配

我已經構建了一個簡單的搜索字段(帶有建議),並將用戶發送到數組匹配上的相關着陸頁。如果搜索不相關,則返回錯誤消息。但是,我的代碼依賴於用戶單擊建議或在搜索字段中輸入整個單詞。因此,可用性很差。

下面的代碼將突出顯示我的問題。理想情況下,我需要將字段輸入'br'與'bristol'匹配(根據我對用戶的建議)。我認爲解決方案是http://php.net/manual/en/function.levenshtein.php,但我遇到問題(像我說的,我是新的)。我將不勝感激任何指導。

感謝您的時間!

<?php 

$counties = array("Avon", 
"Bristol", 
"Bedfordshire", 
"Berkshire", 
"Buckinghamshire" 
); 

if (in_array(strtolower($_GET["my_input"]), array_map('strtolower', $counties))) 

{ header('Location: http://domain.co.uk/county/'.strtolower(str_replace(' ', '-', $_GET['my_input']))); 
} 

else 

{ 
header('Location: ' . $_SERVER['HTTP_REFERER'] . "?message=tryagain"); 
exit; 
} 

?> 

回答

0

可以優化,但在一般:

foreach(array_map('strtolower', $counties) as $county) { 
    if(substr($county, 0, strlen($_GET["my_input"])) == strtolower($_GET["my_input"])) { 
     header('Location: http://domain.co.uk/county/'.str_replace(' ', '-', $county)); 
     exit; 
    } 
} 
header('Location: ' . $_SERVER['HTTP_REFERER'] . "?message=tryagain"); 
exit; 
  • 河套$counties和比較$_GET["my_input"]$county
  • 相同數量的開始字符3210
  • 確保在標題中使用$county,而不是$_GET["my_input"]

顯然,如果用戶輸入Be然後Bedfordshire是第一項將被選擇。只要你的「建議」是相同的順序,它應該工作得很好。

如果用戶輸入一個尾隨空格或什麼的,也許trim()

if(substr($county, 0, strlen(trim($_GET["my_input"]))) == strtolower(trim($_GET["my_input"]))) { 
+0

完美的作品!修剪元素似乎打破了代碼,但我會進一步研究。用戶習慣於輸入一些字符,我的代碼在一半時間內掉下來,並且我失去了用戶。但這已經成功了。謝謝! –

0

這應該讓你更接近(如果不)到你的目標:

if(array_key_exists('my_input', $_GET){ 

    $input = $_GET["my_input"]; 
    $counties = array("Avon", "Bristol", "Bedfordshire", "Berkshire", "Buckinghamshire"); 

    // no shortest distance found, yet 
    $shortest = -1; 

    // loop through words to find the closest 
    foreach ($counties as $country) { 

     $lev = levenshtein($input, $country); 

     // check for an exact match 
     if ($lev == 0) { 
      $closest = $country; 
      $shortest = 0; 
      // break out of the loop; we've found an exact match 
      break; 
    } 

     // if this distance is less than the next found shortest 
     // distance, OR if a next shortest word has not yet been found 
     if ($lev <= $shortest || $shortest < 0) { 
      // set the closest match, and shortest distance 
      $closest = $country; 
      $shortest = $lev; 
     } 
    } 

    if($shortest < 5){ //insert your own value here (accuracy) 
     header('Location: http://domain.co.uk/county/'.strtolower($closest)); 
    }else{  
     // if not match 
     header('Location: ' . $_SERVER['HTTP_REFERER'] . "?message=tryagain"); 
    } 

} 
0

你可以使用一個startsWith function from this answer如果發現匹配遍歷您的縣設定一個標誌。

<?php 

function startsWith($haystack, $needle) { 
    // search backwards starting from haystack length characters from the end 
    return $needle === "" || strrpos($haystack, $needle, -strlen($haystack)) !== false; 
} 

$counties = array("Avon", 
"Bristol", 
"Bedfordshire", 
"Berkshire", 
"Buckinghamshire" 
); 

foreach (array_map('strtolower', $counties) as $county){ 
    if(startsWith($county, strtolower($_GET["my_input"]))){ 
    header('Location: http://domain.co.uk/county/'.strtolower(str_replace(' ', '-', $_GET['my_input']))); 
    $match = true; 
    break; 
    } 
} 

if(empty($match)) 
    header('Location: ' . $_SERVER['HTTP_REFERER'] . "?message=tryagain"); 
0

實施萊文斯坦爲您的代碼看起來是這樣的:

$counties = array(
    "Avon", 
    "Bristol", 
    "Bedfordshire", 
    "Berkshire", 
    "Buckinghamshire" 
); 

$input = 'Bed'; 
$shortest = -1; 

foreach($counties as $county) { 

    $lev = levenshtein($input, $county); 
    var_dump($county, $lev); 

    if ($lev == 0) { 
     $closest = $county; 
     break; 
    } 

    if ($lev <= $shortest || $shortest < 0) { 
     $closest = $county; 
     $shortest = $lev; 
    } 

} 

echo $closest; 

但我不認爲這會做你尋找什麼,因爲技術上AvonBedfordshire接近Bed使用這個算法。

PHP中有一個similar_text函數可能會給你更好的結果。

$counties = array(
    "Avon", 
    "Bristol", 
    "Bedfordshire", 
    "Berkshire", 
    "Buckinghamshire" 
); 

$input = 'Bed'; 
$mostSimilar = 0; 

foreach($counties as $county) { 

    similar_text($input, $county, $similarity); 

    if ($similarity == 100) { 
     $closest = $county; 
     break; 
    } 

    if ($mostSimilar <= $similarity || $similarity < 0) { 
     $closest = $county; 
     $mostSimilar = $similarity; 
    } 

} 

echo $closest;