PDO::prepare
Подготавливает инструкцию для выполнения.
Синтаксис
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. - Когда подготовленная инструкция вызывает хранимую процедуру с заполнителем в качестве аргумента выходного параметра, исключение не возникает, так как драйвер не может обнаружить выходной параметр. Однако переменная, которую пользователь предоставляет для выходного параметра, остается неизменной.
- Когда пользователь создает подготовленную инструкцию с заполнителями для выходных параметров (то есть со знаком равенства сразу же после заполнителя, например
- Повторяющиеся заполнители для двоичного закодированного параметра не работают.