2011-02-07 27 views
5

Aşağıdaki girdiyi PHP kullanarak SQL'e dönüştürmenin en iyi yolu ne olurdu?Özel sorguları SQL'e dönüştürme

+a - includes a 
+(c\d) - includes c or d but not both 
+(c/d/e) - includes any of these 
-f - does not include f 

Ben preg_replace kullanarak veya döngü patlayabilir ve tablolar halinde yapmak çeşitli kesmelerine yaşadım ama tutarlı bir şekilde çalışması şey yok.

Temelde

SELECT * FROM the_table 
WHERE description LIKE "%a%" 
AND (description LIKE "%c%" OR description like "%d%" OR description LIKE "%$e%") 

teşekkür içine

+a +(c/d/e) 

gibi bir şey çevirmek gerekiyor!

GÜNCELLEME:

İşte o benim denemesi. Eğer iç içe ifadesini gerekmez beri ...

public function custom_query($query){ 

    $fields = " feed_items.description "; 

    $return_query = ""; 

    $query = str_replace("'", '', $query); 

    $pluses = explode('+',$query); 

    foreach($pluses as $plus){ 

      $plus = trim($plus); 

      if (substr($plus,0,1) == '('){ 
       $return_query .= 'AND ('; 

       $plus = str_replace(array('(',')'), '', $plus); 

       $ors = explode('/', $plus); 

       foreach($ors as $or){ 
        if ($or){ 
         $return_query .= $fields." LIKE '%".$or."%' OR"; 
        } 
       } 

       $return_query = rtrim($return_query, ' OR'); 
       $return_query .= ')'; 
      } else { 
       if ($plus){ 
        $return_query .= ' AND ' . $fields.' LIKE '.'"%'.$plus.'%"'; 
       } 
      } 

     } 

    $negatives = explode('-',$query); 

    foreach($negatives as $negative){ 

      $negative = trim($negative); 

      if (substr($negative,0,1) == '('){ 
       $return_query .= 'AND ('; 

       $negative = str_replace(array('(',')'), '', $negative); 

       $ors = explode('\\', $negative); 

       foreach($ors as $or){ 
        if ($or){ 
         $return_query .= $fields." NOT LIKE '%".$or."%' OR"; 
        } 
       } 

       $return_query = rtrim($return_query, ' OR'); 
       $return_query .= ')'; 
      } else { 
       if ($negative){ 
        $return_query .= ' AND ' . $fields.' NOT LIKE '.'"%'.$negative.'%"'; 
       } 
      } 

     } 

    $return_query = ' AND '.ltrim($return_query, ' AND '); 

    return $return_query; 

} 

cevap

1

daha kolay bir yolu yoktur eminim. Çok basit ve regex sadece aslında tembellik:

$sql = preg_replace_callback("' 
      ([+-])   # AND or NOT 
      (\w+    # capture a single word 
      | \(    # or something enclosed in literal braces 
       (\w+   # word 
        ([/\\\\])? # logical delimiter 
       [^)]*)  # remainder words and/or delimiters 
      \) 
      )'x", 
     "to_sql", $search_pattern); 

function to_sql($match) { 
    @list($uu, $logical, $word, $words, $or) = $match; 

    if ($logical == "+") { 
     $sql = " AND ("; 
    } 
    else { 
     $sql = " OR ("; 
    } 

    if ($words) { 
     $words = explode($or, $words); 
    } 
    else { 
     $words = array($word); 
     $or = "/"; 
    } 

    foreach ($words as $i=>$word) { 
     $words[$i] = "description LIKE '%$word%'"; 
    } 

    $or = ($or == "/") ? " OR " : " XOR "; 
    $sql .= implode($or, $words); 

    return "$sql)"; 
} 

O adapte edilebileceği ile "AND" başlangıç ​​deyimi dönecekti, ama dolandırıcı daha kolaydır ve sadece geçerli bir çevirmek için "DOĞRU" Önlerine WHERE yan tümcesi.

1
$pattern = "+a +(c/d/e)"; 

// replace a, c, d, e with "description like "%something%" 
$pattern = preg_replace('#[^()+\\-\\\\/\s]#', 'description like "%$0%"', $pattern); 

// replace operators 
$replacements = array(
    '+' => ' and ', 
    '-' => ' and not ', 
    '\\' => ' xor ', 
    '/' => ' or ', 
); 
$pattern = str_replace(array_keys($replacements), $replacements, $pattern); 
$pattern = trim($pattern); 

// remove first "and" 
// * "and something and something_else" becomes "something and something_else" 
// * "and not something and something_else" becomes "not something and something else" 
$pattern = preg_replace('#^and #', '', $pattern); 

Patten +, - ile ya da herhangi bir operatör olmadan başlamalıdır. xor ile \ değiştirilmesi konusunda

emin değil - Eğer (a\b\c), (a\b\c\d) vb

işlemek istiyorum nasıl bağlıdır