<?php
include_once $_SERVER['DOCUMENT_ROOT'] . '/include/shared-manual.inc';
$TOC = array();
$TOC_DEPRECATED = array();
$PARENTS = array();
include_once dirname(__FILE__) ."/toc/mongodb.architecture.inc";
$setup = array (
  'home' => 
  array (
    0 => 'index.php',
    1 => 'PHP Manual',
  ),
  'head' => 
  array (
    0 => 'UTF-8',
    1 => 'ru',
  ),
  'this' => 
  array (
    0 => 'mongodb.persistence.php',
    1 => 'Сохранение данных',
    2 => 'Сериализация и десериализация PHP-переменных в модуле MongoDB',
  ),
  'up' => 
  array (
    0 => 'mongodb.architecture.php',
    1 => 'Архитектура и внутреннее устройство драйвера',
  ),
  'prev' => 
  array (
    0 => 'mongodb.connection-handling.php',
    1 => 'Соединения',
  ),
  'next' => 
  array (
    0 => 'mongodb.security.php',
    1 => 'Безопасность',
  ),
  'alternatives' => 
  array (
  ),
  'source' => 
  array (
    'lang' => 'ru',
    'path' => 'reference/mongodb/architecture.xml',
  ),
  'history' => 
  array (
  ),
);
$setup["toc"] = $TOC;
$setup["toc_deprecated"] = $TOC_DEPRECATED;
$setup["parents"] = $PARENTS;
manual_setup($setup);

contributors($setup);

?>
<div id="mongodb.persistence" class="section">
  
  <h2 class="title">Сериализация и десериализация PHP-переменных в модуле MongoDB</h2>

  <p class="para">
   В документе обсуждается, как составные структуры наподобие документов, массивов
   и объектов преобразовываются между значениями формата BSON и PHP-значениями.
  </p>

  <div class="section" id="mongodb.persistence.serialization">
   <h2 class="title">Сериализация в BSON</h2>

   <div class="section">
    <h2 class="title">Массивы</h2>

    <p class="para">
     Если массив представляет собой <em>упакованный массив</em> —
     то есть пустой массив или ключи начинаются
     с 0 и идут последовательно без пробелов: <em>BSON-массив</em>.
    </p>

    <p class="para">
     Если массив не упакован — то есть содержит ассоциативные (строковые) ключи,
     ключи не начинаются с 0 или содержат пробелы: <em>BSON-объект</em>
    </p>

    <p class="para">
     Документ верхнего уровня (корневой) <em>всегда</em> сериализуется
     как BSON-документ.
    </p>

    <div class="section">
     <h2 class="title">Примеры</h2>

     <p class="para">
      Эти PHP-массивы сериализуются как BSON-массив:
     </p>

     <div class="example-contents">
<div class="textcode"><pre class="textcode">[8, 5, 2, 3] =&gt; [8, 5, 2, 3]
[0 =&gt; 4, 1 =&gt; 9] =&gt; [4, 9]</pre>
</div>
     </div>


     <p class="para">
      Эти PHP-массивы сериализуются как BSON-документ:
     </p>

     <div class="example-contents">
<div class="textcode"><pre class="textcode">[0 =&gt; 1, 2 =&gt; 8, 3 =&gt; 12] =&gt; {&quot;0&quot;: 1, &quot;2&quot;: 8, &quot;3&quot;: 12}
[&quot;foo&quot; =&gt; 42] =&gt; {&quot;foo&quot;: 42}
[1 =&gt; 9, 0 =&gt; 10] =&gt; {&quot;1&quot;: 9, &quot;0&quot;: 10}</pre>
</div>
     </div>


     <p class="para">
      Обратите внимание, что пять приведённых примеров — <em>выдержки</em> из полного
      документа и представляют только <em>одно</em> значение внутри
      документа.
     </p>

    </div>
   </div>

   <div class="section">
    <h2 class="title">Объекты</h2>

     <p class="para">
      Если объект принадлежит типу <span class="classname"><a href="class.stdclass.php" class="classname">stdClass</a></span>, он сериализуется
      как <em>BSON-документ</em>.
     </p>

     <p class="para">
      Если объект — поддерживаемый класс, который реализует
      интерфейс <span class="interfacename"><a href="class.mongodb-bson-type.php" class="interfacename">MongoDB\BSON\Type</a></span>, используется
      логика сериализации BSON для этого конкретного типа.
      Экземпляры с типом <span class="interfacename"><a href="class.mongodb-bson-type.php" class="interfacename">MongoDB\BSON\Type</a></span> (исключая
      тип <span class="interfacename"><a href="class.mongodb-bson-serializable.php" class="interfacename">MongoDB\BSON\Serializable</a></span>) можно
      сериализовать только как значение поля документа. Попытка сериализовать такой объект
      как корневой документ выбросит исключение
      <span class="classname"><a href="class.mongodb-driver-exception-unexpectedvalueexception.php" class="classname">MongoDB\Driver\Exception\UnexpectedValueException</a></span>.
     </p>

     <p class="para">
      Если объект принадлежит неизвестному классу, который реализует интерфейс
      <span class="interfacename"><a href="class.mongodb-bson-type.php" class="interfacename">MongoDB\BSON\Type</a></span>, выбрасывается исключение
      <span class="classname"><a href="class.mongodb-driver-exception-unexpectedvalueexception.php" class="classname">MongoDB\Driver\Exception\UnexpectedValueException</a></span>.
     </p>

     <p class="para">
      Если объект принадлежит какому-либо другому классу без реализации какого-либо специального
      интерфейса, он сериализуется как <em>BSON-документ</em>. Остаются только
      открытые (<em>public</em>) свойства, а защищённые (<em>protected</em>)
      и закрытые (<em>private</em>) свойства игнорируются.
     </p>

     <p class="para">
      Если объект принадлежит к классу, который реализует интерфейс
      <span class="interfacename"><a href="class.mongodb-bson-serializable.php" class="interfacename">MongoDB\BSON\Serializable</a></span>, вызывают
      метод <span class="methodname"><a href="mongodb-bson-serializable.bsonserialize.php" class="methodname">MongoDB\BSON\Serializable::bsonSerialize()</a></span>
      и сериализуют массив или <span class="classname"><a href="class.stdclass.php" class="classname">stdClass</a></span>, которые возвращает метод,
      как BSON-документ или как BSON-массив. Тип BSON определят следующие условия:
     </p>

     <p class="para">
      <ol type="1">
       <li class="listitem">
        <p class="para">Корневые документы требуется сериализовать
         как BSON-документ.
        </p>
       </li>
       <li class="listitem">
        <p class="para">
         Объекты с типом <span class="interfacename"><a href="class.mongodb-bson-persistable.php" class="interfacename">MongoDB\BSON\Persistable</a></span> требуется
         сериализовать как BSON-документы.
        </p>
       </li>
       <li class="listitem">
        <p class="para">
         Если метод <span class="methodname"><a href="mongodb-bson-serializable.bsonserialize.php" class="methodname">MongoDB\BSON\Serializable::bsonSerialize()</a></span>
         возвращает упакованный массив, его сериализуют как BSON-массив.
        </p>
       </li>
       <li class="listitem">
        <p class="para">
         Если метод <span class="methodname"><a href="mongodb-bson-serializable.bsonserialize.php" class="methodname">MongoDB\BSON\Serializable::bsonSerialize()</a></span>
         возвращает неупакованный массив или объект <span class="classname"><a href="class.stdclass.php" class="classname">stdClass</a></span>,
         его сериализуют как BSON-документ.
        </p>
       </li>
       <li class="listitem">
        <p class="para">
         Если метод <span class="methodname"><a href="mongodb-bson-serializable.bsonserialize.php" class="methodname">MongoDB\BSON\Serializable::bsonSerialize()</a></span>
         не вернул массив или объект <span class="classname"><a href="class.stdclass.php" class="classname">stdClass</a></span>, выбрасывается исключение
         <span class="classname"><a href="class.mongodb-driver-exception-unexpectedvalueexception.php" class="classname">MongoDB\Driver\Exception\UnexpectedValueException</a></span>.
        </p>
       </li>
      </ol>
     </p>

     <p class="para">
      Если объект принадлежит классу, который реализует интерфейс
      <span class="interfacename"><a href="class.mongodb-bson-persistable.php" class="interfacename">MongoDB\BSON\Persistable</a></span> (что
      подразумевает реализацию метода <span class="interfacename"><a href="class.mongodb-bson-serializable.php" class="interfacename">MongoDB\BSON\Serializable</a></span>),
      свойства остаются по аналогии с предыдущими абзацами,
      но <em>также</em> добавляется дополнительное свойство
      <span class="property">__pclass</span> в виде Binary-значения с подтипом
      <code class="literal">0x80</code> и данными, которые содержат полное имя класса объекта,
      который сериализуется.
     </p>

     <p class="para">
      Свойство <span class="property">__pclass</span> добавляется в массив или
      объект, который возвращает метод
      <span class="methodname"><a href="mongodb-bson-serializable.bsonserialize.php" class="methodname">MongoDB\BSON\Serializable::bsonSerialize()</a></span>,
      что означает, что оно перезапишет любой ключ или свойство <span class="property">__pclass</span>
      в значении, которое возвращает метод <span class="methodname"><a href="mongodb-bson-serializable.bsonserialize.php" class="methodname">MongoDB\BSON\Serializable::bsonSerialize()</a></span>.
      Если требуется избежать такого поведения и установить собственное значение
      <span class="property">__pclass</span>, <em>вместо</em>
      реализации интерфейса <span class="interfacename"><a href="class.mongodb-bson-persistable.php" class="interfacename">MongoDB\BSON\Persistable</a></span>
      следует напрямую реализовать интерфейс
      <span class="interfacename"><a href="class.mongodb-bson-serializable.php" class="interfacename">MongoDB\BSON\Serializable</a></span>.
     </p>

     <div class="section">
      <h2 class="title">Примеры</h2>

      <div class="example-contents">
<div class="phpcode"><code><span style="color: #000000"><span style="color: #0000BB">&lt;?php<br /><br /></span><span style="color: #007700">class </span><span style="color: #0000BB">stdClass<br /></span><span style="color: #007700">{<br />    public </span><span style="color: #0000BB">$foo </span><span style="color: #007700">= </span><span style="color: #0000BB">42</span><span style="color: #007700">;<br />} </span><span style="color: #FF8000">// =&gt; {"foo": 42}<br /><br /></span><span style="color: #007700">class </span><span style="color: #0000BB">MyClass<br /></span><span style="color: #007700">{<br />    public </span><span style="color: #0000BB">$foo </span><span style="color: #007700">= </span><span style="color: #0000BB">42</span><span style="color: #007700">;<br />    protected </span><span style="color: #0000BB">$prot </span><span style="color: #007700">= </span><span style="color: #DD0000">'вино'</span><span style="color: #007700">;<br />    private </span><span style="color: #0000BB">$fpr </span><span style="color: #007700">= </span><span style="color: #DD0000">'сыр'</span><span style="color: #007700">;<br />} </span><span style="color: #FF8000">// =&gt; {"foo": 42}<br /><br /></span><span style="color: #007700">class </span><span style="color: #0000BB">AnotherClass1 </span><span style="color: #007700">implements </span><span style="color: #0000BB">MongoDB\BSON\Serializable<br /></span><span style="color: #007700">{<br />    public </span><span style="color: #0000BB">$foo </span><span style="color: #007700">= </span><span style="color: #0000BB">42</span><span style="color: #007700">;<br />    protected </span><span style="color: #0000BB">$prot </span><span style="color: #007700">= </span><span style="color: #DD0000">'вино'</span><span style="color: #007700">;<br />    private </span><span style="color: #0000BB">$fpr </span><span style="color: #007700">= </span><span style="color: #DD0000">'сыр'</span><span style="color: #007700">;<br /><br />    public function </span><span style="color: #0000BB">bsonSerialize</span><span style="color: #007700">(): array<br />    {<br />        return [</span><span style="color: #DD0000">'foo' </span><span style="color: #007700">=&gt; </span><span style="color: #0000BB">$this</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">foo</span><span style="color: #007700">, </span><span style="color: #DD0000">'prot' </span><span style="color: #007700">=&gt; </span><span style="color: #0000BB">$this</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">prot</span><span style="color: #007700">];<br />    }<br />} </span><span style="color: #FF8000">// =&gt; {"foo": 42, "prot": "вино"}<br /><br /></span><span style="color: #007700">class </span><span style="color: #0000BB">AnotherClass2 </span><span style="color: #007700">implements </span><span style="color: #0000BB">MongoDB\BSON\Serializable<br /></span><span style="color: #007700">{<br />    public </span><span style="color: #0000BB">$foo </span><span style="color: #007700">= </span><span style="color: #0000BB">42</span><span style="color: #007700">;<br /><br />    public function </span><span style="color: #0000BB">bsonSerialize</span><span style="color: #007700">(): </span><span style="color: #0000BB">self<br />    </span><span style="color: #007700">{<br />        return </span><span style="color: #0000BB">$this</span><span style="color: #007700">;<br />    }<br />} </span><span style="color: #FF8000">// =&gt; MongoDB\Driver\Exception\UnexpectedValueException("bsonSerialize() did not return an array or stdClass")<br /><br /></span><span style="color: #007700">class </span><span style="color: #0000BB">AnotherClass3 </span><span style="color: #007700">implements </span><span style="color: #0000BB">MongoDB\BSON\Serializable<br /></span><span style="color: #007700">{<br />    private </span><span style="color: #0000BB">$elements </span><span style="color: #007700">= [</span><span style="color: #DD0000">'foo'</span><span style="color: #007700">, </span><span style="color: #DD0000">'bar'</span><span style="color: #007700">];<br /><br />    public function </span><span style="color: #0000BB">bsonSerialize</span><span style="color: #007700">(): array<br />    {<br />        return </span><span style="color: #0000BB">$this</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">elements</span><span style="color: #007700">;<br />    }<br />} </span><span style="color: #FF8000">// =&gt; {"0": "foo", "1": "bar"}<br /><br />/**<br /> * Вложенные сериализуемые классы<br /> */<br /><br /></span><span style="color: #007700">class </span><span style="color: #0000BB">AnotherClass4 </span><span style="color: #007700">implements </span><span style="color: #0000BB">MongoDB\BSON\Serializable<br /></span><span style="color: #007700">{<br />    private </span><span style="color: #0000BB">$elements </span><span style="color: #007700">= [</span><span style="color: #0000BB">0 </span><span style="color: #007700">=&gt; </span><span style="color: #DD0000">'foo'</span><span style="color: #007700">, </span><span style="color: #0000BB">2 </span><span style="color: #007700">=&gt; </span><span style="color: #DD0000">'bar'</span><span style="color: #007700">];<br /><br />    public function </span><span style="color: #0000BB">bsonSerialize</span><span style="color: #007700">(): array<br />    {<br />        return </span><span style="color: #0000BB">$this</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">elements</span><span style="color: #007700">;<br />    }<br />} </span><span style="color: #FF8000">// =&gt; {"0": "foo", "2": "bar"}<br /><br /></span><span style="color: #007700">class </span><span style="color: #0000BB">ContainerClass1 </span><span style="color: #007700">implements </span><span style="color: #0000BB">MongoDB\BSON\Serializable<br /></span><span style="color: #007700">{<br />    public </span><span style="color: #0000BB">$things</span><span style="color: #007700">;<br /><br />    public function </span><span style="color: #0000BB">__construct</span><span style="color: #007700">()<br />    {<br />        </span><span style="color: #0000BB">$this</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">things </span><span style="color: #007700">= new </span><span style="color: #0000BB">AnotherClass4</span><span style="color: #007700">();<br />    }<br /><br />    function </span><span style="color: #0000BB">bsonSerialize</span><span style="color: #007700">(): array<br />    {<br />        return [</span><span style="color: #DD0000">'things' </span><span style="color: #007700">=&gt; </span><span style="color: #0000BB">$this</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">things</span><span style="color: #007700">];<br />    }<br />} </span><span style="color: #FF8000">// =&gt; {"things": {"0": "foo", "2": "bar"}}<br /><br /><br /></span><span style="color: #007700">class </span><span style="color: #0000BB">AnotherClass5 </span><span style="color: #007700">implements </span><span style="color: #0000BB">MongoDB\BSON\Serializable<br /></span><span style="color: #007700">{<br />    private </span><span style="color: #0000BB">$elements </span><span style="color: #007700">= [</span><span style="color: #0000BB">0 </span><span style="color: #007700">=&gt; </span><span style="color: #DD0000">'foo'</span><span style="color: #007700">, </span><span style="color: #0000BB">2 </span><span style="color: #007700">=&gt; </span><span style="color: #DD0000">'bar'</span><span style="color: #007700">];<br /><br />    public function </span><span style="color: #0000BB">bsonSerialize</span><span style="color: #007700">(): array<br />    {<br />        return </span><span style="color: #0000BB">array_values</span><span style="color: #007700">(</span><span style="color: #0000BB">$this</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">elements</span><span style="color: #007700">);<br />    }<br />} </span><span style="color: #FF8000">// =&gt; {"0": "foo", "1": "bar"} as a root class<br />  //    ["foo", "bar"] as a nested value<br /><br /></span><span style="color: #007700">class </span><span style="color: #0000BB">ContainerClass2 </span><span style="color: #007700">implements </span><span style="color: #0000BB">MongoDB\BSON\Serializable<br /></span><span style="color: #007700">{<br />    public </span><span style="color: #0000BB">$things</span><span style="color: #007700">;<br /><br />    public function </span><span style="color: #0000BB">__construct</span><span style="color: #007700">()<br />    {<br />        </span><span style="color: #0000BB">$this</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">things </span><span style="color: #007700">= new </span><span style="color: #0000BB">AnotherClass5</span><span style="color: #007700">();<br />    }<br /><br />    public function </span><span style="color: #0000BB">bsonSerialize</span><span style="color: #007700">(): array<br />    {<br />        return [</span><span style="color: #DD0000">'things' </span><span style="color: #007700">=&gt; </span><span style="color: #0000BB">$this</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">things</span><span style="color: #007700">];<br />    }<br />} </span><span style="color: #FF8000">// =&gt; {"things": ["foo", "bar"]}<br /><br /><br /></span><span style="color: #007700">class </span><span style="color: #0000BB">AnotherClass6 </span><span style="color: #007700">implements </span><span style="color: #0000BB">MongoDB\BSON\Serializable<br /></span><span style="color: #007700">{<br />    private </span><span style="color: #0000BB">$elements </span><span style="color: #007700">= [</span><span style="color: #DD0000">'foo'</span><span style="color: #007700">, </span><span style="color: #DD0000">'bar'</span><span style="color: #007700">];<br /><br />    function </span><span style="color: #0000BB">bsonSerialize</span><span style="color: #007700">(): </span><span style="color: #0000BB">object<br />    </span><span style="color: #007700">{<br />        return (object) </span><span style="color: #0000BB">$this</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">elements</span><span style="color: #007700">;<br />    }<br />} </span><span style="color: #FF8000">// =&gt; {"0": "foo", "1": "bar"}<br /><br /></span><span style="color: #007700">class </span><span style="color: #0000BB">ContainerClass3 </span><span style="color: #007700">implements </span><span style="color: #0000BB">MongoDB\BSON\Serializable<br /></span><span style="color: #007700">{<br />    public </span><span style="color: #0000BB">$things</span><span style="color: #007700">;<br /><br />    public function </span><span style="color: #0000BB">__construct</span><span style="color: #007700">()<br />    {<br />        </span><span style="color: #0000BB">$this</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">things </span><span style="color: #007700">= new </span><span style="color: #0000BB">AnotherClass6</span><span style="color: #007700">();<br />    }<br /><br />    public function </span><span style="color: #0000BB">bsonSerialize</span><span style="color: #007700">(): array<br />    {<br />        return [</span><span style="color: #DD0000">'things' </span><span style="color: #007700">=&gt; </span><span style="color: #0000BB">$this</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">things</span><span style="color: #007700">];<br />    }<br />} </span><span style="color: #FF8000">// =&gt; {"things": {"0": "foo", "1": "bar"}}<br /><br /></span><span style="color: #007700">class </span><span style="color: #0000BB">UpperClass </span><span style="color: #007700">implements </span><span style="color: #0000BB">MongoDB\BSON\Persistable<br /></span><span style="color: #007700">{<br />    public </span><span style="color: #0000BB">$foo </span><span style="color: #007700">= </span><span style="color: #0000BB">42</span><span style="color: #007700">;<br />    protected </span><span style="color: #0000BB">$prot </span><span style="color: #007700">= </span><span style="color: #DD0000">'вино'</span><span style="color: #007700">;<br />    private </span><span style="color: #0000BB">$fpr </span><span style="color: #007700">= </span><span style="color: #DD0000">'сыр'</span><span style="color: #007700">;<br /><br />    private </span><span style="color: #0000BB">$data</span><span style="color: #007700">;<br /><br />    public function </span><span style="color: #0000BB">bsonUnserialize</span><span style="color: #007700">(array </span><span style="color: #0000BB">$data</span><span style="color: #007700">): </span><span style="color: #0000BB">void<br />    </span><span style="color: #007700">{<br />        </span><span style="color: #0000BB">$this</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">data </span><span style="color: #007700">= </span><span style="color: #0000BB">$data</span><span style="color: #007700">;<br />    }<br /><br />    public function </span><span style="color: #0000BB">bsonSerialize</span><span style="color: #007700">(): array<br />    {<br />        return [</span><span style="color: #DD0000">'foo' </span><span style="color: #007700">=&gt; </span><span style="color: #0000BB">$this</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">foo</span><span style="color: #007700">, </span><span style="color: #DD0000">'prot' </span><span style="color: #007700">=&gt; </span><span style="color: #0000BB">$this</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">prot</span><span style="color: #007700">];<br />    }<br />} </span><span style="color: #FF8000">// =&gt; {"foo": 42, "prot": "вино", "__pclass": {"$type": "80", "$binary": "VXBwZXJDbGFzcw=="}}<br /><br /></span><span style="color: #0000BB">?&gt;</span></span></code></div>
     </div>

    </div>
   </div>
  </div>

  <div class="section" id="mongodb.persistence.deserialization">
   <h2 class="title">Десериализация из BSON</h2>

   
   <div class="warning"><strong class="warning">Внимание</strong>
    <p class="simpara">
      Документы BSON технически могут содержать повторяющиеся ключи, поскольку документы хранятся в виде списка пар ключ-значение;
      однако приложениям следует воздерживаться от создания документов с дубликатами ключей,
      поскольку поведение сервера и драйвера может быть неопределённым.
      Поскольку объекты и массивы PHP не могут иметь повторяющихся ключей,
      данные также могут быть потеряны при декодировании документа BSON с повторяющимися ключами.
    </p>
   </div>


   <p class="para">
    Устаревший модуль <code class="code">mongo</code> десериализовывал
    BSON-документы и BSON-массивы в PHP-массивы. Хотя с PHP-массивами
    удобно работать, такое поведение было проблематичным, поскольку разные
    BSON-типы могли десериализоваться до одного и того же PHP-значения (например,
    <code class="literal">{&quot;0&quot;: &quot;foo&quot;}</code> и <code class="literal">[&quot;foo&quot;]</code>), что делало
    невозможным определение оригинального BSON-типа. По умолчанию модуль <code class="code">mongodb</code>
    решает эту проблему и гарантирует, что BSON-массивы преобразуются в PHP-массивы, а BSON-документы
    в PHP-объекты.
   </p>

   <p class="para">
    Для составных типов существует три типа данных:
   </p>

   <p class="para">
    <dl>
     
      <dt>root</dt>
      <dd>
       <p class="para">
        относится <em>только</em> к BSON-документу верхнего уровня
       </p>
      </dd>
     
     
      <dt>document</dt>
      <dd>
       <p class="para">
        относится <em>только</em> к встроенным BSON-документам
       </p>
      </dd>
     
     
      <dt>array</dt>
      <dd>
       <p class="para">
        относится к BSON-массивам
       </p>
      </dd>
     
    </dl>
   </p>

   <p class="para">
    Помимо трёх групповых типов, также можно настроить
    определённые поля в документе для сопоставления с типами данных, как указывает следующий фрагмент кода.
    В качестве примера, следующая карта типов позволяет
    сопоставить каждый встроенный документ в массиве <code class="literal">«addresses»</code>
    с классом <span class="classname"><strong class="classname">Address</strong></span>, <em>а</em> каждое
    поле <code class="literal">«city»</code> в этих документах с встроенным адресом
    с классом <span class="classname"><strong class="classname">City</strong></span>:

    <div class="example-contents">
<div class="textcode"><pre class="textcode">[
    &#039;fieldPaths&#039; =&gt; [
        &#039;addresses.$&#039; =&gt; &#039;MyProject\Address&#039;,
        &#039;addresses.$.city&#039; =&gt; &#039;MyProject\City&#039;,
    ],
]</pre>
</div>
    </div>

   </p>

   <p class="para">
    Каждый из этих трёх типов данных, а также сопоставления конкретных полей
    можно сопоставить с различными типами PHP. Возможные значения сопоставления:
   </p>

   <p class="para">
    <dl>
     
      <dt><em>не указано</em> или <span class="type"><a href="language.types.null.php" class="type NULL">NULL</a></span> (по умолчанию)</dt>
      <dd>
       <p class="para">
        <ul class="itemizedlist">
         <li class="listitem">
          <p class="para">
           BSON-массив будет десериализован как PHP-массив (<span class="type"><a href="language.types.array.php" class="type array">array</a></span>).
          </p>
         </li>
         <li class="listitem">
          <p class="para">
           BSON-документ (корневой или встроенный) без свойства
           <span class="property">__pclass</span>
           <a href="#fnidmongodb.pclass" name="fnmongodb.pclass"><sup>[1]</sup></a>
            
           
           становится PHP-объектом <span class="classname"><a href="class.stdclass.php" class="classname">stdClass</a></span>, причём каждый
           ключ BSON-документа устанавливается как открытое
           свойство объекта <span class="classname"><a href="class.stdclass.php" class="classname">stdClass</a></span>.
          </p>
         </li>
         <li class="listitem">
          <p class="para">
           BSON-документ (корневой или встроенный) со свойством
           <span class="property">__pclass</span> <a href="#fnidmongodb.pclass"><sup>[1]</sup></a> становится PHP-объектом
           имени класса, как это определяет свойство <span class="property">__pclass</span>.
          </p>
          <p class="para">
           Если именованный класс реализует интерфейс
           M<span class="interfacename"><a href="class.mongodb-bson-persistable.php" class="interfacename">MongoDB\BSON\Persistable</a></span>,
           то свойства BSON-документа, включая свойство
           <span class="property">__pclass</span>, отправляются как ассоциативный
           массив в метод
           <span class="methodname"><a href="mongodb-bson-unserializable.bsonunserialize.php" class="methodname">MongoDB\BSON\Unserializable::bsonUnserialize()</a></span>,
           чтобы инициализировать свойства объекта.
          </p>
          <p class="para">
           Если именованный класс не существует или не реализует интерфейс
           <span class="interfacename"><a href="class.mongodb-bson-persistable.php" class="interfacename">MongoDB\BSON\Persistable</a></span>,
           будет использоваться объект <span class="classname"><a href="class.stdclass.php" class="classname">stdClass</a></span>, и каждый ключ BSON-документа
           (включая свойство <span class="property">__pclass</span>) будет установлен
           как открытое свойство объекта <span class="classname"><a href="class.stdclass.php" class="classname">stdClass</a></span>.
          </p>
          <p class="para">
           Функциональность свойства <span class="property">__pclass</span> зависит от того, представляет ли
           собой свойство часть извлечённого документа БД MongoDB. Если при запросе документов
           используется <a href="mongodb-driver-query.construct.php#mongodb-driver-query.construct-queryOptions" class="link">проекция</a>,
           необходимо включить в проекцию поле <span class="property">__pclass</span>,
           чтобы эта функциональность работала.
          </p>
         </li>
        </ul>
       </p>
      </dd>
     

     
      <dt><code class="literal">«array»</code></dt>
      <dd>
       <p class="para">
        Превращает BSON-массив или BSON-документ в PHP-массив. Специальной обработки
        свойства <span class="property">__pclass</span> <a href="#fnidmongodb.pclass"><sup>[1]</sup></a> не будет,
        но его можно установить как элемент в возвращаемом массиве, если он
        содержался в BSON-документе.
       </p>
      </dd>
     

     
      <dt><code class="literal">«object»</code> или <code class="literal">«stdClass»</code></dt>
      <dd>
       <p class="para">
        Превращает BSON-массив или BSON-документ в объект
        <span class="classname"><a href="class.stdclass.php" class="classname">stdClass</a></span>. Специальной
        обработки свойства <span class="property">__pclass</span> <a href="#fnidmongodb.pclass"><sup>[1]</sup></a> не будет,
        но его можно установить как открытое свойство в возвращаемом объекте, если оно присутствовало
        в BSON-документе.
       </p>
      </dd>
     

     
      <dt><code class="literal">«bson»</code></dt>
      <dd>
       <p class="para">
        Превращает BSON-массив в объект <span class="classname"><a href="class.mongodb-bson-packedarray.php" class="classname">MongoDB\BSON\PackedArray</a></span>,
        а BSON-документ в объект <span class="classname"><a href="class.mongodb-bson-document.php" class="classname">MongoDB\BSON\Document</a></span>,
        независимо от того, есть ли у BSON-документа свойство <span class="property">__pclass</span>
        <a href="#fnidmongodb.pclass"><sup>[1]</sup></a>.
       </p>
       <blockquote class="note"><p><strong class="note">Замечание</strong>: 
        <span class="simpara">
         Значение <code class="literal">bson</code> доступно только для трёх корневых типов,
         но не в отображениях для конкретных полей.
        </span>
       </p></blockquote>
      </dd>
     

     
      <dt>любая другая строка</dt>
      <dd>
       <p class="para">
        Определяет имя класса, который должен десериализовать BSON-массив
        или BSON-объект. Для BSON-объектов, которые содержат свойства
        <span class="property">__pclass</span>, этот класс будет приоритетным.
       </p>

       <p class="para">
        Если именованный класс не существует, не представляет собой конкретный класс (то есть это
        абстрактный класс или интерфейс) или не реализует
        интерфейс <span class="interfacename"><a href="class.mongodb-bson-unserializable.php" class="interfacename">MongoDB\BSON\Unserializable</a></span>, выбрасывается исключение
        <span class="classname"><a href="class.mongodb-driver-exception-invalidargumentexception.php" class="classname">MongoDB\Driver\Exception\InvalidArgumentException</a></span>.
       </p>

       <p class="para">
        Если BSON-объект содержит свойство <span class="property">__pclass</span> и
        этот класс существует и реализует
        интерфейс <span class="interfacename"><a href="class.mongodb-bson-persistable.php" class="interfacename">MongoDB\BSON\Persistable</a></span>,
        он заменит класс, представленный в карте типов.
       </p>

       <p class="para">
        Свойства BSON-документа, <em>включая</em>
        свойство <span class="property">__pclass</span>, если оно существует, отправляются
        как ассоциативный массив в метод
        <span class="methodname"><a href="mongodb-bson-unserializable.bsonunserialize.php" class="methodname">MongoDB\BSON\Unserializable::bsonUnserialize()</a></span>,
        чтобы инициализировать свойства объекта.
       </p>
      </dd>
     
    </dl>
   </p>

   <div class="section" id="mongodb.persistence.typemaps">
    <h2 class="title">TypeMaps</h2>

     <p class="para">
      Функции настройки TypeMaps можно установить методом
      <span class="methodname"><a href="mongodb-driver-cursor.settypemap.php" class="methodname">MongoDB\Driver\Cursor::setTypeMap()</a></span> для объекта
      <span class="classname"><a href="class.mongodb-driver-cursor.php" class="classname">MongoDB\Driver\Cursor</a></span> или аргумента
      <code class="literal">$typeMap</code>
      в методах <span class="function"><a href="function.mongodb.bson-tophp.php" class="function">MongoDB\BSON\toPHP()</a></span>,
      <span class="methodname"><a href="mongodb-bson-document.tophp.php" class="methodname">MongoDB\BSON\Document::toPHP()</a></span>
      и <span class="methodname"><a href="mongodb-bson-packedarray.tophp.php" class="methodname">MongoDB\BSON\PackedArray::toPHP()</a></span>. Каждый из трёх
      классов (<em>root</em>, <em>document</em>, и
      <em>array</em>) можно задать индивидуально, в дополнение
      к типам полей.
     </p>

     <p class="para">
      Если значение на карте равно <span class="type"><a href="language.types.null.php" class="type NULL">NULL</a></span>, это означает то же,
      что и значение <em>по умолчанию</em> для этого элемента.
     </p>
    </div>

    <div class="section">
     <h2 class="title">Примеры</h2>

     <p class="para">
      В этих примерах используются следующие классы:
     </p>

     <p class="para">
      <dl>
       
        <dt>MyClass</dt>
        <dd>
         <p class="para">
          <em>не</em> реализует интерфейсы
         </p>
        </dd>
       
       
        <dt>YourClass</dt>
        <dd>
         <p class="para">
          реализует интерфейс
          <span class="interfacename"><a href="class.mongodb-bson-unserializable.php" class="interfacename">MongoDB\BSON\Unserializable</a></span>
         </p>
        </dd>
       
       
        <dt>OurClass</dt>
        <dd>
         <p class="para">
          реализует интерфейс
          <span class="interfacename"><a href="class.mongodb-bson-persistable.php" class="interfacename">MongoDB\BSON\Persistable</a></span>
         </p>
        </dd>
       
       
        <dt>TheirClass</dt>
        <dd>
         <p class="para">
          расширяет класс OurClass
         </p>
        </dd>
       
      </dl>
     </p>

     <p class="para">
      Метод <span class="methodname"><a href="mongodb-bson-unserializable.bsonunserialize.php" class="methodname">MongoDB\BSON\Unserializable::bsonUnserialize()</a></span>
      классов YourClass, OurClass, OurClass выполняет итерацию по массиву и устанавливает
      свойства без изменений. Метод <em>также</em> устанавливает для свойства
      <code class="literal">$unserialized</code> значение <strong><code><a href="reserved.constants.php#constant.true">true</a></code></strong>:

      <div class="example-contents">
<div class="phpcode"><code><span style="color: #000000"><span style="color: #0000BB">&lt;?php<br /><br /></span><span style="color: #007700">function </span><span style="color: #0000BB">bsonUnserialize</span><span style="color: #007700">(array </span><span style="color: #0000BB">$map</span><span style="color: #007700">)<br />{<br />    foreach (</span><span style="color: #0000BB">$map </span><span style="color: #007700">as </span><span style="color: #0000BB">$k </span><span style="color: #007700">=&gt; </span><span style="color: #0000BB">$value</span><span style="color: #007700">) {<br />        </span><span style="color: #0000BB">$this</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">$k </span><span style="color: #007700">= </span><span style="color: #0000BB">$value</span><span style="color: #007700">;<br />    }<br />    </span><span style="color: #0000BB">$this</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">unserialized </span><span style="color: #007700">= </span><span style="color: #0000BB">true</span><span style="color: #007700">;<br />}<br /><br /></span><span style="color: #0000BB">?&gt;</span></span></code></div>
      </div>

     </p>

     <p class="para">
      <div class="example-contents">
<div class="textcode"><pre class="textcode">/* typemap: [] (все значения по умолчанию) */
{&quot;foo&quot;: &quot;yes&quot;, &quot;bar&quot; : false}
  -&gt; stdClass {$foo =&gt; &#039;yes&#039;, $bar =&gt; false}

{&quot;foo&quot;: &quot;no&quot;, &quot;array&quot; : [5, 6]}
  -&gt; stdClass {$foo =&gt; &#039;no&#039;, $array =&gt; [5, 6]}

{&quot;foo&quot;: &quot;no&quot;, &quot;obj&quot; : {&quot;embedded&quot; : 3.14}}
  -&gt; stdClass {$foo =&gt; &#039;no&#039;, $obj =&gt; stdClass {$embedded =&gt; 3.14}}

{&quot;foo&quot;: &quot;yes&quot;, &quot;__pclass&quot;: &quot;MyClass&quot;}
  -&gt; stdClass {$foo =&gt; &#039;yes&#039;, $__pclass =&gt; &#039;MyClass&#039;}

{&quot;foo&quot;: &quot;yes&quot;, &quot;__pclass&quot;: {&quot;$type&quot; : &quot;80&quot;, &quot;$binary&quot; : &quot;MyClass&quot;}}
  -&gt; stdClass {$foo =&gt; &#039;yes&#039;, $__pclass =&gt; Binary(0x80, &#039;MyClass&#039;)}

{&quot;foo&quot;: &quot;yes&quot;, &quot;__pclass&quot;: {&quot;$type&quot; : &quot;80&quot;, &quot;$binary&quot; : &quot;YourClass&quot;)}
  -&gt; stdClass {$foo =&gt; &#039;yes&#039;, $__pclass =&gt; Binary(0x80, &#039;YourClass&#039;)}

{&quot;foo&quot;: &quot;yes&quot;, &quot;__pclass&quot;: {&quot;$type&quot; : &quot;80&quot;, &quot;$binary&quot; : &quot;OurClass&quot;)}
  -&gt; OurClass {$foo =&gt; &#039;yes&#039;, $__pclass =&gt; Binary(0x80, &#039;OurClass&#039;), $unserialized =&gt; true}

{&quot;foo&quot;: &quot;yes&quot;, &quot;__pclass&quot;: {&quot;$type&quot; : &quot;44&quot;, &quot;$binary&quot; : &quot;YourClass&quot;)}
  -&gt; stdClass {$foo =&gt; &#039;yes&#039;, $__pclass =&gt; Binary(0x44, &#039;YourClass&#039;)}</pre>
</div>
      </div>

     </p>

     <p class="para">
      <div class="example-contents">
<div class="textcode"><pre class="textcode">/* typemap: [&quot;root&quot; =&gt; &quot;MissingClass&quot;] */
{&quot;foo&quot;: &quot;yes&quot;}
  -&gt; MongoDB\Driver\Exception\InvalidArgumentException(&quot;MissingClass does not exist&quot;)

/* typemap: [&quot;root&quot; =&gt; &quot;MyClass&quot;] */
{&quot;foo&quot;: &quot;yes&quot;, &quot;__pclass&quot; : {&quot;$type&quot;: &quot;80&quot;, &quot;$binary&quot;: &quot;MyClass&quot;}}
  -&gt; MongoDB\Driver\Exception\InvalidArgumentException(&quot;MyClass does not implement Unserializable interface&quot;)

/* typemap: [&quot;root&quot; =&gt; &quot;MongoDB\BSON\Unserializable&quot;] */
{&quot;foo&quot;: &quot;yes&quot;}
  -&gt; MongoDB\Driver\Exception\InvalidArgumentException(&quot;Unserializable is not a concrete class&quot;)

/* typemap: [&quot;root&quot; =&gt; &quot;YourClass&quot;] */
{&quot;foo&quot;: &quot;yes&quot;, &quot;__pclass&quot; : {&quot;$type&quot;: &quot;80&quot;, &quot;$binary&quot;: &quot;MongoDB\BSON\Unserializable&quot;}}
  -&gt; YourClass {$foo =&gt; &quot;yes&quot;, $__pclass =&gt; Binary(0x80, &quot;MongoDB\BSON\Unserializable&quot;), $unserialized =&gt; true}

/* typemap: [&quot;root&quot; =&gt; &quot;YourClass&quot;] */
{&quot;foo&quot;: &quot;yes&quot;, &quot;__pclass&quot; : {&quot;$type&quot;: &quot;80&quot;, &quot;$binary&quot;: &quot;MyClass&quot;}}
  -&gt; YourClass {$foo =&gt; &quot;yes&quot;, $__pclass =&gt; Binary(0x80, &quot;MyClass&quot;), $unserialized =&gt; true}

/* typemap: [&quot;root&quot; =&gt; &quot;YourClass&quot;] */
{&quot;foo&quot;: &quot;yes&quot;, &quot;__pclass&quot; : {&quot;$type&quot;: &quot;80&quot;, &quot;$binary&quot;: &quot;OurClass&quot;}}
  -&gt; OurClass {$foo =&gt; &quot;yes&quot;, $__pclass =&gt; Binary(0x80, &quot;OurClass&quot;), $unserialized =&gt; true}

/* typemap: [&quot;root&quot; =&gt; &quot;YourClass&quot;] */
{&quot;foo&quot;: &quot;yes&quot;, &quot;__pclass&quot; : {&quot;$type&quot;: &quot;80&quot;, &quot;$binary&quot;: &quot;TheirClass&quot;}}
  -&gt; TheirClass {$foo =&gt; &quot;yes&quot;, $__pclass =&gt; Binary(0x80, &quot;TheirClass&quot;), $unserialized =&gt; true}

/* typemap: [&quot;root&quot; =&gt; &quot;OurClass&quot;] */
{ foo: &quot;yes&quot;, &quot;__pclass&quot; : {&quot;$type&quot;: &quot;80&quot;, &quot;$binary&quot;: &quot;TheirClass&quot;}}
  -&gt; TheirClass {$foo =&gt; &quot;yes&quot;, $__pclass =&gt; Binary(0x80, &quot;TheirClass&quot;), $unserialized =&gt; true}</pre>
</div>
      </div>

     </p>

     <p class="para">
      <div class="example-contents">
<div class="textcode"><pre class="textcode">/* typemap: [&#039;root&#039; =&gt; &#039;YourClass&#039;] */
{foo: &quot;yes&quot;, &quot;__pclass&quot;: {&quot;$type&quot;: &quot;80&quot;, &quot;$binary&quot;: &quot;YourClass&quot;}}
  -&gt; YourClass {$foo =&gt; &#039;yes&#039;, $__pclass =&gt; Binary(0x80, &#039;YourClass&#039;), $unserialized =&gt; true}</pre>
</div>
      </div>

     </p>

     <p class="para">
      <div class="example-contents">
<div class="textcode"><pre class="textcode">/* typemap: [&#039;root&#039; =&gt; &#039;array&#039;, &#039;document&#039; =&gt; &#039;array&#039;] */
{&quot;foo&quot;: &quot;yes&quot;, &quot;bar&quot;: false}
  -&gt; [&quot;foo&quot; =&gt; &quot;yes&quot;, &quot;bar&quot; =&gt; false]

{&quot;foo&quot;: &quot;no&quot;, &quot;array&quot;: [5, 6]}
  -&gt; [&quot;foo&quot; =&gt; &quot;no&quot;, &quot;array&quot; =&gt; [5, 6]]

{&quot;foo&quot;: &quot;no&quot;, &quot;obj&quot;: {&quot;embedded&quot;: 3.14}}
  -&gt; [&quot;foo&quot; =&gt; &quot;no&quot;, &quot;obj&quot; =&gt; [&quot;embedded =&gt; 3.14]]

{&quot;foo&quot;: &quot;yes&quot;, &quot;__pclass&quot;: &quot;MyClass&quot;}
  -&gt; [&quot;foo&quot; =&gt; &quot;yes&quot;, &quot;__pclass&quot; =&gt; &quot;MyClass&quot;]

{&quot;foo&quot;: &quot;yes&quot;, &quot;__pclass&quot;: {&quot;$type&quot;: &quot;80&quot;, &quot;$binary&quot;: &quot;MyClass&quot;}}
  -&gt; [&quot;foo&quot; =&gt; &quot;yes&quot;, &quot;__pclass&quot; =&gt; Binary(0x80, &quot;MyClass&quot;)]

{&quot;foo&quot;: &quot;yes&quot;, &quot;__pclass&quot;: {&quot;$type&quot;: &quot;80&quot;, &quot;$binary&quot;: &quot;OurClass&quot;}}
  -&gt; [&quot;foo&quot; =&gt; &quot;yes&quot;, &quot;__pclass&quot; =&gt; Binary(0x80, &quot;OurClass&quot;)]</pre>
</div>
      </div>

     </p>

     <p class="para">
      <div class="example-contents">
<div class="textcode"><pre class="textcode">/* typemap: [&#039;root&#039; =&gt; &#039;object&#039;, &#039;document&#039; =&gt; &#039;object&#039;] */
{&quot;foo&quot;: &quot;yes&quot;, &quot;__pclass&quot;: {&quot;$type&quot;: &quot;80&quot;, &quot;$binary&quot;: &quot;MyClass&quot;}}
  -&gt; stdClass {$foo =&gt; &quot;yes&quot;, &quot;__pclass&quot; =&gt; Binary(0x80, &quot;MyClass&quot;)}</pre>
</div>
      </div>

     </p>

   </div>
  </div>

 </div><?php manual_footer($setup); ?>