我有一个函数,可以使用单维数组进行很好的更新,但是对于多维数组(或嵌套数组),它不会更新。 文档数据、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 } }