2016-05-17 14 views
2

mongodbデータベースからドキュメントを読み込み、PHPでクライアント側に渡しています。MongoDB(php) - 複数のプロパティの代わりに配列としてドキュメントプロパティを返す

文書には配列プロパティが含まれています。問題は、クライアント側が標準配列ではなく0,1という名前のプロパティを持つオブジェクトとして受け取ることです。

これは、元のデータである:要求されたよう

{ 
    "_id" : ObjectId("573b47a1f99a8a1f9a6278a5"), 
    "persons" : [ 
     { 
      "name" : "Moshe", 
     }, 
     { 
      "name" : "E", 
     }, ... 
    ] 
} 

、私はでvar_exportを添付しています:

array (
    0 => 
    MongoDB\Model\BSONDocument::__set_state(array(
    '_id' => 
    MongoDB\BSON\ObjectID::__set_state(array(
    )), 
    'persons' => 
    MongoDB\Model\BSONArray::__set_state(array(
     0 => 
     MongoDB\Model\BSONDocument::__set_state(array(
     'name' => 'Moshe', 
    )), 
     1 => 
     MongoDB\Model\BSONDocument::__set_state(array(
     'name' => 'E', 
    )), 
    )), 
)), 
) 

とのvar_dump:

array(1) { 
    [0]=> 
    object(MongoDB\Model\BSONDocument)#40 (1) { 
    ["storage":"ArrayObject":private]=> 
    array(2) { 
     ["_id"]=> 
     object(MongoDB\BSON\ObjectID)#11 (1) { 
     ["oid"]=> 
     string(24) "573b47a1f99a8d1f986278a5" 
     } 
     ["persons"]=> 
     object(MongoDB\Model\BSONArray)#34 (1) { 
     ["storage":"ArrayObject":private]=> 
     array(2) { 
      [0]=> 
      object(MongoDB\Model\BSONDocument)#10 (1) { 
      ["storage":"ArrayObject":private]=> 
      array(1) { 
       ["name"]=> 
       string(5) "Moshe" 
      } 
      } 
      [1]=> 
      object(MongoDB\Model\BSONDocument)#12 (1) { 
      ["storage":"ArrayObject":private]=> 
      array(1) { 
       ["name"]=> 
       string(1) "E" 
      } 
      } 
     } 
     } 
    } 
    } 
} 

これは、PHPコードです(すべてのそれの):

それはクライアント側に表示されている

echo json_encode(select()); 

そして結果:

{ 
    "_id" : ObjectId("573b47a1f99a8a1f9a6278a5"), 
    "persons" : { 
     "0" : { 
      "name" : "Moshe", 
     }, 
     "1" : { 
      "name" : "E", 
     }, ... 
    } 
} 

EDIT: LordNeo

は、それから私はこのようなjson_encodeでクライアントにオブジェクトを渡します実際にそれを解決しました。

return json_decode(json_encode(current($cursor->toArray()),true); 

それは恐ろしい見えますが、それは動作します:彼の答えを読んだ後、私は次のように私の「選択」機能で最後の行を変更しました。

より良い解決策をお聞きします。

+0

コードが不十分です – Richard

+0

私が以前に提供しなかった唯一の行を追加しました。 – Dorad

+0

'$ cursor-> toArray()'の 'var_dump'を追加できますか? – guessimtoolate

答えて

2

オプションの「真の」パラメータを使用することができ、それは次にあなたがarray_shiftを使用して索引を取り除くことができ、アレイ

$obj = json_decode($json, true); 
//$obj will be an associative array 

http://php.net/manual/en/function.json-decode.php

に関連付けますjson_decodeを使用して:

$obj = array_shift($obj); 

http://php.net/manual/en/function.array-shift.php

JSONは明示的に設定されていないときに数値インデックスを追加するので、デコード - >インデックスの削除 - >エンコンディング - >インデックスの削除の代わりに、クライアントに配列を送信する必要があります。

または、クライアントが受信した後にインデックスを削除するだけです。

+0

オブジェクトを配列に変換する方法を説明できますか? – Dorad

+1

json_decodeを使用すると@Doradは "true"を渡す最後のパラメータを持っています。このような配列には、$ obj = json_decode($ json、true);(http://php.net/manual/en/function.json -decode.php)$ objは連想配列になり、array_shiftでインデックスを取り除くことができます – LordNeo

+0

あなたのご意見は私がそれを解決するのに役立ちました。それにもかかわらず、あなたがあなたの答えを編集して他の人が理解できるようにするといいと思います。 (無関係な部分を削除し、実際のポイントを拡張します。)とにかく - ありがとう。 – Dorad

1

0からnまでのすべてのインデックスがありますか、またはそれらのいずれかが欠落していますか?それがおそらく理由だろう。あなたが戻って配列に変換したい場合は、おそらくインデックスを取り除くために

$obj = select(); // changed by the new line added 

を使用して、

$obj['persons'] = array_values($obj['persons']); 

ことがあります。

私はまだかなりの価値がないと確信しています。しかし、それはあなたの例からは見えません。

+0

1.すべての指標があります。 0からnまで。
2.なぜjsonデコードを使用する必要がありますか?私は文字列ではなく、オブジェクトとしてdbからドキュメントを取得しています。 – Dorad

+0

もっとコードを提供できる方が簡単です。あなたの質問から私はあなたが何をしているのか分かりません。変数に何が含まれているかを表示するには、var_exportも使用する必要があります。ありがとうございます-1: – Richard

+0

とにかく、それは動作していません。結果は変わりません。 – Dorad

2

MongoDBドライバは、MongoDB\BSON\toJSON()関数を提供します。この関数は、データをJSONに正しく変換します。文字列を入力する必要があるため、まずドキュメント上でMongoDB\BSON\fromPHP()を呼び出す必要があります。 あなただけの最初に見つかった要素を取得したいように見えるとして、あなたは出力を取得することが非常に簡単になり代わりfind()findOne()方法、使用することができます:あなたは出力複数のエントリにしたい場合は

function select() { 
    $conn = new MongoDB\Client("mongodb://localhost:27017"); 
    $db = $conn->mydb; 
    $doc = $db->entries_meta_data->findOne(); 
    return MongoDB\BSON\toJSON(MongoDB\BSON\fromPHP($doc)); 
} 

を、もう少し複雑になります。アレイがここに示されている出力する一方(確かハック)方法:

function select() { 
    $conn = new MongoDB\Client("mongodb://localhost:27017"); 
    $db = $conn->mydb; 
    $cursor = $db->entries_meta_data->find(); 
    $result = $cursor->toArray(); 
    foreach($result as $i => $doc) { 
    $result[$i] = MongoDB\BSON\toJSON(MongoDB\BSON\fromPHP($doc)); 
    } 
    return '[' . implode($res) . ']'; 
} 

代替json_encode()によって呼び出されたときBSONArrayクラスの出力を調整することです。これを行うには、setting up the MongoDB driverが 'vendor/mongodb/mongodb/src/Model'フォルダにあり、JsonSerializableインターフェイスとjsonSerialize()メソッドを追加すると、

のようになるBSONArray.phpファイルを調整する必要があります。
<?php 

... 

class BSONArray extends ArrayObject implements \JsonSerializable, 
    Serializable, Unserializable 
{ 
    ... 

    /** 
    * Serialize the ArrayObject as normal array 
    * 
    * @return array 
    */ 
    public function jsonSerialize() { 
     return $this->getArrayCopy(); 
    } 
} 
2

理由はnew MongoDB driverthe old driverとは異なるPHPの種類にMongoDBのドキュメントの変換を処理ということです。

良いニュースは、いわゆる "タイプマップ"を指定することで古い動作を得ることができることです。

ドキュメントは少し隠されていますが、in the github repository of the driverまたはin the online docsについて読むことができます。

TLに、DRを使用して、

array(
    'array' => 'array', 
    'document' => 'array', 
    'root' => 'array' 
) 

MongoDB\Clientのコンストラクタの第3引数(「driverOptions」)として、または個別のいずれかのクエリごとにMongoDB\Driver\Cursor::setTypeMap()を呼び出すような配列を渡すことです。

あなたの例では、コール$db->entries_meta_data->find()

$cursor->setTypeMap(array(
    'array' => 'array', 
    'document' => 'array', 
    'root' => 'array' 
)); 

は、トリックを行う必要があります。

+0

これは真の解決策です。例の配列をClientコンストラクタの3番目のパラメータとして設定します。 – VSG24

関連する問題