Привет, у меня есть функция поиска, в которой я буду искать db для ключевых слов. я хотел бы выделить ключевые слова и найти вторую функцию, которую я хотел бы реализовать в своей функции поиска.
поэтому у меня есть этот код для поиска:
<?php function searchText($keywords){ global $db; $returned_results = array(); $where2 = ""; $keywords = preg_split('/[\s]+/', $keywords); $total_keywords = count($keywords); foreach ($keywords as $key=>$keyword){ $where2 .= "`column` LIKE '%$keyword%'"; if ($key != ($total_keywords - 1)){ $where2 .= " OR "; } } $results_text = "SELECT `a`, `b`, LEFT(`c`, 150) as `c` FROM `table` WHERE $where2"; $results_num_text = ($query2 = mysqli_query($db, $results_text)) ? mysqli_num_rows($query2) : 0; if ($results_num_text === 0){ return false; } else { while ($row = mysqli_fetch_assoc($query2)){ $returned_results[] = array( 'ab' => $row['ab'], 'cd' => $row['cd'], ); } return $returned_results; } } ?>
и хотел бы реализовать в нем вторую функцию:
<?php function mark_words ($text, $words, $colors = false) { if (!$colors || !is_array($colors) ) { $colors = array('#ff9999', '#ffff99', '#ff99ff', '#99ffff','#99ff99'); } $c = 0; foreach ($words as $w) { $w = preg_quote(trim($w)); if($w=='') { continue; } $regexp = "/($w)(?![^<]+>)/i"; $replacement = '<b style="background-color:'.$colors[$c].'">\\1</b>'; $text = preg_replace ($regexp,$replacement ,$text); $c++; if ($c >= count($colors)) { $c=0; } } return $text; } $example = <<< EOT some text is here inside EOT; $search = array('some','is', 'inside'); echo mark_words($example, $search); ?>
поэтому у меня есть этот код, который не работает:
<?php function searchText($keywords, $colors = false){ global $db; if (!$colors || !is_array($colors) ) { $colors = array('#ff9999', '#ffff99', '#ff99ff', '#99ffff','#99ff99'); } $c = 0; $returned_results = array(); $where2 = ""; $keywords = preg_split('/[\s]+/', $keywords); $total_keywords = count($keywords); foreach ($keywords as $key=>$keyword){ $regexp = "/($w)(?![^<]+>)/i"; $replacement = '<b style="background-color:'.$colors[$c].'">\\1</b>'; $text = preg_replace($regexp,$replacement ,$keywords); $c++; if ($c >= count($colors)) { $c=0; } $where2 .= "`b` LIKE '%$keyword%'"; if ($key != ($total_keywords - 1)){ $where2 .= " OR "; } } $results_text = "SELECT `a`, LEFT(`b`, 150) as `b`, `c` FROM `table` WHERE $where2"; $results_num_text = ($query2 = mysqli_query($db, $results_text)) ? mysqli_num_rows($query2) : 0; if ($results_num_text === 0){ return false; } else { while ($row = mysqli_fetch_assoc($query2)){ $returned_results[] = array( 'ab' => $row['a'], 'cd' => $row['b'], ); } return $returned_results; $highlight = array($keywords); echo mark_words($highlight); } } ?>
поскольку я искал его, как это сделать, я нашел две возможности. первая будет функцией, вторая – для выделения ее из запроса select:
SELECT REPLACE(`col`, 'foobar', '<span class="highlight">foobar</span>') AS `formated_foobar` FROM … WHERE `col` LIKE "%foobar%"
поэтому мой вопрос заключается в том, как я могу реализовать вторую функцию в функции поиска или было бы лучше использовать второй метод?
если есть кто-то, кто мог бы мне помочь, я действительно был бы признателен. большое спасибо.
Вы не должны делать это слишком тяжело для себя. Все, что вам нужно, чтобы заменить каждое слово слова словом, заключенным в промежутке, с требуемым стилем. Это должно сработать для вас:
function highlight_word( $content, $word, $color ) { $replace = '<span style="background-color: ' . $color . ';">' . $word . '</span>'; // create replacement $content = str_replace( $word, $replace, $content ); // replace content return $content; // return highlighted data } function highlight_words( $content, $words, $colors ) { $color_index = 0; // index of color (assuming it's an array) // loop through words foreach( $words as $word ) { $content = highlight_word( $content, $word, $colors[$color_index] ); // highlight word $color_index = ( $color_index + 1 ) % count( $colors ); // get next color index } return $content; // return highlighted data } // words to find $words = array( 'normal', 'text' ); // colors to use $colors = array( '#88ccff', '#cc88ff' ); // faking your results_text $results_text = array( array( 'ab' => 'AB #1', 'cd' => 'Some normal text with normal words isn\'t abnormal at all' ), array( 'ab' => 'AB #2', 'cd' => 'This is another text containing very normal content' ) ); // loop through results (assuming $output1 is true) foreach( $results_text as $result ) { $result['cd'] = highlight_words( $result['cd'], $words, $colors ); echo '<fieldset><p>ab: ' . $result['ab'] . '<br />cd: ' . $result['cd'] . '</p></fieldset>'; }
Использование регулярных выражений для замены содержимого также будет выполнено, хотя использование str_replace()
выполняется немного быстрее.
Функции принимают эти аргументы:
highlight_word( string, string, string );
highlight_words( string, array, array );
Приведенный выше пример приводит к:
Используя str_ireplace вместо str_replace, функция будет работать нечувствительно к регистру
Я бы не использовал метод SQL. По прошествии времени, и у вас есть все больше и больше правил подсветки, которые станут неуправляемыми. Также сложнее обрабатывать случаи, когда вам нужно выделять foo
разному на foobar
, но один содержит другой.
Отделите свою обработку данных от форматирования.