私はちょうど同じ問題に出くわしました。私にとっては、独自のステートメントクラス(拡張PDOStatement
)を独自のexecute()
メソッドで使用すると修正されました。
これはクラスです:
class MyPDOStatement extends PDOStatement {
public function execute($input_parameters = null) {
if (is_array($input_parameters)) {
$i = 1;
foreach ($input_parameters as $p) {
// default to string datatype
$parameterType = PDO::PARAM_STR;
// now let's see if there is something more appropriate
if (is_bool($p)) {
$parameterType = PDO::PARAM_BOOL;
} elseif (is_null($p)) {
$parameterType = PDO::PARAM_NULL;
} elseif (is_int($p)) {
$parameterType = PDO::PARAM_INT;
}
// parameters passed to execute() are input-only parameters, so use
// bindValue()
$this->bindValue($i, $p, $parameterType);
$i++;
}
}
return parent::execute();
}
}
PDO にデフォルトのステートメント クラスの代わりにこのステートメント クラスを使用するように指示するには、次のようにします。
$db = new PDO(...);
$db->setAttribute(PDO::ATTR_STATEMENT_CLASS, array('MyPDOStatement'));
問題のコードが機能するようになりました。
$start = 0;
$rows = 20;
$sql = "SELECT * FROM tbl_news ORDER BY date DESC LIMIT ?, ?";
$q = $db->prepare($sql);
$q->execute(array($start , $rows));
確実にする必要があるのは、ステートメントにバインドされた変数が正しい型である整数であることだけです。配列などの数値文字列がある場合は、次の$_GET
ようにすることができます。
if (isset($_GET['start']) && is_numeric($_GET['start'])
&& is_int($_GET['start'] + 0) {
$start = (int) $_GET['start'];
}
最後にもっと簡単な方法があるかどうかはわかりませんが、少なくとも私にとってはうまくいきます。