0

我正在尝试创建一个带有变量 LIMIT 值的 MySQL 查询,以在多个页面上显示表结果。这不起作用:

// Check the page number
if (isset($_GET["usPage"])) { 
    $treatedPage  = mysql_real_escape_string(strip_tags($_GET["usPage"])); 
} else { 
    $treatedPage=1; 
}
$start_from = ($treatedPage-1) * 20; 
// Prepare MySQL query with a variable depending on page to display
$req = $DB->prepare('SELECT * FROM Table ORDER BY Id ASC LIMIT :MySQL_start_from, 20');
$req->execute(array(
    'MySQL_start_from' => $start_from
    ));
// Fetch result and display array content
$row = $req->fetch();
echo '<pre>';
print_r($row);
echo '</pre>';

如果我将 :MySQL_start_from 替换为 0,我可以显示行内容。我认为我的问题来自查询中的那个变量。发现任何错误?

4

2 回答 2

1

将您的 PDO 设置为非仿真模式

$DB->setAttribute( PDO::ATTR_EMULATE_PREPARES, FALSE);

或绑定你的变量显式设置它的类型为整数使用bindValue

当直接从执行 PDO 绑定变量时,会将它们视为字符串,因此您的查询看起来像ORDER BY Id ASC LIMIT '0', 20')并导致解析错误。

顺便说一句,要被通知这些错误总是告诉 PDO 抛出一个异常:

$DB->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION );

当然,您必须同时摆脱mysql_real_escape_stringand strip_tags,因为它们在这里毫无用处。

所以最终的代码是

//  right after $DB = new PDO...
$DB->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION );
$DB->setAttribute( PDO::ATTR_EMULATE_PREPARES, FALSE);

// and then with your code
if (isset($_GET["usPage"])) { 
    $treatedPage  = $_GET["usPage"]; 
} else { 
    $treatedPage=1; 
}
$start_from = ($treatedPage-1) * 20; 
// Prepare MySQL query with a variable depending on page to display
$req = $DB->prepare('SELECT * FROM Table ORDER BY Id ASC LIMIT ?, 20');
$req->execute(array($start_from));
// Fetch result and display array content
$row = $req->fetch();
echo '<pre>';
print_r($row);
echo '</pre>';
于 2013-02-19T08:04:39.977 回答
-1

尝试以下面的方式使用:

$dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$sql = "SELECT * FROM table ORDER BY :sort :dir LIMIT :start, :results";
$stmt = $dbh->prepare($sql);
$stmt->bindParam(':start', $_GET['start'], PDO::PARAM_INT);
$stmt->bindParam(':results', $_GET['results'], PDO::PARAM_INT); 
于 2013-02-19T08:08:58.343 回答