PHP 将嵌套数组插入 mongoDB


PHP insert nested arrays into mongoDB

我有一个函数,可以使用单维数组进行很好的更新,但是对于多维数组(或嵌套数组),它不会更新。 文档数据、BSONfield(充当查找键)和集合补。知道我做错了什么吗?

Public Static function updateDocument($collection, $BSONfield, $document){
    $dbcollection = $db->selectCollection($collection);
    $sdata = $document[$BSONfield];
    $secureInnerDocument = array();
            $secureDocument = array();
    if($BSONfield == "_id"){
        $sdata = new MongoID($sdata);
        unset($document["_id"]);
    }
    $filter = array($BSONfield=>$sdata);
    foreach ($document as $k => $v) {   
        if (is_array($v)) {
            foreach ($v as $sk => $sv) {
                $secureInnerDocument[$sk] = Security::secureQuery($sv);
            }
                $secureDocument[$k] = $secureInnerDocument;
        }else{      
            $secureDocument[$k] = Security::secureQuery($v);
        }
    }
    $dbcollection->update($filter,array('$set'=>$secureDocument));
    $objid = (string) $secureDocument['_id'];
    return $objid;
}

它翻译得相当直接:

db.collection.update(
   {fieldNameFilter:'filterValue'}, 
   {$set: {'stringFieldName' : 'newValue'}}
);

翻译为:

$collection->update(
   array('fieldNameFilter'=>'filterValue'), 
   array($set => array('stringFieldName'=>$value))
);

然后有一些用于多行更新等的标志,我在这里没有显示,但在 PHP 和 Mongo 文档中。

您可能还想查看: MongoDB - PHP 查询帮助

因此,在摆弄了一下之后,我的解决方案最终变得有点卡顿,我删除了文档然后重新创建它。这是代码,以防有人在看:

/**
 * updates document in the collection.
 * This function secures the data
 *
 * @return  object ID
 * @param   string $collection  The name of the collection
 * @param   string $BSONfield   The $BSON Field you want to index by
 * @param   string $document    The document contents as an array
 */
Public Static function updateDocument($collection, $BSONfield, $document){
    $db =  Database::dbConnect();
    $collection = Security::secureQuery($collection);
    $BSONfield = Security::secureQuery($BSONfield);
    $dbcollection = $db->selectCollection($collection);
    if(array_key_exists('_id', $document)){
        $document["_id"] = new MongoID($document["_id"]);
    }
    Database::deleteDocument($collection, $BSONfield, $document);
    $objid = Database::createDocument($collection, $document);
    return $objid;
}
/**
 * Deletes a document in the collection.
 * This function secures the data
 *
 * @return  Boolean     True - if successfully deleted, False if document not found
 * @param   string $collection  The name of the collection
 * @param   string $BSONfield   The $BSON Field you want to index by
 * @param   string $document    The document contents as an array
 */
Public Static function deleteDocument($collection, $BSONfield, $document){
    $db =  Database::dbConnect();
    $collection = Security::secureQuery($collection);
    $BSONfield = Security::secureQuery($BSONfield);
    $exists = False;
    $dbcollection = $db->selectCollection($collection);
    $documentList = $dbcollection->find();
    $sdata = $document[$BSONfield];
    if($BSONfield == "_id"){
        $sdata = new MongoID($sdata);
    }
    foreach ($documentList as $doc) {
        $documentID = $doc[$BSONfield];
        if ($documentID == $sdata){
            $exists = True;
        }
    }
    if ($exists){
        $deleted = True;
        $filter = array($BSONfield=>$sdata);
        $dbcollection->remove($filter,true);
    }else{
        $deleted = False;
    }
    return $deleted;
}

/**
 * Inserts document into the collection.
 * This function secures the data
 *
 * @return  object ID.
 * @param   string $collection  The name of the collection
 * @param   string $document    The document contents as an array
 */
Public Static function createDocument($collection, $document){
    $db =  Database::dbConnect();
    $collection = Security::secureQuery($collection);
    $dbcollection = $db->selectCollection($collection);
    $secureDocument = array();
    $secureInnerDocument = array();
    foreach ($document as $k => $v) {   
        if (is_array($v)) {
            foreach ($v as $sk => $sv) {
                $secureInnerDocument[$sk] = Security::secureQuery($sv);
            }
                $secureDocument[$k] = $secureInnerDocument;
        }else{  
            if ($k == '_id'){   
                $secureDocument[$k] = $v;
            }else{  
                $secureDocument[$k] = Security::secureQuery($v);
            }   
        }
    }
    $dbcollection->insert($secureDocument);
    $objid = (string) $secureDocument['_id'];
    return $objid;
}

以及我如何保护所有数据免受注入:

/**
 * Secures string to be inputed into a database.
 * 
 * @return Retuns secure string
 * @param   String $string  String to be secured
 */
Public Static Function secureQuery($string){
    $secureString = strtr($string, array(
            "'"  => "0x27",
            "'"" => "0x22",
            "''" => "0x5C",
            "<"  => "0x3C",
            ">"  => "0x3E",
            "="  => "0x3D",
            "+"  => "0x2B",
            "&"  => "0x26",
            "{"  => "0x7B",
            "}"  => "0x7D",
    ));
    return $secureString;
}
/**
 * Un-Secures string to be inputed into a database.
 *
 * @return Retuns unsecure string
 * @param   String $string  String to be un-secured
 */
Public Static Function unsecureQuery($string){
    $secureString = strtr($string, array(
            "0x27"  => "'",
            "0x22" => "'"",
            "0x5C" => "''",
            "0x3C"  => "<",
            "0x3E"  => ">",
            "0x3D"  => "=",
            "0x2B"  => "+",
            "0x26"  => "&",
            "0x7B"  => "{",
            "0x7D"  => "}",
    ));
    return $secureString;
}

享受!

您似乎没有正确使用 $set 运算符。根据MongoDB文档,您需要像这样格式化更新文档;

{ $set : { 字段 : 值 } }

如果要对嵌套键运行$set,则需要使用点表示法来访问它们。例如;

{ $set : { field.nest : value } }