2011-02-07 10 views
5

में कस्टम क्वेरी को कनवर्ट करना PHP का उपयोग कर SQL में निम्न इनपुट को परिवर्तित करने का सबसे अच्छा तरीका क्या होगा?एसक्यूएल

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

मैं preg_replace का उपयोग कर या लूप करने के लिए विस्फोट और बयान करता है, तो कर विभिन्न stabs लिया है लेकिन लगातार काम करने के लिए कुछ भी नहीं मिला है।

मैं मूल रूप से

+a +(c/d/e) 

की तरह कुछ करने के लिए बारी में

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

धन्यवाद की जरूरत है!

अद्यतन:

यहां मेरा प्रयास है। मुझे यकीन है कि एक आसान तरीका है ...

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; 

} 

उत्तर

1

चूंकि आपको अभिव्यक्ति घोंसला करने की आवश्यकता नहीं है। यह आसान है और रेगुलर एक्सप्रेशन से वास्तव में सिर्फ है आलस्य:

$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)"; 
} 

यह साथ "और" शुरू करने बयान वापस होगा, जो अनुकूलित किया जा सकता है, लेकिन यह धोखा देने के लिए आसान है और सिर्फ पहले जोड़ें "TRUE" यह एक वैध में बदलने के लिए कहां कारण।

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

पैटन +, - साथ या किसी ऑपरेटर के बिना शुरू कर देना चाहिए।

xor साथ \ की जगह के बारे में सुनिश्चित नहीं हैं - आप कैसे (a\b\c), (a\b\c\d) आदि

हैंडल करना चाहते हैं पर निर्भर करता है