PHP.mk документација

Подготвени изрази

Почист и полокален преглед на PHP референцата, со задржана структура од PHP.net и подобра читливост за примери, секции и белешки.

mysqli.quickstart.prepared-statements.php PHP.net прокси Преводот се освежува
Оригинал на PHP.net
Патека mysqli.quickstart.prepared-statements.php Локална патека за оваа страница.
Извор php.net/manual/en Оригиналниот HTML се реупотребува и локално се стилизира.
Режим Прокси + превод во позадина Кодовите, табелите и белешките остануваат читливи во истиот тек.
Подготвени изрази

Референца за `mysqli.quickstart.prepared-statements.php` со подобрена типографија и навигација.

mysqli.quickstart.prepared-statements.php

Подготвени изрази

The MySQL database supports prepared statements. A prepared statement or a parameterized statement is used to execute the same statement repeatedly with high efficiency and protect against SQL injections.

MySQL базата на податоци поддржува подготвени изрази. Подготвен израз или параметарски израз се користи за повторно извршување на истиот израз со висока ефикасност и за заштита од SQL инјекции.

Основен работен тек

Извршувањето на подготвениот израз се состои од две фази: подготовка и извршување. Во фазата на подготовка, шаблон за израз се испраќа до серверот на базата на податоци. Серверот врши проверка на синтаксата и иницијализира внатрешни ресурси на серверот за подоцнежна употреба. ?.

MySQL серверот поддржува користење на анонимни, позиционирани заменски знаци со

Подготовката е проследена со извршување. За време на извршувањето, клиентот ги поврзува вредностите на параметрите и ги испраќа до серверот. Серверот го извршува изразот со поврзаните вредности користејќи ги претходно креираните внатрешни ресурси.

<?php

mysqli_report
(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
$mysqli = new mysqli("example.com", "user", "password", "database");

/* Non-prepared statement */
$mysqli->query("DROP TABLE IF EXISTS test");
$mysqli->query("CREATE TABLE test(id INT, label TEXT)");

/* Prepared statement, stage 1: prepare */
$stmt = $mysqli->prepare("INSERT INTO test(id, label) VALUES (?, ?)");

/* Prepared statement, stage 2: bind and execute */
$id = 1;
$label = 'PHP';
$stmt->bind_param("is", $id, $label); // "is" means that $id is bound as an integer and $label as a string

$stmt->execute();

Пример #1 Подготвен израз

Повторено извршување

Подготвениот израз може да се извршува повеќе пати. При секое извршување, тековната вредност на поврзаната променлива се проценува и се испраќа до серверот. Изразот не се парсира повторно. Шаблонот за израз не се пренесува повторно до серверот.

<?php

mysqli_report
(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
$mysqli = new mysqli("example.com", "user", "password", "database");

/* Non-prepared statement */
$mysqli->query("DROP TABLE IF EXISTS test");
$mysqli->query("CREATE TABLE test(id INT, label TEXT)");

/* Prepared statement, stage 1: prepare */
$stmt = $mysqli->prepare("INSERT INTO test(id, label) VALUES (?, ?)");

/* Prepared statement, stage 2: bind and execute */
$stmt->bind_param("is", $id, $label); // "is" means that $id is bound as an integer and $label as a string

$data = [
1 => 'PHP',
2 => 'Java',
3 => 'C++'
];
foreach (
$data as $id => $label) {
$stmt->execute();
}

$result = $mysqli->query('SELECT id, label FROM test');
var_dump($result->fetch_all(MYSQLI_ASSOC));

Пример #1 Пример што покажува затворачка ознака што го опфаќа последниот нов ред

array(3) {
  [0]=>
  array(2) {
    ["id"]=>
    string(1) "1"
    ["label"]=>
    string(3) "PHP"
  }
  [1]=>
  array(2) {
    ["id"]=>
    string(1) "2"
    ["label"]=>
    string(4) "Java"
  }
  [2]=>
  array(2) {
    ["id"]=>
    string(1) "3"
    ["label"]=>
    string(3) "C++"
  }
}

Пример #2 INSERT подготвен еднаш, извршен повеќе пати

Секој подготвен израз зафаќа ресурси на серверот. Изразите треба експлицитно да се затворат веднаш по употреба. Ако не се направи експлицитно, изразот ќе биде затворен кога рачката на изразот ќе биде ослободена од PHP. SELECT Користењето на подготвен израз не е секогаш најефикасен начин за извршување на израз. Подготвен израз извршен само еднаш предизвикува повеќе кружни патувања клиент-сервер отколку неподготвен израз. Ова е причината зошто

не се извршува како подготвен израз погоре.

Исто така, разгледајте ја употребата на MySQL multi-INSERT SQL синтаксата за INSERTs. За примерот, multi-INSERT бара помалку кружни патувања помеѓу серверот и клиентот отколку подготвениот израз прикажан погоре.

<?php

mysqli_report
(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
$mysqli = new mysqli("example.com", "user", "password", "database");

$mysqli->query("DROP TABLE IF EXISTS test");
$mysqli->query("CREATE TABLE test(id INT)");

$values = [1, 2, 3, 4];

$stmt = $mysqli->prepare("INSERT INTO test(id) VALUES (?), (?), (?), (?)");
$stmt->bind_param('iiii', ...$values);
$stmt->execute();

Пример #3 Помалку кружни патувања користејќи multi-INSERT SQL

Типови на податоци на вредностите на резултатите INT MySQL протоколот клиент-сервер дефинира различен протокол за пренос на податоци за подготвени и неподготвени изрази. Подготвените изрази користат таканаречен бинарен протокол. MySQL серверот ги испраќа податоците од резултатот „какви што се“ во бинарен формат. Резултатите не се серијализираат во низи пред испраќање. Клиентските библиотеки примаат бинарни податоци и се обидуваат да ги претворат вредностите во соодветни PHP типови на податоци. На пример, резултатите од SQL

колона ќе бидат обезбедени како PHP целобројни променливи.

<?php

mysqli_report
(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
$mysqli = new mysqli("example.com", "user", "password", "database");

/* Non-prepared statement */
$mysqli->query("DROP TABLE IF EXISTS test");
$mysqli->query("CREATE TABLE test(id INT, label TEXT)");
$mysqli->query("INSERT INTO test(id, label) VALUES (1, 'PHP')");

$stmt = $mysqli->prepare("SELECT id, label FROM test WHERE id = 1");
$stmt->execute();
$result = $stmt->get_result();
$row = $result->fetch_assoc();

printf("id = %s (%s)\n", $row['id'], gettype($row['id']));
printf("label = %s (%s)\n", $row['label'], gettype($row['label']));

Пример #1 Пример што покажува затворачка ознака што го опфаќа последниот нов ред

id = 1 (integer)
label = PHP (string)

Пример #4 Мајчин типови на податоци

Ова однесување се разликува од неподготвените изрази. Стандардно, неподготвените изрази ги враќаат сите резултати како низи. Оваа стандардна вредност може да се промени со опција за поврзување. Ако се користи опцијата за поврзување, нема разлики.

Results from prepared statements can either be retrieved by binding output variables, or by requesting a mysqli_result object.

Резултатите од подготвените изјави може да се добијат со врзување на излезни променливи или со барање на

Излезните променливи мора да бидат врзани по извршувањето на изјавата. Една променлива мора да биде врзана за секоја колона од множеството резултати на изјавата.

<?php

mysqli_report
(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
$mysqli = new mysqli("example.com", "user", "password", "database");

/* Non-prepared statement */
$mysqli->query("DROP TABLE IF EXISTS test");
$mysqli->query("CREATE TABLE test(id INT, label TEXT)");
$mysqli->query("INSERT INTO test(id, label) VALUES (1, 'PHP')");

$stmt = $mysqli->prepare("SELECT id, label FROM test WHERE id = 1");
$stmt->execute();

$stmt->bind_result($out_id, $out_label);

while (
$stmt->fetch()) {
printf("id = %s (%s), label = %s (%s)\n", $out_id, gettype($out_id), $out_label, gettype($out_label));
}

Пример #1 Пример што покажува затворачка ознака што го опфаќа последниот нов ред

id = 1 (integer), label = PHP (string)

Пример #5 Врзување на излезни променливи mysqli.

Подготвените изјави враќаат нетампонирани множества на резултати по дифолт. Резултатите од изјавата не се имплицитно преземени и пренесени од серверот до клиентот за тампонирање од страна на клиентот. Множеството резултати зафаќа ресурси на серверот додека сите резултати не бидат преземени од клиентот. Така се препорачува навремено користење на резултатите. Ако клиентот не успее да ги преземе сите резултати или клиентот ја затвори изјавата пред да ги преземе сите податоци, податоците мора имплицитно да бидат преземени од Можно е и тампонирање на резултатите од подготвена изјава користејќи.

mysqli_stmt::store_result()

Преземање резултати користејќи mysqli_result интерфејс mysqli_stmt::execute() Наместо да користите врзани резултати, резултатите може да се добијат и преку mysqli_result интерфејсот.

враќа тампонирано множество резултати.

<?php

mysqli_report
(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
$mysqli = new mysqli("example.com", "user", "password", "database");

/* Non-prepared statement */
$mysqli->query("DROP TABLE IF EXISTS test");
$mysqli->query("CREATE TABLE test(id INT, label TEXT)");
$mysqli->query("INSERT INTO test(id, label) VALUES (1, 'PHP')");

$stmt = $mysqli->prepare("SELECT id, label FROM test WHERE id = 1");
$stmt->execute();

$result = $stmt->get_result();

var_dump($result->fetch_all(MYSQLI_ASSOC));

Пример #1 Пример што покажува затворачка ознака што го опфаќа последниот нов ред

array(1) {
  [0]=>
  array(2) {
    ["id"]=>
    int(1)
    ["label"]=>
    string(3) "PHP"
  }
}

Користејќи го mysqli_result Пример #6 Користење mysqli_result за преземање резултати

интерфејсот нуди дополнителна придобивка од флексибилна навигација на множеството резултати од страна на клиентот.

<?php

mysqli_report
(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
$mysqli = new mysqli("example.com", "user", "password", "database");

/* Non-prepared statement */
$mysqli->query("DROP TABLE IF EXISTS test");
$mysqli->query("CREATE TABLE test(id INT, label TEXT)");
$mysqli->query("INSERT INTO test(id, label) VALUES (1, 'PHP'), (2, 'Java'), (3, 'C++')");

$stmt = $mysqli->prepare("SELECT id, label FROM test");
$stmt->execute();

$result = $stmt->get_result();

for (
$row_no = $result->num_rows - 1; $row_no >= 0; $row_no--) {
$result->data_seek($row_no);
var_dump($result->fetch_assoc());
}

Пример #1 Пример што покажува затворачка ознака што го опфаќа последниот нов ред

array(2) {
  ["id"]=>
  int(3)
  ["label"]=>
  string(3) "C++"
}
array(2) {
  ["id"]=>
  int(2)
  ["label"]=>
  string(4) "Java"
}
array(2) {
  ["id"]=>
  int(1)
  ["label"]=>
  string(3) "PHP"
}

Пример #7 Тампонирано множество резултати за флексибилно читање

Избегнување и SQL инјекција методот е кратенка за Наместо едноставно да се печати

Врзаните променливи се испраќаат до серверот одделно од прашањето и затоа не можат да влијаат на него. Серверот ги користи овие вредности директно во моментот на извршување, откако ќе се парсира шаблонот на изјавата. Врзаните параметри не треба да се избегнуваат бидејќи тие никогаш не се заменуваат директно во низата на прашањето. Мора да се обезбеди навестување до серверот за типот на врзаната променлива, за да се создаде соодветна конверзија. Погледнете го

Таквата одделување понекогаш се смета за единствена безбедносна карактеристика за спречување на SQL инјекција, но истиот степен на безбедност може да се постигне и со неподготвени изјави, ако сите вредности се правилно форматирани. Треба да се напомене дека правилното форматирање не е исто што и избегнувањето и вклучува повеќе логика од едноставно избегнување. Така, подготвените изјави се едноставно поудобен и помалку склон кон грешки пристап до овој елемент на безбедноста на базата на податоци.

Емулација на подготвени изјави од страна на клиентот

Види исто така

Белешки од корисници

Нема белешки од корисници за оваа страница.
На оваа страница

Автоматски outline од активната документација.

Насловите ќе се појават тука по вчитување.

Попрегледно читање

Примерите, changelog табелите и user notes се визуелно издвоени за да не се губат во долгата содржина.

Брз совет Користи го outline-от Скокни директно на главните секции од активната страница.
Извор Оригиналниот линк останува достапен Кога ти треба целосен upstream context, отвори го PHP.net во нов tab.