0

我有一个函数可以用一维数组很好地更新,但是用多维数组(或嵌套数组)它不会更新。文档数据、BSON 字段(充当查找键)和集合被估算。任何想法我做错了什么?

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;
}
4

3 回答 3

1

它相当直接地翻译:

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

转换为:

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

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

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

于 2012-04-22T19:07:04.017 回答
0

因此,在摆弄我的解决方案之后,我的解决方案最终变得有点笨拙,我删除了 Document 然后重新创建它。如果有人在看,这是代码:

/**
 * 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;
}

请享用!

于 2012-04-21T21:13:58.207 回答
0

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

{ $set : { 字段 : 值 } }

如果您$set在嵌套键上运行,则需要使用点符号来获取它们。例如;

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

于 2012-04-21T22:30:15.807 回答