PDOStatement::bindParam
Binds a parameter to a named or question mark placeholder in the SQL statement.
Syntax
bool PDOStatement::bindParam($parameter, &$variable[, $data_type[, $length[, $driver_options]]]);
Parameters
$parameter: A (mixed) parameter identifier. For a statement using named placeholders, use a parameter name (:name). For a prepared statement using the question mark syntax, it is the 1-based index of the parameter.
&$variable: The (mixed) name of the PHP variable to bind to the SQL statement parameter.
$data_type: An optional (integer) PDO::PARAM_* constant. Default is PDO::PARAM_STR.
$length: An optional (integer) length of the data type. You can specify PDO::SQLSRV_PARAM_OUT_DEFAULT_SIZE to indicate the default size when using PDO::PARAM_INT or PDO::PARAM_BOOL in $data_type.
$driver_options: The optional (mixed) driver-specific options. For example, you could specify PDO::SQLSRV_ENCODING_UTF8 to bind the column to a variable as a string encoded in UTF-8.
Return Value
TRUE on success, otherwise FALSE.
Remarks
When binding null data to server columns of type varbinary, binary, or varbinary(max) you should specify binary encoding (PDO::SQLSRV_ENCODING_BINARY) using the $driver_options. For more information about encoding constants, see Constants.
Support for PDO was added in version 2.0 of the Microsoft Drivers for PHP for SQL Server.
Parameter example
This code sample shows that after $contact is bound to the parameter, changing the value does change the value passed in the query.
prepare("select * from Person.ContactType where name = ?"); $stmt->bindParam(1, $contact); $contact = "Owner"; $stmt->execute(); while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) < print "$row[Name]\n\n"; >$stmt = null; $contact = "Sales Agent"; $stmt = $conn->prepare("select * from Person.ContactType where name = :contact"); $stmt->bindParam(':contact', $contact); $contact = "Owner"; $stmt->execute(); while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) < print "$row[Name]\n\n"; >?>
Output parameter example
This code sample shows how to access an output parameter.
prepare("select ? = count(*) from Sys.tables"); $stmt->bindParam(1, $input1, PDO::PARAM_STR, 10); $stmt->execute(); echo $input1; ?>
When binding an output parameter to a bigint type, if the value may end up outside the range of an integer, using PDO::PARAM_INT with PDO::SQLSRV_PARAM_OUT_DEFAULT_SIZE may result in a «value out of range» exception. Therefore, use the default PDO::PARAM_STR instead and provide the size of the resulting string, which is at most 21. It is the maximum number of digits, including the negative sign, of any bigint value.
Input/Output example
This code sample shows how to use an input/output parameter.
query("IF OBJECT_ID('dbo.sp_ReverseString', 'P') IS NOT NULL DROP PROCEDURE dbo.sp_ReverseString"); $dbh->query("CREATE PROCEDURE dbo.sp_ReverseString @String as VARCHAR(2048) OUTPUT as SELECT @String = REVERSE(@String)"); $stmt = $dbh->prepare("EXEC dbo.sp_ReverseString ?"); $string = "123456789"; $stmt->bindParam(1, $string, PDO::PARAM_STR | PDO::PARAM_INPUT_OUTPUT, 2048); $stmt->execute(); print $string; // Expect 987654321 ?>
It is recommended to use strings as inputs when binding values to a decimal or numeric column to ensure precision and accuracy as PHP has limited precision for floating point numbers. The same applies to bigint columns, especially when the values are outside the range of an integer.
Decimal input example
This code sample shows how to bind a decimal value as an input parameter.
prepare("INSERT INTO TestTable (DecimalCol) VALUES (?)"); // by default it is PDO::PARAM_STR, rounding of a large input value may // occur if PDO::PARAM_INT is specified $stmt->bindParam(1, $input, PDO::PARAM_STR); $stmt->execute();
Подготовленные запросы и хранимые процедуры
Большинство баз данных поддерживают концепцию подготовленных запросов. Что это такое? Это можно описать, как некий вид скомпилированного шаблона SQL запроса, который будет запускаться приложением и настраиваться с помощью входных параметров. У подготовленных запросов есть два главных преимущества:
- Запрос необходимо однажды подготовить и затем его можно запускать столько раз, сколько нужно, причём как с теми же, так и с отличающимися параметрами. Когда запрос подготовлен, СУБД анализирует его, компилирует и оптимизирует план его выполнения. В случае сложных запросов этот процесс может занимать ощутимое время и заметно замедлить работу приложения, если потребуется много раз выполнять запрос с разными параметрами. При использовании подготовленного запроса СУБД анализирует/компилирует/оптимизирует запрос любой сложности только один раз, а приложение запускает на выполнение уже подготовленный шаблон. Таким образом подготовленные запросы потребляют меньше ресурсов и работают быстрее.
- Параметры подготовленного запроса не требуется экранировать кавычками; драйвер это делает автоматически. Если в приложении используются исключительно подготовленные запросы, разработчик может быть уверен, что никаких SQL-инъекций случиться не может (однако, если другие части текста запроса создаются с неэкранированным вводом, то SQL инъекция по-прежнему возможна).
Подготовленные запросы также полезны тем, что PDO может эмулировать их, если драйвер базы данных не имеет подобной функциональности. Это значит, что приложение может пользоваться одной и той же методикой доступа к данным независимо от возможностей СУБД.
Пример #1 Повторяющиеся вставки в базу с использованием подготовленных запросов
В этом примере 2 раза выполняется INSERT запрос с разными значениями name и value , которые подставляются вместо соответствующих псевдопеременных:
$stmt = $dbh -> prepare ( «INSERT INTO REGISTRY (name, value) VALUES (:name, :value)» );
$stmt -> bindParam ( ‘:name’ , $name );
$stmt -> bindParam ( ‘:value’ , $value );
?php
// вставим одну строку
$name = ‘one’ ;
$value = 1 ;
$stmt -> execute ();
// теперь другую строку с другими значениями
$name = ‘two’ ;
$value = 2 ;
$stmt -> execute ();
?>
Пример #2 Повторяющиеся вставки в базу с использованием подготовленных запросов
В этом примере 2 раза выполняется INSERT запрос с разными значениями name и value , которые подставляются вместо псевдопеременных ? .
$stmt = $dbh -> prepare ( «INSERT INTO REGISTRY (name, value) VALUES (?, ?)» );
$stmt -> bindParam ( 1 , $name );
$stmt -> bindParam ( 2 , $value );
?php
// вставим одну строку
$name = ‘one’ ;
$value = 1 ;
$stmt -> execute ();
// теперь другую строку с другими значениями
$name = ‘two’ ;
$value = 2 ;
$stmt -> execute ();
?>
Пример #3 Выборка данных с использованием подготовленных запросов
В этом примере производится выборка из базы по ключу, который вводит пользователь через форму. Пользовательский ввод автоматически заключается в кавычки, поэтому нет риска SQL инъекции.
$stmt = $dbh -> prepare ( «SELECT * FROM REGISTRY where name = ?» );
$stmt -> execute ([ $_GET [ ‘name’ ]]);
foreach ( $stmt as $row ) print_r ( $row );
>
?>?php
Пример #4 Вызов хранимой процедуры с выходными параметрами
Если СУБД поддерживает выходные параметры, приложение может пользоваться ими также как и входными. Выходные параметры обычно используют для получения данных из хранимых процедур. Пользоваться выходными параметрами несколько сложнее, так как разработчику необходимо знать максимальный размер извлекаемых значений ещё на этапе задания этих параметров. Если извлекаемое значение окажется больше, чем предполагалось, будет вызвана ошибка.
$stmt = $dbh -> prepare ( «CALL sp_returns_string(?)» );
$stmt -> bindParam ( 1 , $return_value , PDO :: PARAM_STR , 4000 );
?php
// вызов хранимой процедуры
$stmt -> execute ();
print «процедура вернула $return_value \n» ;
?>
Пример #5 Вызов хранимой процедуры с входным/выходным параметром
Можно задать параметр одновременно входным и выходным; синтаксис при этом тот же, что и для выходных параметров. В следующем примере строка ‘привет’ передаётся в хранимую процедуру, а затем эта строка будет заменена возвращаемым значением.
$stmt = $dbh -> prepare ( «CALL sp_takes_string_returns_string(?)» );
$value = ‘привет’ ;
$stmt -> bindParam ( 1 , $value , PDO :: PARAM_STR | PDO :: PARAM_INPUT_OUTPUT , 4000 );
?php
// вызов хранимой процедуры
$stmt -> execute ();
print «процедура вернула $value \n» ;
?>
Пример #6 Неправильное использование псевдопеременной
$stmt = $dbh -> prepare ( «SELECT * FROM REGISTRY where name LIKE ‘%?%'» );
$stmt -> execute ([ $_GET [ ‘name’ ]]);
?php
// псевдопеременная может использоваться только в виде отдельного значения
$stmt = $dbh -> prepare ( «SELECT * FROM REGISTRY where name LIKE ?» );
$stmt -> execute ([ «% $_GET [ name ] %» ]);
?>
PDOStatement::bindParam
Связывает PHP переменную с именованным или неименованным параметром подготавливаемого SQL запроса. В отличие от PDOStatement::bindValue() , переменная привязывается по ссылке, и ее значение будет вычисляться во время вызова PDOStatement::execute() .
В большинстве случаев в подготавливаемых запросах используются только входные параметры, то есть при построении запроса доступ к ним осуществляется только в режиме чтения. Тем не менее, некоторые драйверы позволяют запускать хранимые процедуры, которые, в свою очередь, могут возвращать данные посредством выходных параметров. Зачастую, такие параметры используются одновременно как входные и как выходные.
Список параметров
Идентификатор параметра. Для подготавливаемых запросов с именованными параметрами это будет имя в виде :name . Если используются неименованные параметры (знаки вопроса ?) это будет позиция псевдопеременной в запросе (начиная с 1).
Имя PHP переменной, которую требуется привязать к параметру SQL запроса.
Явно заданный тип данных параметра. Тип задается одной из констант PDO::PARAM_*. Если параметр используется в том числе для вывода информации из хранимой процедуры, к значению аргумента data_type необходимо добавить PDO::PARAM_INPUT_OUTPUT, используя оператор побитовое ИЛИ.
Размер типа данных. Чтобы указать, что параметр используется для вывода данных из хранимой процедуры, необходимо явно задать его размер.
Возвращаемые значения
Возвращает TRUE в случае успешного завершения или FALSE в случае возникновения ошибки.
Примеры
Пример #1 Выполнение подготовленного запроса с именованными псевдопеременными
/* Выполнение запроса с привязкой PHP переменных */
$calories = 150 ;
$colour = ‘red’ ;
$sth = $dbh -> prepare ( ‘SELECT name, colour, calories
FROM fruit
WHERE calories < :calories AND colour = :colour' );
$sth -> bindParam ( ‘:calories’ , $calories , PDO :: PARAM_INT );
$sth -> bindParam ( ‘:colour’ , $colour , PDO :: PARAM_STR , 12 );
$sth -> execute ();
?>?php
Пример #2 Выполнение подготовленного запроса с неименованными псевдопеременными (?)
/* Выполнение запроса с привязкой PHP переменных */
$calories = 150 ;
$colour = ‘red’ ;
$sth = $dbh -> prepare ( ‘SELECT name, colour, calories
FROM fruit
WHERE calories < ? AND colour = ?' );
$sth -> bindParam ( 1 , $calories , PDO :: PARAM_INT );
$sth -> bindParam ( 2 , $colour , PDO :: PARAM_STR , 12 );
$sth -> execute ();
?>?php
Пример #3 Вызов хранимой процедуры с INOUT параметром
/* Вызов хранимой процедуры с INOUT параметром */
$colour = ‘red’ ;
$sth = $dbh -> prepare ( ‘CALL puree_fruit(?)’ );
$sth -> bindParam ( 1 , $colour , PDO :: PARAM_STR | PDO :: PARAM_INPUT_OUTPUT , 12 );
$sth -> execute ();
print( «After pureeing fruit, the colour is: $colour » );
?>?php
Смотрите также
- PDO::prepare() — Подготавливает запрос к выполнению и возвращает ассоциированный с этим запросом объект
- PDOStatement::execute() — Запускает подготовленный запрос на выполнение
- PDOStatement::bindValue() — Связывает параметр с заданным значением