TrashNotes

2025-03-02 19:29:20
Пример модификации кода для поддержки логических операторов

php
$search = isset($_GET['search']) ? trim($_GET['search']) : '';
$search = preg_replace('/\s+/', ' ', $search); // Заменить несколько пробелов на один
$search = preg_replace('/[^a-zA-Z0-9\s\+\-\|]/u', '', $search); // Удалить спецсимволы, кроме логических операторов

$searchQuery = '';
if (!empty($search)) {
    $searchTerms = explode(' ', $search);
    $searchConditions = [];
    
    foreach ($searchTerms as $term) {
        if (strpos($term, '+') === 0) {
            // Обязательное наличие термина (AND)
            $term = substr($term, 1);
            $term = $db->escapeString($term);
            $searchConditions[] = "users_fts MATCH '$term*'";
        } elseif (strpos($term, '|') === 0) {
            // Альтернативное наличие термина (OR)
            $term = substr($term, 1);
            $term = $db->escapeString($term);
            $searchConditions[] = "users_fts MATCH '$term*'";
            // Для OR нужно использовать другой подход, так как FTS5 не поддерживает OR напрямую
            // Вместо этого можно использовать UNION или отдельные запросы для каждого термина
        } elseif (strpos($term, '-') === 0) {
            // Исключение термина (NOT)
            $term = substr($term, 1);
            $term = $db->escapeString($term);
            $searchConditions[] = "NOT users_fts MATCH '$term*'";
        } else {
            // Обычный поиск
            $term = $db->escapeString($term);
            $searchConditions[] = "users_fts MATCH '$term*'";
        }
    }
    
    // Формирование поискового запроса
    // Для поддержки OR и NOT нужно использовать более сложные запросы
    if (count($searchConditions) > 1) {
        // Для OR можно использовать UNION
        $orConditions = [];
        $andConditions = [];
        foreach ($searchConditions as $condition) {
            if (strpos($condition, 'OR') !== false || strpos($condition, '|') !== false) {
                $orConditions[] = $condition;
            } else {
                $andConditions[] = $condition;
            }
        }
        
        if (!empty($orConditions)) {
            $orQuery = implode(' UNION ', array_map(function($condition) {
                return "(SELECT rowid FROM users_fts WHERE $condition)";
            }, $orConditions));
            $searchQuery = " WHERE id IN ($orQuery)";
        }
        
        if (!empty($andConditions)) {
            $andQuery = implode(' AND ', $andConditions);
            if (!empty($orConditions)) {
                $searchQuery .= " AND id IN (SELECT rowid FROM users_fts WHERE $andQuery)";
            } else {
                $searchQuery = " WHERE id IN (SELECT rowid FROM users_fts WHERE $andQuery)";
            }
        }
    } else {
        $searchQuery = " WHERE id IN (SELECT rowid FROM users_fts WHERE " . implode(" AND ", $searchConditions) . ")";
    }
}
← Previous Next →
Back to list