2017-07-22 124 views
0

我正在使用數據庫,運行動態生成的查詢。一切都很好,當我發現在一個表中的幾行編碼問題時,所以我從備份中重新填充它並重建表。PDO返回無結果,而MySQL命令行返回預期結果

執行此操作後,PDO返回空結果並且不會拋出任何異常,但是,具有相同參數的相同查詢將從命令行成功執行(返回一些行)。我從var_dump()輸出複製粘貼查詢和參數以從命令行運行。

查詢:

SELECT `contracts_info`.`contract_number` AS `Номер контракта`, `contracts_info`.`balance` AS `Остаток`, `contracts_info`.`conclusion_date` AS `Дата заключения`, `contracts_info`.`activation_date` AS `Активация аккаунта`, `contracts_info`.`deactivation_date` AS `Деактивация аккаунта`, 
`parents`.`mother_fullname` AS `ФИО матери`, `parents`.`mother_email` AS `E-mail матери`, `parents`.`mother_phone` AS `Телефон матери`, `parents`.`father_fullname` AS `ФИО отца`, `parents`.`father_email` AS `E-mail отца`, `parents`.`father_phone` AS `Телефон отца`, `parents`.`postal_office` AS `Отделение Новой почты`, 
`students`.`name` AS `Имя`, `students`.`second_name` AS `Отчество`, `students`.`surname` AS `Фамилия`, `students`.`form_number` AS `Класс`, `students`.`form_letter` AS `Буква класса`, `students_info`.`medical_features` AS `Медицинские особенности`, `students_info`.`psychological_features` AS `Психологические особенности` 
FROM contracts_info 
JOIN `parents` USING(`contract_number`) 
JOIN `students` USING(`contract_number`) 
JOIN `students_info` USING(`contract_number`) 
WHERE MATCH (`contracts_info`.`contract_number`) AGAINST (? IN BOOLEAN MODE) 
OR MATCH (`parents`.`contract_number`, `parents`.`mother_fullname`, `parents`.`mother_email`, `parents`.`father_fullname`, `parents`.`father_email`) AGAINST (? IN BOOLEAN MODE) 
OR MATCH (`students`.`name`, `students`.`second_name`, `students`.`surname`, `students`.`contract_number`) AGAINST (? IN BOOLEAN MODE) 
OR MATCH (`students_info`.`medical_features`, `students_info`.`psychological_features`, `students_info`.`contract_number`) AGAINST (? IN BOOLEAN MODE); 

事情我已經嘗試過或檢查:

  • 檢查憑證,由腳本中使用;
  • 運行相同的查詢與不同的參數 - 相同的結果;
  • 通過兩種方法運行其他查詢 - 相同的結果;
  • 嘗試運行沒有反引號 - 相同的結果;
  • 從PHP腳本重建表 - 沒有幫助;
  • 在html中刪除表格轉儲 - 它們是最新的;
  • 比較html表格轉儲和cli轉儲 - 它們是相似的;
  • 檢查是否php請求對結果的影響,通過CLI命令收購 - 是的,有效果(所以,都使用相同的服務器/數據庫)

我已經用完了,我提出的想法一個錯誤和什麼修復,所以我想借你=) 即使是最瘋狂的。

什麼問題?

我錯在哪裏?

可能是此服務器故障?我分享nginx服務器並託管其他網站和程序員,其中一些可能有權訪問我的數據庫。

MySQL版本():5.6.29-76.2,PHP 5.5.9

預先感謝您。

編輯:PDO處理

PDO處理被封裝在類

創建PDO:用於

try 
    { 
     $this->handle = new PDO("mysql:dbname=" . $this->database . ";host=" . $this->server, 
      $this->user, $this->password); 

     // ensure that PDO::prepare returns false when passed invalid SQL 
     $this->handle->setAttribute(PDO::ATTR_EMULATE_PREPARES, false); 
     $this->handle->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); 
    } 
    catch (Exception $e) 
    { 
     trigger_error($e->getMessage(), E_USER_ERROR); 
     exit; 
    } 

Query()方法運行查詢。它有這樣的參數:$sql - 帶'?'的查詢字符串,$parameters - 參數數組。改變$this->PDOFetchMode

public function SetPDOFetchMode($pdo_constant) 
{ 
    if (is_int($pdo_constant) && $pdo_constant >= 0) 
     $this->PDOFetchMode = $pdo_constant; 
} 

其他代碼

$statement = $this->handle->prepare($sql); 
    if ($statement === false) 
    { 
     trigger_error($this->handle->errorInfo()[2], E_USER_ERROR); 
     exit; 
    } 
    $results = $statement->execute($parameters); 

    if ($results !== false) 
    { 
     return $statement->fetchAll($this->PDOFetchMode); 
    } 
    else 
    { 
     return false; 
    } 

方法是有關參數的驗證,單執行等

編輯:

通過這個帖子的啓發:PDO prepare statement and match against in boolean mode

我嘗試綁定參數,但這並沒有幫助

我試過Paul T.關於在查詢中直接根據他的評論使用參數的建議,但這也沒有幫助。儘管如此,我仍然可以在CLI中成功運行查詢。

+1

您可以添加PDO處理過,因爲PDO是在標題,問題和標籤? –

+0

你有什麼MySQL版本?過去有麻煩[在AGAINST子句中有參數](https://stackoverflow.com/a/13682516/7644018)。 –

+1

您能否提供'$ parameters'數組的樣例'var_dump()'? –

回答

0

問題解決了相當不尋常的這個帖子最佳答案: PDO + MySQL and broken UTF-8 encoding

強制使用UTF8編碼使用在構造整個基地後,它的工作很好,結果沒出現。但我不太明白,這是怎麼完成的。 CLI請求在默認情況下正確返回utf8編碼的結果。

看來我的AGAINST參數與編碼混淆了。

代碼來解決它:

$pdo = new PDO(
'mysql:host=hostname;dbname=defaultDbName', 
'username', 
'password', 
array(PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES utf8") 
); 

感謝Paul T.靈感

+0

這是一個很好的發現。感謝發佈發現的結果! –