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);
	}
}

MySQL просмотров: 316

Комментарии

Ваш комментарий будет первым.
Войдите, чтобы оставить комментарий.