Поделиться через


PDO::prepare

Скачать драйвер PHP

Подготавливает инструкцию для выполнения.

Синтаксис

PDOStatement PDO::prepare ( $statement [ , array(key_pair) ] )

Параметры

$инструкция

Строка, содержащая инструкцию SQL.

key_pair

Массив, содержащий имя и значение атрибута. Дополнительные сведения см. в разделе с примечаниями.

Возвращаемое значение

Возвращает объект при успешном выполнении PDOStatement . При сбое возвращает PDOException объект или значение false в зависимости от значения PDO::ATTR_ERRMODE.

Замечания

Драйверы Майкрософт для PHP для SQL Server не оценивают подготовленные инструкции до выполнения.

Возможные значения key_pair перечислены в следующей таблице.

Ключ. Description
PDO::ATTR_CURSOR Определяет поведение курсора. По умолчанию используется PDO::CURSOR_FWDONLY, непрокручиваемый однонаправленный курсор. PDO::CURSOR_SCROLL является прокручиваемым курсором.

Например, array( PDO::ATTR_CURSOR => PDO::CURSOR_FWDONLY ).

Если задано значение PDO::CURSOR_SCROLL, можно использовать PDO::SQLSRV_ATTR_CURSOR_SCROLL_TYPE для задания типа прокручиваемого курсора, описанного далее в этой статье.

Дополнительные сведения о результирующих наборах и курсорах в драйвере PDO_SQLSRV см. в разделе "Типы курсоров" (драйвер PDO_SQLSRV).
PDO::ATTR_EMULATE_PREPARES По умолчанию этот атрибут имеет значение false, но вы можете изменить его с помощью PDO::ATTR_EMULATE_PREPARES => true. В статье о подготовке эмуляции приводятся подробные сведения и пример.
PDO::SQLSRV_ATTR_CURSOR_SCROLL_TYPE Задает тип прокручиваемого курсора. Действует, только если PDO::ATTR_CURSOR имеет значение PDO::CURSOR_SCROLL. Дополнительные сведения см. в этой статье о значениях, которые может принимать этот атрибут.
PDO::SQLSRV_ATTR_DECIMAL_PLACES Указывает число десятичных знаков при форматировании полученных денежных значений. Этот параметр работает только в том случае, если PDO::SQLSRV_ATTR_FORMAT_DECIMALS имеет значение true. См. подробнее о форматировании десятичных строк и денежных значений (драйвер PDO_SQLSRV).
PDO::SQLSRV_ATTR_DIRECT_QUERY При Trueуказании прямого выполнения запроса. False означает выполнение подготовленной инструкции. Дополнительные сведения о PDO::SQLSRV_ATTR_DIRECT_QUERY см. в статье Выполнение прямых и подготовленных инструкций в драйвере PDO_SQLSRV.
PDO::SQLSRV_ATTR_ENCODING PDO::SQLSRV_ENCODING_UTF8 (по умолчанию)
PDO::SQLSRV_ENCODING_SYSTEM
PDO::SQLSRV_ENCODING_BINARY
PDO::SQLSRV_ATTR_FETCHES_DATETIME_TYPE Указывает, нужно ли извлекать типы даты и времени в виде объектов PHP DateTime. См. подробнее об извлечении типов даты и времени в виде объектов PHP DateTime с помощью драйвера PDO_SQLSRV.
PDO::SQLSRV_ATTR_FETCHES_NUMERIC_TYPE Обрабатывает выборку числовых значений из столбцов с числовыми типами SQL. Дополнительные сведения см. в статье PDO::setAttribute.
PDO::SQLSRV_ATTR_FORMAT_DECIMALS Указывает, нужно ли при необходимости добавлять начальные нули к десятичным строкам. Если задан этот параметр, включается параметр PDO::SQLSRV_ATTR_DECIMAL_PLACES для форматирования денежных типов. См. подробнее о форматировании десятичных строк и денежных значений (драйвер PDO_SQLSRV).
PDO::SQLSRV_ATTR_QUERY_TIMEOUT Дополнительные сведения см. в статье PDO::setAttribute.

При использовании PDO::ATTR_CURSOR => PDO::CURSOR_SCROLL вы можете применить PDO::SQLSRV_ATTR_CURSOR_SCROLL_TYPE для указания типа курсора. Например, передайте следующий массив, чтобы PDO::prepare задать динамический курсор:

array(PDO::ATTR_CURSOR => PDO::CURSOR_SCROLL, PDO::SQLSRV_ATTR_CURSOR_SCROLL_TYPE => PDO::SQLSRV_CURSOR_DYNAMIC));

В следующей таблице приводятся возможные значения PDO::SQLSRV_ATTR_CURSOR_SCROLL_TYPE. Дополнительные сведения о прокручиваемых курсорах см. в статье Типы курсоров (драйвер PDO_SQLSRV).

значение Описание
PDO::SQLSRV_CURSOR_BUFFERED Создает клиентский (буферизованный) статический курсор, который помещает результирующий набор в память на клиентском компьютере.
PDO::SQLSRV_CURSOR_DYNAMIC Создает динамический курсор на стороне сервера ,который позволяет получать доступ к строкам в любом порядке и отражать изменения в базе данных.
PDO::SQLSRV_CURSOR_KEYSET Создает серверный курсор набора ключей. Курсор набора ключей не обновляет число строк, если строка удаляется из таблицы (удаленная строка возвращается без значений).
PDO::SQLSRV_CURSOR_STATIC Создает статический курсор на стороне сервера, который позволяет получать доступ к строкам в любом порядке, но не отражает изменения в базе данных.

PDO::ATTR_CURSOR => PDO::CURSOR_SCROLL подразумевает PDO::SQLSRV_ATTR_CURSOR_SCROLL_TYPE => PDO::SQLSRV_CURSOR_STATIC.

Можно закрыть PDOStatement объект, вызвав:unset

unset($stmt);

Пример последовательного доступа

В этом примере показано, как использовать PDO::prepare маркеры параметров и курсор только для пересылки.

<?php
$database = "Test";
$server = "(local)";
$conn = new PDO( "sqlsrv:server=$server ; Database = $database", "", "");

$col1 = 'a';
$col2 = 'b';

$query = "insert into Table1(col1, col2) values(?, ?)";
$stmt = $conn->prepare( $query, array( PDO::ATTR_CURSOR => PDO::CURSOR_FWDONLY, PDO::SQLSRV_ATTR_QUERY_TIMEOUT => 1  ) );
$stmt->execute( array( $col1, $col2 ) );
print $stmt->rowCount();
echo "\n";

$query = "insert into Table1(col1, col2) values(:col1, :col2)";
$stmt = $conn->prepare( $query, array( PDO::ATTR_CURSOR => PDO::CURSOR_FWDONLY, PDO::SQLSRV_ATTR_QUERY_TIMEOUT => 1  ) );
$stmt->execute( array( ':col1' => $col1, ':col2' => $col2 ) );
print $stmt->rowCount();

unset($stmt);
?>

Пример статического курсора

В этом примере показано, как использовать PDO::prepare статический курсор на стороне сервера. Пример использования курсора на стороне клиента см. в статье Типы курсоров (драйвер PDO_SQLSRV).

<?php
$database = "AdventureWorks";
$server = "(local)";
$conn = new PDO( "sqlsrv:server=$server ; Database = $database", "", "");

$query = "select * from Person.ContactType";
$stmt = $conn->prepare( $query, array(PDO::ATTR_CURSOR => PDO::CURSOR_SCROLL));
$stmt->execute();

echo "\n";

while ( $row = $stmt->fetch( PDO::FETCH_ASSOC ) ){
   print "$row[Name]\n";
}
echo "\n..\n";

$row = $stmt->fetch( PDO::FETCH_BOTH, PDO::FETCH_ORI_FIRST );
print_r($row);

$row = $stmt->fetch( PDO::FETCH_ASSOC, PDO::FETCH_ORI_REL, 1 );
print "$row[Name]\n";

$row = $stmt->fetch( PDO::FETCH_NUM, PDO::FETCH_ORI_NEXT );
print "$row[1]\n";

$row = $stmt->fetch( PDO::FETCH_NUM, PDO::FETCH_ORI_PRIOR );
print "$row[1]..\n";

$row = $stmt->fetch( PDO::FETCH_NUM, PDO::FETCH_ORI_ABS, 0 );
print_r($row);

$row = $stmt->fetch( PDO::FETCH_NUM, PDO::FETCH_ORI_LAST );
print_r($row);
?>

Пример целевого объекта

В следующих двух фрагментах показано, как использовать PDO::prepare данные, предназначенные для столбцов char / varchar. Так как кодировка по умолчанию — PDO::prepare UTF-8, пользователь может использовать этот параметр PDO::SQLSRV_ENCODING_SYSTEM , чтобы избежать неявных преобразований.

Вариант 1

$options = array(PDO::SQLSRV_ATTR_ENCODING => PDO::SQLSRV_ENCODING_SYSTEM);
$statement = $pdo->prepare(
  'SELECT *
   FROM myTable
   WHERE myVarcharColumn = :myVarcharValue',
  $options
);

$statement->bindValue(':myVarcharValue', 'my data', PDO::PARAM_STR);

Вариант 2

$statement = $pdo->prepare(
  'SELECT *
   FROM myTable
   WHERE myVarcharColumn = :myVarcharValue'
);
$p = 'my data';
$statement->bindParam(':myVarcharValue', $p, PDO::PARAM_STR, 0, PDO::SQLSRV_ENCODING_SYSTEM);

Пример подготовки

В этом примере показано, как использовать PDO::prepare с PDO::ATTR_EMULATE_PREPARES, имеющим значение true.

<?php
$serverName = "yourservername";
$username = "yourusername";
$password = "yourpassword";
$database = "tempdb";
$conn = new PDO("sqlsrv:server = $serverName; Database = $database", $username, $password);

$pdo_options = array();
$pdo_options[PDO::ATTR_EMULATE_PREPARES] = true;
$pdo_options[PDO::SQLSRV_ATTR_ENCODING] = PDO::SQLSRV_ENCODING_UTF8;

$stmt = $conn->prepare("CREATE TABLE TEST([id] [int] IDENTITY(1,1) NOT NULL,
                                          [name] nvarchar(max))",
                                          $pdo_options);
$stmt->execute();

$prefix = '가각';
$name = '가각ácasa';
$name2 = '가각sample2';

$stmt = $conn->prepare("INSERT INTO TEST(name) VALUES(:p0)", $pdo_options);
$stmt->execute(['p0' => $name]);
unset($stmt);

$stmt = $conn->prepare("SELECT * FROM TEST WHERE NAME LIKE :p0", $pdo_options);
$stmt->execute(['p0' => "$prefix%"]);
foreach ($stmt as $row) {
    echo "\n" . 'FOUND: ' . $row['name'];
}

unset($stmt);
unset($conn);
?>

Драйвер PDO_SQLSRV внутренне заменяет все заполнители параметрами, привязанными PDOStatement ::bindParam(). Таким образом, на сервер отправляется строка запроса SQL уже без заполнителей. Рассмотрим следующий пример:

$statement = $PDO->prepare("INSERT into Customers (CustomerName, ContactName) VALUES (:cus_name, :con_name)");
$statement->bindParam(:cus_name, "Cardinal");
$statement->bindParam(:con_name, "Tom B. Erichsen");
$statement->execute();

Когда PDO::ATTR_EMULATE_PREPARES имеет значение false (вариант по умолчанию), в базу данных отправляются следующие данные:

"INSERT into Customers (CustomerName, ContactName) VALUES (:cus_name, :con_name)"
Information on :cus_name parameter
Information on :con_name parameter

Сервер выполняет запрос с помощью параметризованного функции запроса для параметров привязки. Если же PDO::ATTR_EMULATE_PREPARES имеет значение true, на сервер по сути отправляется такой запрос:

"INSERT into Customers (CustomerName, ContactName) VALUES ('Cardinal', 'Tom B. Erichsen')"

Присвоив параметру PDO::ATTR_EMULATE_PREPARES значение true, вы можете обойти некоторые ограничения SQL Server. Например, SQL Server не поддерживает именованные или позиционные параметры в некоторых предложениях Transact-SQL. Кроме того, SQL Server имеет ограничение привязки 2100 параметров.

Примечание.

При эмуляции подготавливает значение true, безопасность параметризованных запросов не действует. Поэтому приложение должно убедиться, что данные, привязанные к параметрам, не содержат вредоносный код Transact-SQL.

Кодировка

Если пользователь хочет привязать параметры с другими кодировками (например UTF-8 или двоичный файл), пользователь должен явно указать кодировку в скрипте PHP.

Драйвер PDO_SQLSRV сначала проверяет кодировку, указанную в PDO::bindParam() (например, $statement->bindParam(:cus_name, "Cardinal", PDO::PARAM_STR, 10, PDO::SQLSRV_ENCODING_UTF8)).

Если ее там нет, драйвер проверяет наличие кодировки в PDO::prepare() или PDOStatement::setAttribute(). В противном случае драйвер использует кодировку, указанную в PDO::__construct() или PDO::setAttribute().

Кроме того, начиная с версии 5.8.0 при использовании PDO::p repare с PDO::ATTR_EMULATE_PREPARES заданным значением true, пользователь может использовать расширенные типы строк, представленные в PHP 7.2 , чтобы убедиться, что N префикс используется. В следующих фрагментах кода отображаются различные альтернативные варианты.

Примечание.

По умолчанию параметр подготовки к эмуляции получает значение false, а значит расширенные строковые константы PDO будут игнорироваться.

Использование параметра драйвера PDO::SQLSRV_ENCODING_UTF8 при привязке

$p = '가각';
$sql = 'SELECT :value';
$options = array(PDO::ATTR_EMULATE_PREPARES => true);
$stmt = $conn->prepare($sql, $options);
$stmt->bindParam(':value', $p, PDO::PARAM_STR, 0, PDO::SQLSRV_ENCODING_UTF8);
$stmt->execute();

Использование атрибута PDO::SQLSRV_ATTR_ENCODING

$p = '가각';
$sql = 'SELECT :value';
$options = array(PDO::ATTR_EMULATE_PREPARES => true, PDO::SQLSRV_ATTR_ENCODING => PDO::SQLSRV_ENCODING_UTF8);
$stmt = $conn->prepare($sql, $options);
$stmt->execute([':value' => $p]);

Использование константы PDO::P ARAM_STR_NATL

$p = '가각';
$sql = 'SELECT :value';
$options = array(PDO::ATTR_EMULATE_PREPARES => true);
$stmt = $conn->prepare($sql, $options);
$stmt->bindParam(':value', $p, PDO::PARAM_STR | PDO::PARAM_STR_NATL);
$stmt->execute();

Установка типа PDO::P ARAM_STR_NATL по умолчанию

$conn->setAttribute(PDO::ATTR_DEFAULT_STR_PARAM, PDO::PARAM_STR_NATL);
$p = '가각';
$sql = 'SELECT :value';
$options = array(PDO::ATTR_EMULATE_PREPARES => true);
$stmt = $conn->prepare($sql, $options);
$stmt->execute([':value' => $p]);

Ограничения

Как вы видите, привязка выполняется внутри драйвера. Запрос отправляется на сервер для выполнения уже без параметров. По сравнению с обычным случаем некоторые ограничения приводят к тому, что параметризованный компонент запроса не используется.

  • Он не работает для параметров, привязанных как PDO::PARAM_INPUT_OUTPUT.
    • Если пользователь указал PDO::PARAM_INPUT_OUTPUT в PDO::bindParam(), создается исключение PDO.
  • Он не работает для параметров, привязанных к выходным параметрам.
    • Когда пользователь создает подготовленную инструкцию с заполнителями для выходных параметров (то есть со знаком равенства сразу же после заполнителя, например SELECT ? = COUNT(*) FROM Table1), создается исключение PDO.
    • Когда подготовленная инструкция вызывает хранимую процедуру с заполнителем в качестве аргумента выходного параметра, исключение не возникает, так как драйвер не может обнаружить выходной параметр. Однако переменная, которую пользователь предоставляет для выходного параметра, остается неизменной.
  • Повторяющиеся заполнители для двоичного закодированного параметра не работают.