PHP / MySQL: Vurgu "gibi geliyor"

2 Cevap php

Hızlı MYSQL / PHP soru. Hiçbir sonuç normal bir arama sorgusu ile bulunursa ben ayarlamak için, son çare olarak "-so-sıkı değil" arama sorgusu kullanıyorum:

foreach($find_array as $word) { 
  clauses[] = "(firstname SOUNDS LIKE '$word%' OR lastname SOUNDS LIKE '$word%')";
}
if (!empty($clauses)) $filter='('.implode(' AND ', $clauses).')';
$query = "SELECT * FROM table WHERE $filter";

Şimdi, ben gibi, sonuçlarını vurgulamak için PHP kullanıyorum:

foreach ($find_array as $term_to_highlight){
    foreach ($result as $key => $result_string){
    	$result[$key]=highlight_stuff($result_string, $term_to_highlight);
    }
}

Ben vurgulamak için bilmiyorum Fakat bu yöntem eşek düşüyor. Bu mysql sorgusu çalıştırırken "ses-alike" maçı ne olduğunu öğrenmek için herhangi bir yolu var mı?

Yani birisi "Joan" arar eğer ben bunun yerine "John" vurgulamak istiyorum, söylemektir.

2 Cevap

SES GİBİ durum sadece iki kelime SOUNDEX anahtarını karşılaştırır ve aynı anahtarı oluşturmak için PHP soundex () işlevini kullanabilirsiniz.

Eşleşen bir satır bulundu ve vurgulamak için hangi sözcük bulmak için gerekirse Yani, ad ve soyad hem getir, ve sonra hangisinin eşleşmeleri bulmak ve sadece bu kelimeyi vurgulamak için PHP kullanabilirsiniz.

Ben sadece bu denemek için bu kodu yaptı. (Had to test my theory xD)

<?php
// A space seperated string of keywords, presumably from a search box somewhere.
$search_string = 'John Doe';

// Create a data array to contain the keywords and their matches.
// Keywords are grouped by their soundex keys.
$data = array();
foreach(explode(' ', $search_string) as $_word) {
    $data[soundex($_word)]['keywords'][] = $_word;
}

// Execute a query to find all rows matching the soundex keys for the words.
$soundex_list = "'". implode("','", array_keys($data)) ."'";
$sql = "SELECT id, firstname, lastname
        FROM   sounds_like
        WHERE  SOUNDEX(firstname) IN({$soundex_list})
        OR     SOUNDEX(lastname)  IN({$soundex_list})";
$sql_result = $dbLink->query($sql);

// Add the matches to their respective soundex key in the data array.
// This checks which word matched, the first or last name, and tags
// that word as the match so it can be highlighted later.
if($sql_result) {
    while($_row = $sql_result->fetch_assoc()) {
        foreach($data as $_soundex => &$_elem) {
            if(soundex($_row['firstname']) == $_soundex) {
                $_row['matches'] = 'firstname';
                $_elem['matches'][] = $_row;
            }
            else if(soundex($_row['lastname']) == $_soundex) {
                $_row['matches'] = 'lastname';
                $_elem['matches'][] = $_row;
            }
        }
    }
}

// Print the results as a simple text list.
header('content-type: text/plain');
echo "-- Possible results --\n";

foreach($data as $_group) {
    // Print the keywords for this group's soundex key.
    $keyword_list = "'". implode("', '", $_group['keywords']) ."'";
    echo "For keywords: {$keyword_list}\n";

    // Print all the matches for this group, if any.
    if(isset($_group['matches']) && count($_group['matches']) > 0) {
        foreach($_group['matches'] as $_match) {
            // Highlight the matching word by encapsulatin it in dashes.
            if($_match['matches'] == 'firstname') {
                $_match['firstname'] = "-{$_match['firstname']}-";
            }
            else {
                $_match['lastname'] = "-{$_match['lastname']}-";
            }

            echo " #{$_match['id']}: {$_match['firstname']} {$_match['lastname']}\n";
        }
    }
    else {
        echo " No matches.\n";
    }
}
?>

Bir dizelerden eşleşen soundex kelimeyi çekip daha genelleştirilmiş fonksiyon gibi görünebilir:

<?php
/**
 * Attempts to find the first word in the $heystack that is a soundex
 * match for the $needle.
 */
function find_soundex_match($heystack, $needle) {
    $words = explode(' ', $heystack);
    $needle_soundex = soundex($needle);
    foreach($words as $_word) {
        if(soundex($_word) == $needle_soundex) {
            return $_word;
        }
    }
    return false;
}
?>

: Ben bunu doğru anlamak ediyorsam, gibi önceden yayınlanmıştır kodunda kullanılan olabilir ki,

foreach ($find_array as $term_to_highlight){
    foreach ($result as $key => $result_string){
        $match_to_highlight = find_soundex_match($result_string, $term_to_highlight);
        $result[$key]=highlight_stuff($result_string, $match_to_highlight);
    }
}

Bu daha hedefli kodu olarak ilk özette verimli tho olmaz.

Eğer öyle düşünüyorum SOUNDS LIKE çalışmaz unutmayın. O % joker desteklemediği gibi, LIKE MySQL eşdeğer değildir.

Bu "John" ararken sorgu "John David'i" bulmak anlamına gelir. Bu sadece son çare ise bu kabul edilebilir olabilir, ancak bu ideal değildir.

Yani burada farklı bir öneri (ki iyileşme gerekebilir) 'dir; İlk kullanımdan PHPs soundex() aradığınız anahtar kelimenin soundex bulmak için çalışır.

$soundex = soundex($word);
$soundexPrefix = substr($soundex, 0, 2); // first two characters of soundex
$sql = "SELECT lastname, firstname ".
    "FROM table WHERE SOUNDEX(lastname) LIKE '$soundexPrefix%' ".
    "OR SOUNDEX(firstname) LIKE '$soundexPrefix%'";

Şimdi FirstNames ve sondaj belli belirsiz bir benzerlik vardır lastnames bir listesi olacak (bu çok girişleri olabilir, ve size arama için kullanmak soundex önek uzunluğunu artırmak isteyebilirsiniz). Daha sonra her bir kelimenin Soundex ve arama terimi arasındaki Levenshtein mesafeyi hesaplamak ve bu göre sıralayabilirsiniz.

İkinci olarak, SQL enjeksiyon hataları önlemek için, MySQL parametreli sorgular bakmak gerekir.