MySQL: Запрос LIMIT OFFSET с подготовленными параметрами PHP PDO
C «ленивой» привязкой (с использованием массива в execute()) параметров PDO обрабатывает каждый параметр как строку. В результате подготовленный запрос LIMIT ?, ? преобразуется в LIMIT '10', '10'. Строковые параметры являются недопустимым синтаксисом. В результате заброс не будет выполнен корректно.
Первое решение
Отключить режим эмуляции подготовленных запросов, который включен по умолчанию. Для этого атрибуту объекта PDO PDO::ATTR_EMULATE_PREPARE нужно задать значение false.
$start = 0; $limit = 30; $conn->setAttribute( PDO::ATTR_EMULATE_PREPARES, false ); $sql = "SELECT `id` FROM `test` LIMIT :start, :limit "; $st = $pdo->prepare( $sql ) if( $st->execute([ ':start' => $start, ':limit' => $limit, ]) ) { foreach ( $st as $row ) { print_r($row); } }
Второе решение
Указываем параметры не массивом в execute(), а отдельно с указанием типа данных - PDO::PARAM_INT.
$start = 0; $limit = 30; $sql = "SELECT `id` FROM `test` LIMIT :start, :limit "; $st = $pdo->prepare( $sql ) $st->bindValue(':start', $start, PDO::PARAM_INT); $st->bindValue(':limit', $limit, PDO::PARAM_INT); if( $st->execute() ) { foreach ( $st as $row ) { print_r($row); } }
Третье решение
Выходим за рамки подготовленных параметров PDO и используем функицю sprintf().
$start = 0; $limit = 30; $sql = "SELECT `id` FROM `test` LIMIT %d, %d "; $sql = sprintf( $sql, $start, $limit ); $st = $pdo->prepare( $sql ) if( $st->execute() ) { foreach ( $st as $row ) { print_r($row); } }
Комментарии