(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
  • Обязательно используйте $county в шапке а не $_GET["my_input"]

Очевидно, если пользователь вводит Be затем Bedfordshire Будут выбраны первые записи. Пока ваши «предложения» находятся в одном и том же порядке, все должно работать нормально.

В случае, если пользователь вводит завершающий пробел или что-то, возможно trim():

if(substr($county, 0, strlen(trim($_GET["my_input"]))) == strtolower(trim($_GET["my_input"]))) {
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 функция из этого ответа и итерации по вашим округам, установив флаг, если совпадение найдено.

<?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

Реализация levenshtein для вашего кода будет выглядеть примерно так:

$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;

Но я не думаю, что это будет именно то, что вы ищете, потому что технически Avon ближе к Bed чем Bedfordshire используя этот алгоритм.

Eсть similar_text функция в PHP, которая может дать вам лучшие результаты.

$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;
0
По вопросам рекламы [email protected]