我在 PHP 中有一个函数(见底部),它查询 MySQL 数据库。 当我使用以下值时:
- $map => 1,
- $limit => 10,
- $from => 0,
- $to => CURRENT_TIMESTAMP
用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
在 phpMyAdmin 中,我得到以下结果:
但是 PHP PDO 返回一个空数组。
到目前为止我的调试尝试:
- 我已将他准备的 SQL 查询替换为静态值而不是占位符 - 正确返回
- 分别尝试每个占位符,用经过测试的硬编码值替换其余部分 - 不返回任何内容
- 我没有将变量传递给占位符,而是在 execute(Array()) 部分传递了固定常量。 - 什么都不返回。
- 我还发现在打开 mySQL 查询日志后,PHP 客户端连接,但随后没有发送任何查询就退出了。
据此,我认为这是函数内占位符的问题,但我一直无法找到它们失败的原因。这很可能发生在 PHP 端,因为 MySQL 没有向错误文件抛出任何错误。
这是我正在使用的函数,其中传递了变量:
- $map => 1,
- $limit => 10,
- $from => 0,
- $to => 0
功能:
/**
* 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;
}
编辑
MySQL表的格式:
我已经尝试输出 $conn->errorInfo();,但是由于没有抛出任何错误,我得到了一个值数组: [00000,null,null]
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);
}
}
谢谢
最佳答案
经过几个小时的尝试,我终于找到了我的解决方案。
我在创建连接时遗漏了两个重要声明:
$conn->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
$conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
打开错误报告(参见 https://stackoverflow.com/a/8776392/2891273)。
一旦我打开它,就很容易发现我的问题,这是由于覆盖了 :to 参数,如果 $to 为 0,$conn->execute( )
语句与 sql 查询中的参数数量不匹配。
我的解决方案是对每个参数使用 $conn->bindValue()
,使用 if 语句检查是否绑定(bind)到 :to 参数。以下是我的解决方案:
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;
}
关于PHP PDO : SQL query not returning expected result,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34660914/