Tell me more ×
Stack Overflow is a question and answer site for professional and enthusiast programmers. It's 100% free, no registration required.

I have a function that updates fine with a single dimensional array, but with a multidimensional array (or nested array) it will not update. the document data, the BSONfield (acts as the find key), and the collection are imputed. Any Idea what i am doing wrong?

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;
}
share|improve this question

3 Answers

up vote 1 down vote accepted

It translates fairly directly:

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

Translates to:

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

Then there are some flags for multi-row updates, etc. which I'm not showing here, but which are in the PHP and Mongo docs.

You might also want to look at: MongoDB - help with a PHP query

share|improve this answer

So after fiddling around with is my solution ended up being kind of janky, I deleted the Document then re-create it. Here is the code in case anyone is looking:

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

and how i am securing all the data from injections:

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

enjoy!

share|improve this answer

You don't seem to be using the $set operator correctly. As per the MongoDB docs, you need to format your update document like so;

{ $set : { field : value } }

If you're running a $set on nested keys, you need to use dot notation to get to them. For example;

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

share|improve this answer
Yeah i am having trouble with how that translates into PHP. I have a nested array do I make the key of the nested array "$set"? like is it myArray[Key] = array('$set' => myNestedArray) or myArray[Key] = array('$set' => array($BSONfield => myNestedArray)? – JBurlison Apr 22 '12 at 2:10
Nope, you'd use just like my second example. array('$set' => array( 'nested.field' => value ) ) – Chris Henry Apr 22 '12 at 23:33

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.