当MySQL命令行返回预期结果

时间:2017-07-22 11:45:06

标签: php mysql nginx pdo command-line-interface

我正在使用数据库,运行动态生成的查询。一切都很好,当我注意到在一个表中的几行中编码时出现问题,所以我从备份重新填充它并重建了表。

执行此操作后,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 version():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 - 参数数组。

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

更改$this->PDOFetchMode

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

其他代码是关于参数验证,单例实现等。

编辑:

受到这篇文章的启发:PDO prepare statement and match against in boolean mode

我尝试了绑定参数,但这没有帮助

我已经根据他的评论直接尝试了Paul T.关于在查询中使用参数的建议,但这也没有帮助。不过,我得到的查询仍然可以在CLI中成功运行。

1 个答案:

答案 0 :(得分:1)

这个帖子的最佳答案非常不寻常地解决了这个问题: 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.获取灵感