简体   繁体   English

PHP PDO:SQL查询未返回预期结果

[英]PHP PDO: SQL query not returning expected result

I have a function (see bottom) in PHP, which queries a MySQL database. 我在PHP中有一个函数(见底部),它查询MySQL数据库。 When I use the following values: 当我使用以下值时:

  • $map => 1, $ map => 1,
  • $limit => 10, $ limit => 10,
  • $from => 0, $ from => 0,
  • $to => CURRENT_TIMESTAMP $ to => CURRENT_TIMESTAMP

With the SQL statement: 使用SQL语句:

SELECT user,
       scoreVal AS score,
       UNIX_TIMESTAMP(timestamp) AS timestamp 
  FROM Score 
 WHERE timestamp >= :from 
   AND timestamp <= :to 
   AND map = :map 
 ORDER BY scoreVal DESC, timestamp ASC 
 LIMIT :limit

In phpMyAdmin, I get the following result: 在phpMyAdmin中,我得到以下结果:

phpMyAdmin结果

However the PHP PDO gets returned an empty array. 但是PHP PDO返回一个空数组。

My attempts to debug so far: 我到目前为止尝试调试:

  • I have replaced he prepared SQL query with static values instead of placeholders - Returns correctly 我已经用静态值而不是占位符替换了他准备的SQL查询 - 正确返回
  • Trying each placeholder separately, replacing the rest with tested hard-coded values - Returns nothing 分别尝试每个占位符,用经过测试的硬编码值替换其余的 - 不返回任何内容
  • Instead of passing variables to placeholders I pass fixed constants in the execute(Array()) part. 我没有将变量传递给占位符,而是在execute(Array())部分传递固定常量。 - Returns nothing. - 什么都不返回。
  • I have furthermore discovered after turning on mySQL query logs, that the PHP client Connects, but then quits without sending any queries. 我在打开mySQL查询日志之后进一步发现,PHP客户端连接,但随后退出而不发送任何查询。

From this, I believe it to be a problem with the place holders within the function, however I have been unable to find a reason why they are failing. 由此,我认为这是函数中占位符的一个问题,但是我一直无法找到他们失败的原因。 This is most probably occurring on the PHP side, as no errors are being thrown by MySQL to the error file. 这很可能发生在PHP端,因为MySQL没有错误抛出错误文件。

This is the function I am using, with the variables being passed in: 这是我正在使用的函数,传入的变量是:

  • $map => 1, $ map => 1,
  • $limit => 10, $ limit => 10,
  • $from => 0, $ from => 0,
  • $to => 0 $ to => 0

Function: 功能:

/**
 * Gets the highscore list for the map in that timespan
 * @param  integer $map   Id of map for which to fetch the highscore
 * @param  integer $limit Maximum no. of records to fetch
 * @param  integer $from  Timestamp from when to find rank
 * @param  integer $to    Timestamp up to when to find rank
 * @return array   Array of highscores arranged by rank for the map in the format [{"user"=>$user,"score"=>score,"timestamp" => timestamp}]
 */
function get_highscore_list($map,$limit,$from,$to){
    $sql = "SELECT user,scoreVal AS score,UNIX_TIMESTAMP(timestamp) AS timestamp FROM Score WHERE timestamp >= :from AND timestamp <= :to AND map = :map ORDER BY scoreVal DESC, timestamp ASC LIMIT :limit";
    if ($to==intval(0)){
        $max =1;
        $sql = str_replace(":to","NOW()",$sql,$max);
    }
    try{
    $conn = request_connection();
    $stmt = $conn->prepare($sql);
    $stmt->execute(array(':map'=>$map,':from'=>$from,':limit'=>$limit));
    $result = $stmt->fetchAll(PDO::FETCH_ASSOC);
    }catch(PDOException $e){
        $_POST["exception"]=$e;
        continue;
    }
    return $result;
}

EDITS EDITS


Format of MySQL table: MySQL表的格式:

MySQL表格式


I have tried outputting the $conn->errorInfo();, however as no error is being thrown, I get returned an array of values: [00000,null,null] 我已经尝试输出$ conn-> errorInfo();但是由于没有抛出错误,我得到一个值数组:[00000,null,null]


The request_connection function only returns the result of this function, and it is working for all of my other statements. request_connection函数只返回此函数的结果,它适用于我的所有其他语句。

/**
 * Creates a new PDO connection to the database specified in the configuration file
 * @author Ignacy Debicki
 * @return PDO A new open PDO connection to the database
 */
function create_connection(){
    try {
        $config = parse_ini_file('caDB.ini');
        $conn = new PDO('mysql' . ':host=' . $config['dbHost'] . ';dbname=' . $config['db'],$config['dbPHPUser'], $config['dbPHPPass']);
        date_default_timezone_set($config['dbTimezone']);
        return $conn;
    } catch(PDOException $e){
        throw new Exception("Failed to initiate connection",102,$e);
    }   
}

Thanks 谢谢

After many hours of trying, I have finally found my solution. 经过几个小时的尝试,我终于找到了解决方案。

Two important statements that I had missed out from creating my connection are: 我在创建连接时遗漏的两个重要陈述是:

$conn->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
$conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

which turn on error reporting (See https://stackoverflow.com/a/8776392/2891273 ). 打开错误报告(请参阅https://stackoverflow.com/a/8776392/2891273 )。

Once I turned this on, it was trivial to catch my problem, which was due to the overwriting of the :to parameter if $to was 0, the number of parameters passed in the $conn->execute() statement was mismatched with the number of parameters in the sql query. 一旦我打开它,抓住我的问题很简单,这是由于覆盖了:to参数如果$ to为0,则在$conn->execute()语句中传递的参数数量不匹配sql查询中的参数数量。

My solution was to use $conn->bindValue() for each parameter instead, using an if statement to check if to bind to the :to parameter. 我的解决方案是为每个参数使用$conn->bindValue() ,使用if语句检查是否绑定到:to参数。 Below is my solution: 以下是我的解决方案:

function get_highscore_list($map,$limit,$from,$to){
    $sql='SELECT user, scoreVal AS score, UNIX_TIMESTAMP(timestamp) AS timestamp FROM Score WHERE map = :map AND timestamp >= :from AND timestamp <= :to ORDER BY scoreVal DESC, timestamp ASC LIMIT :limit';
    if ($to==0){
        $sql = str_replace(":to",'CURRENT_TIMESTAMP()',$sql);
    }
    $conn = request_connection();
    $stmt = $conn->prepare($sql);
    $stmt->bindValue(':map',$map,PDO::PARAM_INT);
    $stmt->bindValue(':from',$from,PDO::PARAM_INT);
    if ($to!=0){
        $stmt->bindValue(':to',$to,PDO::PARAM_INT);
    }
    $stmt->bindValue(':limit',$limit,PDO::PARAM_INT);
    $stmt->execute();
    $result = $stmt->fetchAll(PDO::FETCH_ASSOC);
    return $result;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM