2015-05-02 32 views
0

編輯:感謝spencer7593幫助我解決這個問題。我編輯了主要的代碼,爲後來的人提供了正確的表單。從PHP數組中搜索mySQL表中的多列vs固定

我目前正在圍繞着PHP和mySQL,並且在搜索mySQL時遇到了障礙。

我需要搜索表中的多個列進行部分匹配。我已經正確地使用一組固定的列來搜索,但是當我嘗試使用一個數組時,它失敗了,即使mySQL的輸出看起來相同。

任何人都可以指出我在某處做出的那個微小的愚蠢錯誤嗎?那還是改進的方式嗎?

<form name="search" method="post" action="<?php $PHP_SELF; ?>"> 
    Search for: <input type="text" name="find" /> 
    <input type="hidden" name="searching" value="yes" /> 
    <input type="submit" name="search" value="Search" /> 
</form> 


<?php 

$dbdata=array(
    'servername' => "localhost", 
    'username'  => "Username", 
    'password'  => "Password", 
    'dbname'  => "Membership", 
    'table_Members' => "Members" 
); 
$fields=array(
       'MemberID', 
       'FirstName', 
       'LastName', 
       'Nickname', 
       'Interests', 
       'Skills'); 

$output=array(); 
if(isset($_POST['searching'])) { 
    $output=read_db_search($dbdata['table_Members'],$_POST['find'],$fields); 
} 
echo ('<pre>'); 
var_dump($output); 
echo ('</pre>'); 

function read_db_search ($table,$searchQuery,$fields) 
{ 
    global $dbdata; 
    $servername=$dbdata['servername']; 
    $dbname=$dbdata['dbname']; 
    $dbtable=$dbdata['table_Members']; 

    try { 
     $conn = new PDO("mysql:host=$servername;dbname=$dbname", $dbdata['username'], $dbdata['password']); 
     $conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); 

/*This version works!!!!*/ 
$query = "SELECT * FROM `Members` WHERE `" 
     . implode("` LIKE '%$searchQuery%' OR `",$fields) 
      . "` LIKE '%$searchQuery%' " ; 

      /* This section should work but doesnt */ 
     //$query="SELECT * FROM `Members` WHERE`'.implode(' ` LIKE \'%$searchQuery%\' OR `',$fields).'` LIKE \'%$searchQuery%\'"; 
     //$stmt = $conn->prepare($query); 



      /* This one works fine */ 
    /* $stmt = $conn->prepare("SELECT * FROM `Members` WHERE 
      `MemberID` LIKE '%$searchQuery%' OR 
      `FirstName`  LIKE '%$searchQuery%' OR 
      `LastName` LIKE '%$searchQuery%' OR 
      `Nickname` LIKE '%$searchQuery%' OR 
      `Interests` LIKE '%$searchQuery%' OR 
      `Skills` LIKE '%$searchQuery%'"); 
*/ 


     $stmt->execute(); 
      $result = $stmt->setFetchMode(PDO::FETCH_ASSOC); 
      $data=$stmt->fetchAll(); 
     } 
     catch(PDOException $e) { 
      echo "Error: " . $e->getMessage(); 
     } 
     $conn = null; 
     return $data; 
} 
?> 

$查詢返回的的var_dump:

string(89) "SELECT * FROM `Members` WHERE`'.implode(' ` LIKE \'%searchterm%\' OR `',Array).'` LIKE \'%searchterm%\'" 

與錯誤:

Error: SQLSTATE[42000]: Syntax error or access violation: 1064 You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '\'%searchterm%\' OR `',Array).'` LIKE \'%searchterm%\'' at line 1 
+0

「它失敗」是對觀察到的行爲的相當模糊的描述。我們還想知道是否拋出了PDO異常,是否存在MySQL語法錯誤,或者查詢是否返回意外的結果。請編輯問題以更明確地解釋您正在觀察的行爲。並且,將'$ query'的值回顯出來,並將其包含在您的問題中。 – spencer7593

+0

現在很清楚,我錯過了它。 '.implode('需要在雙引號的*之外......在該點之前加一個雙引號(以終止前面的字符串文本),並且''後面還需要雙引號。在implode()的末尾。它看起來像「'數組」,需要用'$ fields'的引用來替換。這不是一個真正的MySQL問題,這是PHP字符串處理的一個問題。 ('$ query'的內容必須是有效的SQL文本。) – spencer7593

回答

1

由於在調試這個第一步,做一個echo$queryvar_dump它的前提交給數據庫。


但由於一些建議......在這裏:

$fields=array( 
      `MemberID`, 
      `FirstName`, 

什麼是與反引號處理?你是否想要執行MemberID,並將其放入數組中?或者你想將字符串文字放入數組中嗎?例如:

$fields=array(
      '`MemberID`', 
      '`FirstName`', 

- 或 -

$fields=array(
      'MemberID', 
      'FirstName', 

如果字符串常量包括反引號,那麼你就不會需要在「內爆」,並稱反引號渣土,當你生成SQL輸入$query

在這裏:

WHERE`'.implode(' ` LIKE \' 
     ^  ^

它看起來像這樣是不會離開WHERE關鍵字和標識符之間的空間。看起來像在標識符的最後一個字符(例如MemberID)與該結束倒退之間添加了一個空格。因此您的SQL將引用包含空格字符的標識符,例如

... WHERE`MemberID ` LIKE '%... 
     ^ ^

這看起來像是一個問題給我。貌似要生成

... WHERE `MemberID` LIKE '%... 
     ^  ^

如果您已納入各地陣列中的標識符反引號,那麼你就不需要在$query產生加反引號。如果你確實包含反引號,那麼他們需要對標識符(列名)提供的值「緊」,並且不要在反引號內包含額外的空格字符。

說明一下,用一個例子稍微清楚......這列名:

`abc` 

與此相同的列名:

`abc ` 

再次,對於調試這隻需要執行生成的查詢字符串的echovar_dump,並仔細查看將要提交給數據庫的SQL。如果您無法發現錯誤,並嘗試使用該SQL文本並在另一個客戶端中針對數據庫進行測試。


編輯

有在真實值分配給$query PHP的字符串處理的幾個問題。

嘗試這樣:

$query = "SELECT * FROM `Members` WHERE `" 
     . implode("` LIKE '%$searchQuery%' OR `",$fields) 
       . "` LIKE '%$searchQuery%' " ; 

當那是完全,$query應該包含的東西,看起來像一個有效的SQL語句,像這樣

SELECT * 
    FROM `Member` 
WHERE `MemberID` LIKE '%foo%' 
    OR `FirstName` LIKE '%foo%' 

(我已經添加了換行和用於格式化的空格。)

+0

反引號是我之前嘗試解決此問題的疏忽。該代碼從一個更大的項目中剝離出來,並專注於這個問題。 至於測試。如果我採取$查詢,回聲它,並將其粘貼到$ conn-> prepare()它可以正常工作,但不直接饋送。 – Cynar

+0

最後一個除了':D 現在有效。我將編輯原件以包含未來頭髮佩戴者的正確解決方案。 – Cynar

+0

@Cynar:你會想驗證'$ fields'是一個至少包含一個元素的數組。如果'$ fields'是一個空數組,那麼該字符串連接不會生成有效的SQL語句。 – spencer7593