<?php
include_once $_SERVER['DOCUMENT_ROOT'] . '/include/shared-manual.inc';
$TOC = array();
$TOC_DEPRECATED = array();
$PARENTS = array();
include_once dirname(__FILE__) ."/toc/mysqli.quickstart.inc";
$setup = array (
  'home' => 
  array (
    0 => 'index.php',
    1 => 'PHP Manual',
  ),
  'head' => 
  array (
    0 => 'UTF-8',
    1 => 'ru',
  ),
  'this' => 
  array (
    0 => 'mysqli.quickstart.prepared-statements.php',
    1 => 'Подготавливаемые запросы',
    2 => 'Подготавливаемые запросы',
  ),
  'up' => 
  array (
    0 => 'mysqli.quickstart.php',
    1 => 'Краткое руководство',
  ),
  'prev' => 
  array (
    0 => 'mysqli.quickstart.statements.php',
    1 => 'Выполнение запросов',
  ),
  'next' => 
  array (
    0 => 'mysqli.quickstart.stored-procedures.php',
    1 => 'Хранимые процедуры',
  ),
  'alternatives' => 
  array (
  ),
  'source' => 
  array (
    'lang' => 'ru',
    'path' => 'reference/mysqli/quickstart.xml',
  ),
  'history' => 
  array (
  ),
);
$setup["toc"] = $TOC;
$setup["toc_deprecated"] = $TOC_DEPRECATED;
$setup["parents"] = $PARENTS;
manual_setup($setup);

contributors($setup);

?>
<div id="mysqli.quickstart.prepared-statements" class="section">
  <h2 class="title">Подготавливаемые запросы</h2>
  <p class="para">
   СУБД MySQL поддерживает подготавливаемые запросы. Подготавливаемые (или
   параметризованные) запросы используются для повышения эффективности, когда
   один запрос выполняется многократно и защищает от SQL-инъекций.
  </p>
  <p class="para">
   <strong>Принцип работы</strong>
  </p>
  <p class="para">
   Выполнение подготавливаемого запроса проводится в два этапа: подготовка и
   исполнение. На этапе подготовки на сервер посылается шаблон запроса. Сервер
   выполняет синтаксическую проверку этого шаблона, строит план выполнения запроса
   и выделяет под него ресурсы.
  </p>
  <p class="para">
   MySQL сервер поддерживает неименованные, или позиционные, псевдопеременные
   <code class="literal">?</code>.
  </p>
  <p class="para">
   За подготовкой следует выполнение. Во время выполнения клиент связывает значения параметров и отправляет их на сервер.
   Сервер выполняет запрос со связанными значениями, используя ранее созданные внутренние ресурсы.
  </p>
  <p class="para">
   <div class="example" id="example-1">
    <p><strong>Пример #1 Подготовленный запрос</strong></p>
    <div class="example-contents">
<div class="phpcode"><code><span style="color: #000000"><span style="color: #0000BB">&lt;?php<br /><br />mysqli_report</span><span style="color: #007700">(</span><span style="color: #0000BB">MYSQLI_REPORT_ERROR </span><span style="color: #007700">| </span><span style="color: #0000BB">MYSQLI_REPORT_STRICT</span><span style="color: #007700">);<br /></span><span style="color: #0000BB">$mysqli </span><span style="color: #007700">= new </span><span style="color: #0000BB">mysqli</span><span style="color: #007700">(</span><span style="color: #DD0000">"example.com"</span><span style="color: #007700">, </span><span style="color: #DD0000">"user"</span><span style="color: #007700">, </span><span style="color: #DD0000">"password"</span><span style="color: #007700">, </span><span style="color: #DD0000">"database"</span><span style="color: #007700">);<br /><br /></span><span style="color: #FF8000">/* Неподготовленный запрос */<br /></span><span style="color: #0000BB">$mysqli</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">query</span><span style="color: #007700">(</span><span style="color: #DD0000">"DROP TABLE IF EXISTS test"</span><span style="color: #007700">);<br /></span><span style="color: #0000BB">$mysqli</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">query</span><span style="color: #007700">(</span><span style="color: #DD0000">"CREATE TABLE test(id INT, label TEXT)"</span><span style="color: #007700">);<br /><br /></span><span style="color: #FF8000">/* Подготовленный запрос, шаг 1: подготовка */<br /></span><span style="color: #0000BB">$stmt </span><span style="color: #007700">= </span><span style="color: #0000BB">$mysqli</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">prepare</span><span style="color: #007700">(</span><span style="color: #DD0000">"INSERT INTO test(id, label) VALUES (?, ?)"</span><span style="color: #007700">);<br /><br /></span><span style="color: #FF8000">/* Подготовленный запрос, шаг 2: связывание и выполнение */<br /></span><span style="color: #0000BB">$id </span><span style="color: #007700">= </span><span style="color: #0000BB">1</span><span style="color: #007700">;<br /></span><span style="color: #0000BB">$label </span><span style="color: #007700">= </span><span style="color: #DD0000">'PHP'</span><span style="color: #007700">;<br /></span><span style="color: #0000BB">$stmt</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">bind_param</span><span style="color: #007700">(</span><span style="color: #DD0000">"is"</span><span style="color: #007700">, </span><span style="color: #0000BB">$id</span><span style="color: #007700">, </span><span style="color: #0000BB">$label</span><span style="color: #007700">); </span><span style="color: #FF8000">// "is" означает, что $id связывается, как целое число, а $label — как строка<br /><br /></span><span style="color: #0000BB">$stmt</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">execute</span><span style="color: #007700">();</span></span></code></div>
    </div>

   </div>
  </p>
  <p class="para">
   <strong>Повторное выполнение запроса</strong>
  </p>
  <p class="para">
   Подготовленный запрос можно запускать многократно. Перед каждым запуском
   значения привязанных переменных будут передаваться на сервер и подставляться
   в текст запроса. Сам текст запроса повторно не анализируется, равно как и не
   отсылается повторно шаблон.
  </p>
  <p class="para">
   <div class="example" id="example-2">
    <p><strong>Пример #2 Выражение INSERT один раз подготавливается, а затем многократно выполняется</strong></p>
    <div class="example-contents">
<div class="phpcode"><code><span style="color: #000000"><span style="color: #0000BB">&lt;?php<br /><br />mysqli_report</span><span style="color: #007700">(</span><span style="color: #0000BB">MYSQLI_REPORT_ERROR </span><span style="color: #007700">| </span><span style="color: #0000BB">MYSQLI_REPORT_STRICT</span><span style="color: #007700">);<br /></span><span style="color: #0000BB">$mysqli </span><span style="color: #007700">= new </span><span style="color: #0000BB">mysqli</span><span style="color: #007700">(</span><span style="color: #DD0000">"example.com"</span><span style="color: #007700">, </span><span style="color: #DD0000">"user"</span><span style="color: #007700">, </span><span style="color: #DD0000">"password"</span><span style="color: #007700">, </span><span style="color: #DD0000">"database"</span><span style="color: #007700">);<br /><br /></span><span style="color: #FF8000">/* Неподготовленный запрос */<br /></span><span style="color: #0000BB">$mysqli</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">query</span><span style="color: #007700">(</span><span style="color: #DD0000">"DROP TABLE IF EXISTS test"</span><span style="color: #007700">);<br /></span><span style="color: #0000BB">$mysqli</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">query</span><span style="color: #007700">(</span><span style="color: #DD0000">"CREATE TABLE test(id INT, label TEXT)"</span><span style="color: #007700">);<br /><br /></span><span style="color: #FF8000">/* Подготовленный запрос, шаг 1: подготовка */<br /></span><span style="color: #0000BB">$stmt </span><span style="color: #007700">= </span><span style="color: #0000BB">$mysqli</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">prepare</span><span style="color: #007700">(</span><span style="color: #DD0000">"INSERT INTO test(id, label) VALUES (?, ?)"</span><span style="color: #007700">);<br /><br /></span><span style="color: #FF8000">/* Подготовленный запрос, шаг 2: связывание и выполнение */<br /></span><span style="color: #0000BB">$stmt</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">bind_param</span><span style="color: #007700">(</span><span style="color: #DD0000">"is"</span><span style="color: #007700">, </span><span style="color: #0000BB">$id</span><span style="color: #007700">, </span><span style="color: #0000BB">$label</span><span style="color: #007700">); </span><span style="color: #FF8000">// "is" означает, что $id связывается, как целое число, а $label — как строка<br /><br /></span><span style="color: #0000BB">$data </span><span style="color: #007700">= [<br />    </span><span style="color: #0000BB">1 </span><span style="color: #007700">=&gt; </span><span style="color: #DD0000">'PHP'</span><span style="color: #007700">,<br />    </span><span style="color: #0000BB">2 </span><span style="color: #007700">=&gt; </span><span style="color: #DD0000">'Java'</span><span style="color: #007700">,<br />    </span><span style="color: #0000BB">3 </span><span style="color: #007700">=&gt; </span><span style="color: #DD0000">'C++'<br /></span><span style="color: #007700">];<br />foreach (</span><span style="color: #0000BB">$data </span><span style="color: #007700">as </span><span style="color: #0000BB">$id </span><span style="color: #007700">=&gt; </span><span style="color: #0000BB">$label</span><span style="color: #007700">) {<br />    </span><span style="color: #0000BB">$stmt</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">execute</span><span style="color: #007700">();<br />}<br /><br /></span><span style="color: #0000BB">$result </span><span style="color: #007700">= </span><span style="color: #0000BB">$mysqli</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">query</span><span style="color: #007700">(</span><span style="color: #DD0000">'SELECT id, label FROM test'</span><span style="color: #007700">);<br /></span><span style="color: #0000BB">var_dump</span><span style="color: #007700">(</span><span style="color: #0000BB">$result</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">fetch_all</span><span style="color: #007700">(</span><span style="color: #0000BB">MYSQLI_ASSOC</span><span style="color: #007700">));</span></span></code></div>
    </div>

    
<div class="example-contents"><p>
 Результат выполнения приведённого примера:
</p></div>

    <div class="example-contents screen">
<div class="cdata"><pre>
array(3) {
  [0]=&gt;
  array(2) {
    [&quot;id&quot;]=&gt;
    string(1) &quot;1&quot;
    [&quot;label&quot;]=&gt;
    string(3) &quot;PHP&quot;
  }
  [1]=&gt;
  array(2) {
    [&quot;id&quot;]=&gt;
    string(1) &quot;2&quot;
    [&quot;label&quot;]=&gt;
    string(4) &quot;Java&quot;
  }
  [2]=&gt;
  array(2) {
    [&quot;id&quot;]=&gt;
    string(1) &quot;3&quot;
    [&quot;label&quot;]=&gt;
    string(3) &quot;C++&quot;
  }
}
</pre></div>
    </div>
   </div>
  </p>
  <p class="para">
   Каждый подготавливаемый запрос использует ресурсы сервера. Если запрос больше
   не нужен, его необходимо сразу закрыть. Если не сделать этого явно, запрос
   закроется сам, но только когда PHP освободит его дескриптор, как правило это
   происходит при выходе запроса из области видимости или при завершении работы
   скрипта.
  </p>
  <p class="para">
   Использование подготавливаемых запросов не всегда приводит к повышению
   эффективности. Если параметризованный запрос запускается лишь раз, это приводит
   к большему количеству клиент-серверных обменов данными, нежели при выполнении
   простого запроса. Именно по этой причине в примере выше выражение
   <code class="literal">SELECT</code> выполнялось, как обычный запрос.
  </p>
  <p class="para">
   Также имеет смысл рассмотреть SQL-синтаксис вставки множества значений в
   выражении INSERT. В примере выше мультивставка (значения для вставки
   перечисляются через запятую) в предложении INSERT обошлась бы дешевле,
   чем подготовленный запрос.
  </p>
  <p class="para">
   <div class="example" id="example-3">
    <p><strong>Пример #3 Меньше обменов данными при использовании мультивставок SQL</strong></p>
    <div class="example-contents">
<div class="phpcode"><code><span style="color: #000000"><span style="color: #0000BB">&lt;?php<br /><br />mysqli_report</span><span style="color: #007700">(</span><span style="color: #0000BB">MYSQLI_REPORT_ERROR </span><span style="color: #007700">| </span><span style="color: #0000BB">MYSQLI_REPORT_STRICT</span><span style="color: #007700">);<br /></span><span style="color: #0000BB">$mysqli </span><span style="color: #007700">= new </span><span style="color: #0000BB">mysqli</span><span style="color: #007700">(</span><span style="color: #DD0000">"example.com"</span><span style="color: #007700">, </span><span style="color: #DD0000">"user"</span><span style="color: #007700">, </span><span style="color: #DD0000">"password"</span><span style="color: #007700">, </span><span style="color: #DD0000">"database"</span><span style="color: #007700">);<br /><br /></span><span style="color: #0000BB">$mysqli</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">query</span><span style="color: #007700">(</span><span style="color: #DD0000">"DROP TABLE IF EXISTS test"</span><span style="color: #007700">);<br /></span><span style="color: #0000BB">$mysqli</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">query</span><span style="color: #007700">(</span><span style="color: #DD0000">"CREATE TABLE test(id INT)"</span><span style="color: #007700">);<br /><br /></span><span style="color: #0000BB">$values </span><span style="color: #007700">= [</span><span style="color: #0000BB">1</span><span style="color: #007700">, </span><span style="color: #0000BB">2</span><span style="color: #007700">, </span><span style="color: #0000BB">3</span><span style="color: #007700">, </span><span style="color: #0000BB">4</span><span style="color: #007700">];<br /><br /></span><span style="color: #0000BB">$stmt </span><span style="color: #007700">= </span><span style="color: #0000BB">$mysqli</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">prepare</span><span style="color: #007700">(</span><span style="color: #DD0000">"INSERT INTO test(id) VALUES (?), (?), (?), (?)"</span><span style="color: #007700">);<br /></span><span style="color: #0000BB">$stmt</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">bind_param</span><span style="color: #007700">(</span><span style="color: #DD0000">'iiii'</span><span style="color: #007700">, ...</span><span style="color: #0000BB">$values</span><span style="color: #007700">);<br /></span><span style="color: #0000BB">$stmt</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">execute</span><span style="color: #007700">();</span></span></code></div>
    </div>

   </div>
  </p>
  <p class="para">
   <strong>Типы данных значений в результирующей таблице</strong>
  </p>
  <p class="para">
   В протоколе клиент-серверного взаимодействия MySQL для обычных и
   подготавливаемых запросов определены разные протоколы передачи данных клиенту.
   Параметризованные запросы используют так называемый двоичный протокол. Сервер
   MySQL посылает результирующий набор клиенту «как есть» в двоичном формате.
   Данные в таблице не преобразовываются в текст. Клиентские библиотеки получают двоичные данные и пытаются преобразовать значения в
   соответствующие типы данных PHP.
   Например, столбец результатов запроса типа SQL <code class="literal">INT</code> PHP примет
   и преобразует в тип integer.
  </p>
  <p class="para">
   <div class="example" id="example-4">
    <p><strong>Пример #4 Исходные типы данных</strong></p>
    <div class="example-contents">
<div class="phpcode"><code><span style="color: #000000"><span style="color: #0000BB">&lt;?php<br /><br />mysqli_report</span><span style="color: #007700">(</span><span style="color: #0000BB">MYSQLI_REPORT_ERROR </span><span style="color: #007700">| </span><span style="color: #0000BB">MYSQLI_REPORT_STRICT</span><span style="color: #007700">);<br /></span><span style="color: #0000BB">$mysqli </span><span style="color: #007700">= new </span><span style="color: #0000BB">mysqli</span><span style="color: #007700">(</span><span style="color: #DD0000">"example.com"</span><span style="color: #007700">, </span><span style="color: #DD0000">"user"</span><span style="color: #007700">, </span><span style="color: #DD0000">"password"</span><span style="color: #007700">, </span><span style="color: #DD0000">"database"</span><span style="color: #007700">);<br /><br /></span><span style="color: #FF8000">/* Неподготовленный запрос */<br /></span><span style="color: #0000BB">$mysqli</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">query</span><span style="color: #007700">(</span><span style="color: #DD0000">"DROP TABLE IF EXISTS test"</span><span style="color: #007700">);<br /></span><span style="color: #0000BB">$mysqli</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">query</span><span style="color: #007700">(</span><span style="color: #DD0000">"CREATE TABLE test(id INT, label TEXT)"</span><span style="color: #007700">);<br /></span><span style="color: #0000BB">$mysqli</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">query</span><span style="color: #007700">(</span><span style="color: #DD0000">"INSERT INTO test(id, label) VALUES (1, 'PHP')"</span><span style="color: #007700">);<br /><br /></span><span style="color: #0000BB">$stmt </span><span style="color: #007700">= </span><span style="color: #0000BB">$mysqli</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">prepare</span><span style="color: #007700">(</span><span style="color: #DD0000">"SELECT id, label FROM test WHERE id = 1"</span><span style="color: #007700">);<br /></span><span style="color: #0000BB">$stmt</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">execute</span><span style="color: #007700">();<br /></span><span style="color: #0000BB">$result </span><span style="color: #007700">= </span><span style="color: #0000BB">$stmt</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">get_result</span><span style="color: #007700">();<br /></span><span style="color: #0000BB">$row </span><span style="color: #007700">= </span><span style="color: #0000BB">$result</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">fetch_assoc</span><span style="color: #007700">();<br /><br /></span><span style="color: #0000BB">printf</span><span style="color: #007700">(</span><span style="color: #DD0000">"id = %s (%s)\n"</span><span style="color: #007700">, </span><span style="color: #0000BB">$row</span><span style="color: #007700">[</span><span style="color: #DD0000">'id'</span><span style="color: #007700">], </span><span style="color: #0000BB">gettype</span><span style="color: #007700">(</span><span style="color: #0000BB">$row</span><span style="color: #007700">[</span><span style="color: #DD0000">'id'</span><span style="color: #007700">]));<br /></span><span style="color: #0000BB">printf</span><span style="color: #007700">(</span><span style="color: #DD0000">"label = %s (%s)\n"</span><span style="color: #007700">, </span><span style="color: #0000BB">$row</span><span style="color: #007700">[</span><span style="color: #DD0000">'label'</span><span style="color: #007700">], </span><span style="color: #0000BB">gettype</span><span style="color: #007700">(</span><span style="color: #0000BB">$row</span><span style="color: #007700">[</span><span style="color: #DD0000">'label'</span><span style="color: #007700">]));</span></span></code></div>
    </div>

    
<div class="example-contents"><p>
 Результат выполнения приведённого примера:
</p></div>

    <div class="example-contents screen">
<div class="cdata"><pre>
id = 1 (integer)
label = PHP (string)
</pre></div>
    </div>
   </div>
  </p>
  <p class="para">
   Такое поведение не характерно для обычных запросов, которые по умолчанию
   все результаты возвращают в виде текстовых строк. Это поведение по умолчанию можно изменить,
   настроив соединение соответствующим образом. После такой настройки разницы
   между данными подготавливаемого и обычного запросов уже не будет.
  </p>
  <p class="para">
   <strong>Получение результатов запроса с привязкой переменных</strong>
  </p>
  <p class="para">
   Результаты из подготовленного запроса можно получить либо привязав выходные
   переменные, либо запросив объект <span class="classname"><a href="class.mysqli-result.php" class="classname">mysqli_result</a></span>.
  </p>
  <p class="para">
   Выходные параметры нужно привязывать после выполнения запроса. Каждому столбцу
   результирующей таблицы должна соответствовать ровно одна переменная.
  </p>
  <p class="para">
   <div class="example" id="example-5">
    <p><strong>Пример #5 Привязка переменных к результату запроса</strong></p>
    <div class="example-contents">
<div class="phpcode"><code><span style="color: #000000"><span style="color: #0000BB">&lt;?php<br /><br />mysqli_report</span><span style="color: #007700">(</span><span style="color: #0000BB">MYSQLI_REPORT_ERROR </span><span style="color: #007700">| </span><span style="color: #0000BB">MYSQLI_REPORT_STRICT</span><span style="color: #007700">);<br /></span><span style="color: #0000BB">$mysqli </span><span style="color: #007700">= new </span><span style="color: #0000BB">mysqli</span><span style="color: #007700">(</span><span style="color: #DD0000">"example.com"</span><span style="color: #007700">, </span><span style="color: #DD0000">"user"</span><span style="color: #007700">, </span><span style="color: #DD0000">"password"</span><span style="color: #007700">, </span><span style="color: #DD0000">"database"</span><span style="color: #007700">);<br /><br /></span><span style="color: #FF8000">/* Неподготовленный запрос */<br /></span><span style="color: #0000BB">$mysqli</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">query</span><span style="color: #007700">(</span><span style="color: #DD0000">"DROP TABLE IF EXISTS test"</span><span style="color: #007700">);<br /></span><span style="color: #0000BB">$mysqli</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">query</span><span style="color: #007700">(</span><span style="color: #DD0000">"CREATE TABLE test(id INT, label TEXT)"</span><span style="color: #007700">);<br /></span><span style="color: #0000BB">$mysqli</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">query</span><span style="color: #007700">(</span><span style="color: #DD0000">"INSERT INTO test(id, label) VALUES (1, 'PHP')"</span><span style="color: #007700">);<br /><br /></span><span style="color: #0000BB">$stmt </span><span style="color: #007700">= </span><span style="color: #0000BB">$mysqli</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">prepare</span><span style="color: #007700">(</span><span style="color: #DD0000">"SELECT id, label FROM test WHERE id = 1"</span><span style="color: #007700">);<br /></span><span style="color: #0000BB">$stmt</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">execute</span><span style="color: #007700">();<br /><br /></span><span style="color: #0000BB">$stmt</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">bind_result</span><span style="color: #007700">(</span><span style="color: #0000BB">$out_id</span><span style="color: #007700">, </span><span style="color: #0000BB">$out_label</span><span style="color: #007700">);<br /><br />while (</span><span style="color: #0000BB">$stmt</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">fetch</span><span style="color: #007700">()) {<br />    </span><span style="color: #0000BB">printf</span><span style="color: #007700">(</span><span style="color: #DD0000">"id = %s (%s), label = %s (%s)\n"</span><span style="color: #007700">, </span><span style="color: #0000BB">$out_id</span><span style="color: #007700">, </span><span style="color: #0000BB">gettype</span><span style="color: #007700">(</span><span style="color: #0000BB">$out_id</span><span style="color: #007700">), </span><span style="color: #0000BB">$out_label</span><span style="color: #007700">, </span><span style="color: #0000BB">gettype</span><span style="color: #007700">(</span><span style="color: #0000BB">$out_label</span><span style="color: #007700">));<br />}</span></span></code></div>
    </div>

    
<div class="example-contents"><p>
 Результат выполнения приведённого примера:
</p></div>

    <div class="example-contents screen">
<div class="cdata"><pre>
id = 1 (integer), label = PHP (string)
</pre></div>
    </div>
   </div>
  </p>
  <p class="para">
   Объекты подготавливаемых запросов по умолчанию возвращают небуферизованные
   результирующие наборы. Эти таблицы никаким неявным образом не переносятся
   на клиента, они остаются на сервере, занимая его ресурсы, пока клиентский
   процесс самостоятельно не извлечёт все данные. Если клиент не может извлечь
   данные результирующего набора, или после закрытия объекта запроса остаются
   невыбранными какие-то данные, то на <code class="literal">mysqli</code> ложится
   ответственность неявно подчистить этот мусор за клиентским процессом.
  </p>
  <p class="para">
   Также можно буферизовать данные результирующих таблиц подготовленного запроса
   с помощью функции <span class="methodname"><a href="mysqli-stmt.store-result.php" class="methodname">mysqli_stmt::store_result()</a></span>.
  </p>
  <p class="para">
   <strong>
    Извлечение результатов запроса посредством mysqli_result интерфейса
   </strong>
  </p>
  <p class="para">
   Вместо использования привязки переменных к результатам запроса, результирующие
   таблицы можно извлекать средствами интерфейса mysqli_result. Функция
   <span class="methodname"><a href="mysqli-stmt.get-result.php" class="methodname">mysqli_stmt::get_result()</a></span> возвращает буферизованный
   результирующий набор строк.
  </p>
  <p class="para">
   <div class="example" id="example-6">
    <p><strong>Пример #6 Использование mysqli_result для выборки результатов запроса</strong></p>
    <div class="example-contents">
<div class="phpcode"><code><span style="color: #000000"><span style="color: #0000BB">&lt;?php<br /><br />mysqli_report</span><span style="color: #007700">(</span><span style="color: #0000BB">MYSQLI_REPORT_ERROR </span><span style="color: #007700">| </span><span style="color: #0000BB">MYSQLI_REPORT_STRICT</span><span style="color: #007700">);<br /></span><span style="color: #0000BB">$mysqli </span><span style="color: #007700">= new </span><span style="color: #0000BB">mysqli</span><span style="color: #007700">(</span><span style="color: #DD0000">"example.com"</span><span style="color: #007700">, </span><span style="color: #DD0000">"user"</span><span style="color: #007700">, </span><span style="color: #DD0000">"password"</span><span style="color: #007700">, </span><span style="color: #DD0000">"database"</span><span style="color: #007700">);<br /><br /></span><span style="color: #FF8000">/* Неподготовленный запрос */<br /></span><span style="color: #0000BB">$mysqli</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">query</span><span style="color: #007700">(</span><span style="color: #DD0000">"DROP TABLE IF EXISTS test"</span><span style="color: #007700">);<br /></span><span style="color: #0000BB">$mysqli</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">query</span><span style="color: #007700">(</span><span style="color: #DD0000">"CREATE TABLE test(id INT, label TEXT)"</span><span style="color: #007700">);<br /></span><span style="color: #0000BB">$mysqli</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">query</span><span style="color: #007700">(</span><span style="color: #DD0000">"INSERT INTO test(id, label) VALUES (1, 'PHP')"</span><span style="color: #007700">);<br /><br /></span><span style="color: #0000BB">$stmt </span><span style="color: #007700">= </span><span style="color: #0000BB">$mysqli</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">prepare</span><span style="color: #007700">(</span><span style="color: #DD0000">"SELECT id, label FROM test WHERE id = 1"</span><span style="color: #007700">);<br /></span><span style="color: #0000BB">$stmt</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">execute</span><span style="color: #007700">();<br /><br /></span><span style="color: #0000BB">$result </span><span style="color: #007700">= </span><span style="color: #0000BB">$stmt</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">get_result</span><span style="color: #007700">();<br /><br /></span><span style="color: #0000BB">var_dump</span><span style="color: #007700">(</span><span style="color: #0000BB">$result</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">fetch_all</span><span style="color: #007700">(</span><span style="color: #0000BB">MYSQLI_ASSOC</span><span style="color: #007700">));</span></span></code></div>
    </div>

    
<div class="example-contents"><p>
 Результат выполнения приведённого примера:
</p></div>

    <div class="example-contents screen">
<div class="cdata"><pre>
array(1) {
  [0]=&gt;
  array(2) {
    [&quot;id&quot;]=&gt;
    int(1)
    [&quot;label&quot;]=&gt;
    string(3) &quot;PHP&quot;
  }
}
</pre></div>
    </div>
   </div>
  </p>
  <p class="para">
   Использование интерфейса <span class="classname"><a href="class.mysqli-result.php" class="classname">mysqli_result</a></span> имеет
   дополнительное преимущество в том, что буферизация результирующих таблиц на
   клиенте предлагает гибкую систему навигации по этим таблицам.
  </p>
  <p class="para">
   <div class="example" id="example-7">
    <p><strong>Пример #7 Буферизация результирующего набора для удобства чтения данных</strong></p>
    <div class="example-contents">
<div class="phpcode"><code><span style="color: #000000"><span style="color: #0000BB">&lt;?php<br /><br />mysqli_report</span><span style="color: #007700">(</span><span style="color: #0000BB">MYSQLI_REPORT_ERROR </span><span style="color: #007700">| </span><span style="color: #0000BB">MYSQLI_REPORT_STRICT</span><span style="color: #007700">);<br /></span><span style="color: #0000BB">$mysqli </span><span style="color: #007700">= new </span><span style="color: #0000BB">mysqli</span><span style="color: #007700">(</span><span style="color: #DD0000">"example.com"</span><span style="color: #007700">, </span><span style="color: #DD0000">"user"</span><span style="color: #007700">, </span><span style="color: #DD0000">"password"</span><span style="color: #007700">, </span><span style="color: #DD0000">"database"</span><span style="color: #007700">);<br /><br /></span><span style="color: #FF8000">/* Неподготовленный запрос */<br /></span><span style="color: #0000BB">$mysqli</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">query</span><span style="color: #007700">(</span><span style="color: #DD0000">"DROP TABLE IF EXISTS test"</span><span style="color: #007700">);<br /></span><span style="color: #0000BB">$mysqli</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">query</span><span style="color: #007700">(</span><span style="color: #DD0000">"CREATE TABLE test(id INT, label TEXT)"</span><span style="color: #007700">);<br /></span><span style="color: #0000BB">$mysqli</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">query</span><span style="color: #007700">(</span><span style="color: #DD0000">"INSERT INTO test(id, label) VALUES (1, 'PHP'), (2, 'Java'), (3, 'C++')"</span><span style="color: #007700">);<br /><br /></span><span style="color: #0000BB">$stmt </span><span style="color: #007700">= </span><span style="color: #0000BB">$mysqli</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">prepare</span><span style="color: #007700">(</span><span style="color: #DD0000">"SELECT id, label FROM test"</span><span style="color: #007700">);<br /></span><span style="color: #0000BB">$stmt</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">execute</span><span style="color: #007700">();<br /><br /></span><span style="color: #0000BB">$result </span><span style="color: #007700">= </span><span style="color: #0000BB">$stmt</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">get_result</span><span style="color: #007700">();<br /><br />for (</span><span style="color: #0000BB">$row_no </span><span style="color: #007700">= </span><span style="color: #0000BB">$result</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">num_rows </span><span style="color: #007700">- </span><span style="color: #0000BB">1</span><span style="color: #007700">; </span><span style="color: #0000BB">$row_no </span><span style="color: #007700">&gt;= </span><span style="color: #0000BB">0</span><span style="color: #007700">; </span><span style="color: #0000BB">$row_no</span><span style="color: #007700">--) {<br />    </span><span style="color: #0000BB">$result</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">data_seek</span><span style="color: #007700">(</span><span style="color: #0000BB">$row_no</span><span style="color: #007700">);<br />    </span><span style="color: #0000BB">var_dump</span><span style="color: #007700">(</span><span style="color: #0000BB">$result</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">fetch_assoc</span><span style="color: #007700">());<br />}</span></span></code></div>
    </div>

    
<div class="example-contents"><p>
 Результат выполнения приведённого примера:
</p></div>

    <div class="example-contents screen">
<div class="cdata"><pre>
array(2) {
  [&quot;id&quot;]=&gt;
  int(3)
  [&quot;label&quot;]=&gt;
  string(3) &quot;C++&quot;
}
array(2) {
  [&quot;id&quot;]=&gt;
  int(2)
  [&quot;label&quot;]=&gt;
  string(4) &quot;Java&quot;
}
array(2) {
  [&quot;id&quot;]=&gt;
  int(1)
  [&quot;label&quot;]=&gt;
  string(3) &quot;PHP&quot;
}
</pre></div>
    </div>
   </div>
  </p>
  <p class="para">
   <strong>Экранирование и SQL-инъекции</strong>
  </p>
  <p class="para">
   Привязанные переменные отправляются на сервер отдельно от запроса и таким
   образом не могут влиять на него. Сервер использует эти значения непосредственно в
   момент выполнения, уже после того, как был обработан шаблон выражения.
   Привязанные параметры не нуждаются в экранировании, так как они никогда не подставляются
   непосредственно в строку запроса. Необходимо отправлять тип привязанной переменной на сервер,
   чтобы определить соответствующее преобразование. Смотрите функцию
   <span class="methodname"><a href="mysqli-stmt.bind-param.php" class="methodname">mysqli_stmt::bind_param()</a></span> для получения большей информации.
  </p>
  <p class="para">
   Такое разделение часто считается единственным способом обезопаситься от
   SQL-инъекции, но на самом деле такого же уровня безопасности можно добиться
   и с неподготовленными выражениями, если правильно отформатировать все значения.
   Важно отметить, что правильное форматирование — не то же самое, что и экранирование,
   и включает в себя больше логики. Таким образом, подготовленные выражения -
   просто более удобный и менее подверженный ошибкам способ для достижения
   такой безопасности базы данных.
  </p>
  <p class="para">
   <strong>Эмуляция подготовленного запроса на клиенте</strong>
  </p>
  <p class="para">
   В API нет возможности эмулировать подготавливаемые запросы на клиенте.
  </p>
  <p class="para">
   <strong>Смотрите также</strong>
  </p>
  <p class="para">
   <ul class="simplelist">
    <li><span class="methodname"><a href="mysqli.construct.php" class="methodname">mysqli::__construct()</a></span></li>
    <li><span class="methodname"><a href="mysqli.query.php" class="methodname">mysqli::query()</a></span></li>
    <li><span class="methodname"><a href="mysqli.prepare.php" class="methodname">mysqli::prepare()</a></span></li>
    <li><span class="methodname"><a href="mysqli-stmt.prepare.php" class="methodname">mysqli_stmt::prepare()</a></span></li>
    <li><span class="methodname"><a href="mysqli-stmt.execute.php" class="methodname">mysqli_stmt::execute()</a></span></li>
    <li><span class="methodname"><a href="mysqli-stmt.bind-param.php" class="methodname">mysqli_stmt::bind_param()</a></span></li>
    <li><span class="methodname"><a href="mysqli-stmt.bind-result.php" class="methodname">mysqli_stmt::bind_result()</a></span></li>
   </ul>
  </p>
 </div><?php manual_footer($setup); ?>