Note that when using name parameters with bindParam, the name itself, cannot contain a dash '-'.
example:
<?php
$stmt = $dbh->prepare ("INSERT INTO user (firstname, surname) VALUES (:f-name, :s-name)");
$stmt -> bindParam(':f-name', 'John');
$stmt -> bindParam(':s-name', 'Smith');
$stmt -> execute();
?>
The dashes in 'f-name' and 's-name' should be replaced with an underscore or no dash at all.
See http://bugs.php.net/43130
AdamТрансакции и автоматско запишување
Почист и полокален преглед на PHP референцата, со задржана структура од PHP.net и подобра читливост за примери, секции и белешки.
Трансакции и автоматско запишување
Референца за `pdo.prepared-statements.php` со подобрена типографија и навигација.
Трансакции и автоматско запишување
Many of the more mature databases support the concept of prepared statements. What are they? They can be thought of as a kind of compiled template for the SQL that an application wants to run, that can be customized using variable parameters. Prepared statements offer two major benefits:
- Многу од постарите бази на податоци ја поддржуваат концепцијата на подготвени изрази. Што се тие? Тие можат да се замислат како вид на компилирана шаблон за SQL што апликацијата сака да ја изврши, што може да се прилагоди со помош на променливи параметри. Подготвените изрази нудат две главни придобивки:
- Запитот треба да се парсира (или подготви) само еднаш, но може да се изврши повеќе пати со исти или различни параметри. Кога запитот е подготвен, базата на податоци ќе го анализира, компилира и оптимизира својот план за извршување на запитот. За сложени запити, овој процес може да потрае доволно време што забележливо ќе ја забави апликацијата ако има потреба да се повтори истиот запит многу пати со различни параметри. Со користење на подготвен израз, апликацијата го избегнува повторувањето на циклусот за анализа/компилација/оптимизација. Ова значи дека подготвените изрази користат помалку ресурси и затоа работат побрзо.
Параметрите за подготвените изрази не треба да се цитираат; драјверот автоматски се грижи за тоа. Ако апликацијата исклучиво користи подготвени изрази, програмерот може да биде сигурен дека нема да дојде до SQL инјекција (меѓутоа, ако други делови од запитот се градат со неискористен влез, SQL инјекција е сè уште можна).
Подготвените изрази се толку корисни што тие се единствената карактеристика што PDO ќе ја емулира за драјвери кои не ги поддржуваат. Ова осигурува дека апликацијата ќе може да ја користи истата парадигма за пристап до податоци без оглед на можностите на базата на податоци.
Пример #1 Повторени вметнувања со користење на подготвени изрази name
и value Овој пример извршува INSERT запит со замена на
<?php
$stmt = $dbh->prepare("INSERT INTO REGISTRY (name, value) VALUES (:name, :value)");
$stmt->bindParam(':name', $name);
$stmt->bindParam(':value', $value);
// insert one row
$name = 'one';
$value = 1;
$stmt->execute();
// insert another row with different values
$name = 'two';
$value = 2;
$stmt->execute();
?>
за именуваните заменски места.
Пример #1 Повторени вметнувања со користење на подготвени изрази name
и value Пример #2 Повторени вметнувања со користење на подготвени изрази ? placeholders.
<?php
$stmt = $dbh->prepare("INSERT INTO REGISTRY (name, value) VALUES (?, ?)");
$stmt->bindParam(1, $name);
$stmt->bindParam(2, $value);
// insert one row
$name = 'one';
$value = 1;
$stmt->execute();
// insert another row with different values
$name = 'two';
$value = 2;
$stmt->execute();
?>
за позиционите
Пример #3 Преземање податоци со користење на подготвени изрази
<?php
$stmt = $dbh->prepare("SELECT * FROM REGISTRY where name = ?");
$stmt->execute([$_GET['name']]);
foreach ($stmt as $row) {
print_r($row);
}
?>
Овој пример презема податоци врз основа на клучен вредност што е обезбедена од форма. Влезот на корисникот автоматски се цитира, така што нема ризик од напад со SQL инјекција.
Пример #4 Повикување на складирана процедура со излезен параметар
<?php
$stmt = $dbh->prepare("CALL sp_returns_string(?)");
$stmt->bindParam(1, $return_value, PDO::PARAM_STR, 4000);
// call the stored procedure
$stmt->execute();
print "procedure returned $return_value\n";
?>
Ако драјверот на базата на податоци го поддржува, апликацијата може исто така да врзе параметри за излез, како и за влез. Излезните параметри обично се користат за преземање вредности од складирани процедури. Излезните параметри се малку посложени за употреба од влезните параметри, во смисла дека програмерот мора да знае колку голем може да биде даден параметар кога ќе го врзе. Ако вредноста се покаже поголема од големината што ја предложиле, се појавува грешка.
Пример #5 Повикување на складирана процедура со влезно/излезен параметар
<?php
$stmt = $dbh->prepare("CALL sp_takes_string_returns_string(?)");
$value = 'hello';
$stmt->bindParam(1, $value, PDO::PARAM_STR|PDO::PARAM_INPUT_OUTPUT, 4000);
// call the stored procedure
$stmt->execute();
print "procedure returned $value\n";
?>
Програмерите исто така можат да специфицираат параметри кои држат вредности и за влез и за излез; синтаксата е слична на излезните параметри. Во овој следен пример, низата 'hello' се предава во складираната процедура, и кога ќе се врати, 'hello' се заменува со вратената вредност на процедурата.
<?php
$stmt = $dbh->prepare("SELECT * FROM REGISTRY where name LIKE '%?%'");
$stmt->execute([$_GET['name']]);
// placeholder must be used in the place of the whole value
$stmt = $dbh->prepare("SELECT * FROM REGISTRY where name LIKE ?");
$stmt->execute(["%$_GET[name]%"]);
?>Белешки од корисници 3 белешки
Example #5 gives an 1414 wenn tried on MariaDB. Use this function to call a stored procedure with the last parameter as INOUT returning a value like a (uu)id or a count;
<?php
/**
* call_sp Call the specified stored procedure with the given parameters.
* The first parameter is the name of the stored procedure.
* The remaining parameters are the (in) parameters to the stored procedure.
* the last (out) parameter should be an int like state or number of affected rows.
*
* @param mixed $sp_name The name of the stored procedure to call.
* @param mixed $params The parameters to pass to the stored procedure.
* @return int The number of affected rows.
*/
function call_sp( \PDO $db, string $sp_name, ...$params ): mixed
{
$placeholders = array_fill( 0, count( $params ), "?" );
$placeholders[] = "@new_id";
$sql = "CALL $sp_name( " . implode( ", ", $placeholders ) . " ); SELECT @new_id AS `new_id`";
try {
LOG->debug( "calling Stored Procedure", [ "sql" => $sql ] );
$stmt = $db->prepare( $sql );
$i = 0;
foreach( $params as $param ) {
$stmt->bindValue( ++$i, $param );
}
$stmt->execute();
$new_id = $stmt->fetch( PDO::FETCH_ASSOC )['new_id'];
return $new_id;
} catch ( \Exception $e ) {
LOG->error( "Error calling Stored Procedure", [ "sql" => $sql, "params" => $params, "error" => $e->getMessage() ] );
throw $e;
}Insert a multidimensional array into the database through a prepared query:
We have an array to write the form:
$dataArr:
Array
(
[0] => Array
(
[0] => 2020
[1] => 23
[2] => 111111
)
[1] => Array
(
[0] => 2020
[1] => 24
[2] => 222222222
)
....
Task: prepare a request and pass through binds
$array = [];
foreach ($dataArr as $k=>$v) {
// $x = 2020, the variable is predetermined in advance, does not change the essence
$array[] = [$x, $k, $v];
}
$sql = ("INSERT INTO `table` (`field`,`field`,`field`) VALUES (?,?,?)");
$db->queryBindInsert($sql,$array);
public function queryBindInsert($sql,$bind) {
$stmt = $this->pdo->prepare($sql);
if(count($bind)) {
foreach($bind as $param => $value) {
$c = 1;
for ($i=0; $i<count($value); $i++) {
$stmt->bindValue($c++, $value[$i]);
}
$stmt->execute();
}
}
}