2017-07-22 131 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

这是一个很好的发现。感谢发布发现的结果! –