PDO 不返回任何结果,而 MySQL 命令行返回预期结果

Posted

技术标签:

【中文标题】PDO 不返回任何结果,而 MySQL 命令行返回预期结果【英文标题】:PDO returns no results while MySQL command line returns expected result 【发布时间】:2017-12-28 11:30:54 【问题描述】:

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

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

    $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 中成功运行。

【问题讨论】:

能否也添加 PDO 处理,因为 PDO 在标题、问题和标签中? 你有什么 MySQL 版本?过去有麻烦with parameters in the AGAINST clause。 您能否提供$parameters 数组的示例var_dump() @PaulT., $parameters 数组通常是从用户作为查询获得的单个参数的重复,它看起来像 '+word +word +*last_word*' 但在本地(俄语)语言。 我很好奇当可能只有 1 个参数或所有 4 个参数时数组可能是什么样子(语言无关紧要),以及它如何影响处理?当存在 4 个参数时它会失败吗?除此之外,我的想法已经不多了。我之前注意到你提到encoding ...这是字符集还是其他问题? 【参考方案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. 的启发

【讨论】:

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

以上是关于PDO 不返回任何结果,而 MySQL 命令行返回预期结果的主要内容,如果未能解决你的问题,请参考以下文章

mysql“日期之间”查询在 phpmyadmin 中有效,但 PDO 不返回任何内容

PDO bindParam 不允许语句返回结果

PDO 不从 mysql 查询返回结果

pdo连接mysql操作方法

PHP,PDO 存储过程不返回任何值或未更改值

PDO 只返回 mysql 的一半结果