I can get the not-bind query on with this way :
\DB::enableQueryLog();
$items = OrderItem::where('name', '=', 'test')->get();
$log = \DB::getQueryLog();
print_r($log);
Output is :
(
[0] => Array
(
[query] => select * from "order_items" where "order_items"."name" = ? and "order_items"."deleted_at" is null
[bindings] => Array
(
[0] => test
)
[time] => 0.07
)
)
But what I really need is bind query like this :
select * from "order_items" where "order_items"."name" = 'test' and "order_items"."deleted_at" is null
I know I can do this with raw PHP but is there any solution in laravel core?
Actually I've created one function within helpers.php for same. You can also use same function within your helpers.php file
if (! function_exists('ql'))
{
/**
* Get Query Log
*
* #return array of queries
*/
function ql()
{
$log = \DB::getQueryLog();
$pdo = \DB::connection()->getPdo();
foreach ($log as &$l)
{
$bindings = $l['bindings'];
if (!empty($bindings))
{
foreach ($bindings as $key => $binding)
{
// This regex matches placeholders only, not the question marks,
// nested in quotes, while we iterate through the bindings
// and substitute placeholders by suitable values.
$regex = is_numeric($key)
? "/\?(?=(?:[^'\\\']*'[^'\\\']*')*[^'\\\']*$)/"
: "/:{$key}(?=(?:[^'\\\']*'[^'\\\']*')*[^'\\\']*$)/";
$l['query'] = preg_replace($regex, $pdo->quote($binding), $l['query'], 1);
}
}
}
return $log;
}
}
if (! function_exists('qldd'))
{
/**
* Get Query Log then Dump and Die
*
* #return array of queries
*/
function qldd()
{
dd(ql());
}
}
if (! function_exists('qld'))
{
/**
* Get Query Log then Dump
*
* #return array of queries
*/
function qld()
{
dump(ql());
}
}
Simply place these three functions within your helpers.php file and you can use same as follows:
$items = OrderItem::where('name', '=', 'test')->get();
qldd(); //for dump and die
or you can use
qld(); // for dump only
Here I extended the answer of #blaz
In app\Providers\AppServiceProvider.php
Add this on boot() method
if (env('APP_DEBUG')) {
DB::listen(function($query) {
File::append(
storage_path('/logs/query.log'),
self::queryLog($query->sql, $query->bindings) . "\n\n"
);
});
}
and also added a private method
private function queryLog($sql, $binds)
{
$result = "";
$sql_chunks = explode('?', $sql);
foreach ($sql_chunks as $key => $sql_chunk) {
if (isset($binds[$key])) {
$result .= $sql_chunk . '"' . $binds[$key] . '"';
}
}
$result .= $sql_chunks[count($sql_chunks) -1];
return $result;
}
Yeah, you're right :/
This is a highly requested feature, and i have no idea why its not a part of the framework yet...
This is not the most elegant solution, but you can do something like this:
function getPureSql($sql, $binds) {
$result = "";
$sql_chunks = explode('?', $sql);
foreach ($sql_chunks as $key => $sql_chunk) {
if (isset($binds[$key])) {
$result .= $sql_chunk . '"' . $binds[$key] . '"';
}
}
return $result;
}
$query = OrderItem::where('name', '=', 'test');
$pure_sql_query = getPureSql($query->toSql(), $query->getBindings());
// Or like this:
$data = OrderItem::where('name', '=', 'test')->get();
$log = DB::getQueryLog();
$log = end($log);
$pure_sql_query = getPureSql($log['query'], $log['bindings']);
You can do that with:
OrderItem::where('name', '=', 'test')->toSql();
Related
Im current creating my own query builder now and Im stuck with PDO's prepared statement. Isn't it possible to loop the the PDO's BindParam. I did it using foreach() but it's not working it only on works on the last data that the loop executed.
$sql = "SELECT * FROM users WHERE id = :a OR fname = :b";
$array = array(":a"=>"10002345", "Josh");
$stmt = $conn->prepare($sql);
foreach($array as $key => $value ) {
$stmt->bindParam($key, $value);
}
$stmt->execute();
it only binds the last data executed by the loop.
It is better to use ? placeholders in a query and pass array of data to execute:
$sql = "SELECT * FROM users WHERE id = ? OR fname = ?";
$array = array("10002345", "Josh"); // you don't even need keys here
$stmt = $conn->prepare($sql);
$stmt->execute($array);
Only just stumbled across this, but just for future reference...
Firstly, I'll work on the assumption that your example was supposed to read $array = array(":a"=>"10002345", ":b"=>"Josh");, as there would be an issue even if your :b key was absent.
In this bit:
foreach($array as $key => $value ) {
$stmt->bindParam($key, $value);
}
You haven't 'passed by reference'. The $value should be amended to &$value
foreach($array as $key => &$value ) {
$stmt->bindParam($key, $value);
}
This is because the bindParam method signature requires the value to be a variable reference:
public function bindParam ($parameter, &$variable, $data_type = PDO::PARAM_STR, $length = null, $driver_options = null) {}
(note the & before $variable).
The end result of your original query (sans &) is that all :params would be set to the value that is in the last iteration of $value in your original loop.
So, the result of
$sql = "SELECT * FROM users WHERE id = :a OR fname = :b";
$array = array(":a"=>"10002345", ":b"=>"Josh");
$stmt = $conn->prepare($sql);
foreach($array as $key => $value ) {
$stmt->bindParam($key, $value);
}
$stmt->execute();
Would be SELECT * FROM users WHERE id = 'Josh' OR fname = 'Josh'
Using named parameters (:param) has advantages over positional params (?), so it's worth reserving that option for prepared statements, as opposed to the accepted answer of "it's better to use ? placeholders", which is not the case.
In my database abstraction layer I use the following utility functions:
/**
* getFieldList return the list with or without PK column
* #param bool $withID - true when including parameter
*/
static protected function getFieldList( $withID = false )
{
if( $withID )
$result = '`' . static::getTableName( ) . '`' .
'.`' . static::getPrimaryKeyName( ) . '`, ';
else
$result = '';
return $result .= '`' . static::getTableName( ) . '`.' .
'`' . implode( '`, `'.static::getTableName( ) . '`.`', static::getFieldNames( ) ) . '`';
}
/**
* getFieldPlaceholders -
* #return string - all PDO place holders prefixed :
*/
static protected function getFieldPlacholders( )
{
return ':' . implode( ',:', static::getFieldNames( ) );
}
/**
* getUpdateList - SQL updates section
* #return string
*/
static private function getUpdateList( )
{
$result = array( );
foreach( static::getFieldNames( ) as $field ) {
if( $field === static::getPrimaryKeyName() ) continue;
$result[] = '`' . $field . '`=:' . $field;
}
return implode( ',', $result );
}
/**
* Bind the fields to PDO placeholdes
* #param PDOStatement $stmt statement that the fields are bound to
* #return void
*/
protected function bindFields( $stmt )
{
foreach( array_keys($this->fields) as $field ) {
if( $field === static::getPrimaryKeyName() ) continue;
$stmt->bindParam( ':' . $field, $this->fields[$field] );
// echo $field . '->' . $this->fields[$field] . '<br>';
}
}
/**
* Bind the fields to the placeholders
* #param PDOStatement $stmt - that the fields are bind to
* #return void
*/
protected function bindColumns( $stmt, $withID = false )
{
if( $withID )
$stmt->bindColumn( static::getPrimaryKeyName(), $this->ID );
foreach( static::getFieldNames() as $fieldname )
{
$stmt->bindColumn( $fieldname, $this->fields[$fieldname] );
}
}
/**
* parseResultset
* Set the values of the select results, resets dirty (object is in sync)
* #param mixed[] $result - associative array
*/
protected function parseResultset( $result )
{
foreach( $result as $field=> $value ) {
if( $field === static::getPrimaryKeyName() )
$this->ID = $value;
$this->fields[$field] = $value;
}
$this->dirty = array();
}
I am preparing a simple class. I want to create a query by following a different path. Class below it is a draft. I look forward to your suggestions.
The Cyclomatic Complexity number 4. PHP Mess Detector, PHPCS fixer tools, I have no problems.
My English is not good, I'm sorry.
<?php
class test
{
protected $q = array();
protected $p = array();
public function get()
{
$new = array();
foreach ($this->p as $value) {
$new = array_merge($new, $value);
}
$this->p = $new;
print_r($this->p);
$query = 'select * from table ';
foreach ($this->q as $sql) {
$query .= implode(' ', $sql) . ' ';
}
echo $query . PHP_EOL;
}
public function camelCase($value)
{
return strtolower(preg_replace('/(.)([A-Z])/', '$1 $2', $value));
}
public function __call($method, $params)
{
$clause = $this->camelCase($method);
$clause = explode(' ', $clause);
if ($key = array_search('in', $clause)) {
$clause[$key] = 'in(?)';
} elseif (isset($clause[2]) && in_array($clause[2], array(
'or',
'and'
))) {
$clause[1] = $clause[1] . ' =?';
$clause[3] = $clause[3] . ' =?';
} elseif (isset($clause[0]) && $clause[0] == 'limit') {
$clause[$key] = 'limit ? offset ?';
} elseif (isset($clause[1]) && $clause[1] != 'by') {
$clause[1] = $clause[1] . ' =?';
}
$this->q[] = $clause;
$this->p[] = $params;
return $this;
}
}
The use of the query creator class is as follows.
<?php
(new test())
->orderByIdDesc()
->limit(15)
->get();
(new test())
->whereIdOrName(6,'foo')
->get();
(new test())
->whereIdIsNotNull(10)
->get();
(new test())
->whereIdIn(9)
->get();
(new test())
->whereIdNotIn(8)
->get();
Output:
Array
(
[0] => 15
)
select * from table order by id desc limit ? offset ?
Array
(
[0] => 6
[1] => foo
)
select * from table where id =? or name =?
Array
(
[0] => 10
)
select * from table where id =? is not null
Array
(
[0] => 9
)
select * from table where id in(?)
Array
(
[0] => 8
)
select * from table where id not in(?)
If it does not make sense, you can write why it doesn't make sense.
In terms of responsibility, your class should never echo in a method.
public function get()
{
$new = array();
foreach ($this->p as $value) {
$new = array_merge($new, $value);
}
$this->p = $new;
print_r($this->p);
$query = 'select * from table ';
foreach($this->q as $sql){
$query .= implode(' ', $sql) . ' ';
}
return $query . PHP_EOL;
}
And
<?= (new test())
->orderByIdDesc()
->limit(15)
->get();
Also, you should have a look at existing libraries rather than inventing and maintaining your own (eloquent for instance).
If you're PHP 5.4+ (which I hope), you could use the short array syntax.
The class could probably be final and with private attributes.
I'm trying to get a complete list of all models under app/Model.
Already tried App::objects('Model') but it only retrieves loaded models.
Is this possible in CakePHP 2?
After some research I found that App::objects('Model') returns all models under app/Models but it doesn't include Plugin models.
To include all models (app models and plugin models) I created the next function:
/**
* Get models list
*
* #return array
*/
public static function getModels()
{
// Get app models
$models = App::objects('Model');
$models = array_combine($models, $models);
// Get plugins models
$pluginsFolder = new Folder(APP . 'Plugin');
$plugins = $pluginsFolder->read();
foreach ( $plugins[0] as $plugin ) {
$pluginModels = App::objects($plugin . '.Model');
foreach ($pluginModels as $pluginModel) {
$models[$plugin . '.' . $pluginModel] = $plugin . '.' . $pluginModel;
}
}
// Exclude tableless and application models
$dataSource = ConnectionManager::getDataSource('default');
$sources = $dataSource->listSources();
foreach($models as $key => $model) {
$table = Inflector::tableize(self::modelName($key));
if (stripos($model, 'AppModel') > -1 || !in_array($table, $sources)) {
unset($models[$key]);
}
}
return $models;
}
Maybe late but here is my version:
(loops through plugin models, and retrieves the table associated by opening the file, and searching for the variable $useTable)
/**
* Get models list.
* Retrieved from: https://stackoverflow.com/questions/38622473/get-models-list-in-cakephp-2
* #return array
*/
public static function getModels() {
// Get app models
$models = App::objects('Model');
$models = array_combine($models, $models);
// Get plugins models
$pluginsFolder = new Folder(APP . 'Plugin');
$plugins = $pluginsFolder->read();
foreach ( $plugins[0] as $plugin ) {
$pluginModels = App::objects($plugin . '.Model');
foreach ($pluginModels as $pluginModel) {
$fullPath = APP.'Plugin'.DS.$plugin.DS."Model".DS.$pluginModel.".php";
$models[$plugin . '.' . $pluginModel] = $fullPath;
}
}
foreach($models as $model => $modelPath) {
if(file_exists($modelPath)) {
$data = file_get_contents($modelPath);
$find = array();
$find[] = "useTable = '";
$find[] = "useTable='";
$find[] = "useTable= '";
$find[] = "useTable ='";
foreach($find as $condition) {
$pos = strrpos($data, $condition);
if($pos !== false ) {
$pos+=(strlen($condition));
$tableName = substr($data, $pos, (strpos($data, "';", $pos)-$pos));
debug($tableName);
}
}
}
}
}
CakePHP v2
In AppController
if (in_array('YOUR_MODEL', $this->uses)) {
//found
}
Is using an object to build up SQL Statements overkill?
Is defining a bare String enough for a SQL statement?
This is my PHP and SQL code:
class SQLStatement {
private $table;
private $sql;
const INNER_JOIN = 'INNER JOIN';
const LEFT_JOIN = 'LEFT JOIN';
const RIGHT_JOIN = 'RIGHT JOIN';
const OUTER_JOIN = 'OUTER JOIN';
public function __construct($table) {
$this->setTable($table);
}
public function setTable($table) {
$this->table = $table;
}
public function buildFromString($string) {
$this->sql = $sql;
}
public function select(array $columns) {
$sql = 'SELECT ';
$columns = implode(',', $columns);
$sql .= $columns;
$sql .= " FROM $this->table";
$this->sql = $sql;
return $this;
}
/**
* Setting up INSERT sql statement
*
* #param array $records The records to insert.The array keys must be the columns, and the array values must be the new values
* #return object Return this object back for method chaining
*/
public function insert(array $records) {
$columns = array_keys($records);
$values = array_values($records);
$values = array_map('quote',$values);
$sql = 'INSERT INTO ';
$sql .= $this->table . '('. implode(',', $columns) . ')';
$sql .= ' VALUES ' . '(' . implode(',', $values) . ')';
$this->sql = $sql;
return $this;
}
/**
* Setting up UPDATE sql statement
*
* #param array $records The records to update. The array keys must be the columns, and the array values must be the new records
* #return object Return this object back for method chaining
*/
public function update(array $records, $where) {
$sql = 'UPDATE ' . $this->table . ' SET ';
$data = array();
foreach ($records as $column => $record) {
$data[] = $column . '=' . quote($record);
}
$sql .= implode(', ', $data);
$this->sql = $sql;
return $this;
}
/**
* Setting up DELETE sql statement
* #return object Return this object back for method chaining
*/
public function delete($where=null) {
$sql = 'DELETE FROM ' . $this->table;
$this->sql = $sql;
if (isset($where)) {
$this->where($where);
}
return $this;
}
/**
* Setting up WHERE clause with equality condition. (Currently only support AND logic)
* #param array $equalityExpression Conditional equality expression. The key is the column, while the value is the conditional values
* #return object Return this object back for method chaining
*
*/
public function where(array $equalityExpression) {
if (!isset($this->sql)) {
throw new BadMethodCallException('You must use SELECT, INSERT, UPDATE, or DELETE first before where clause');
}
$where = ' WHERE ';
$conditions = array();
foreach ($equalityExpression as $column => $value) {
if (is_array($value)) {
$value = array_map('quote', $value);
$conditions[] = "$column IN (" . implode(',', $value) . ')';
}
else {
$value = quote($value);
$conditions[] = "$column = $value";
}
}
$where .= implode(' AND ', $conditions);
$this->sql .= $where;
return $this;
}
/**
* Setting up WHERE clause with expression (Currently only support AND logic)
* #param array $expression Conditional expression. The key is the operator, the value is array with key being the column and the value being the conditional value
* #return object Return this object back for method chaining
*/
public function advancedWhere(array $expression) {
if (!isset($this->sql)) {
throw new BadMethodCallException('You must use SELECT, INSERT, UPDATE, or DELETE first before where clause');
}
if (!is_array(reset($expression))) {
throw new InvalidArgumentException('Invalid format of expression');
}
$where = ' WHERE ';
$conditions = array();
foreach ($expression as $operator => $record) {
foreach ($record as $column => $value) {
$conditions[] = $column . ' ' . $operator . ' ' . quote($value);
}
}
$where .= implode(' AND ', $conditions);
$this->sql .= $where;
return $this;
}
/**
* Setting up join clause (INNER JOIN, LEFT JOIN, RIGHT JOIN, or OUTER JOIN)
* #param array $tables <p>Tables to join as the key and the conditions array as the value (Currently only support ON logic)</p>
* <p>Array example : array('post'=>array('postid'=>'post.id'))</p>
* #param string $mode The mode of join. It can be INNER JOIN, LEFT JOIN, RIGHT JOIN, or OUTER JOIN
* #return object Return this object back for method chaining
*/
public function join(array $joins, $mode = self::INNER_JOIN) {
if (!isset($this->sql) && strpos($this->sql, 'SELECT')) {
throw new BadMethodCallException('You must have SELECT clause before joining another table');
}
if (!is_array(reset($joins))) {
throw new InvalidArgumentException('Invalid format of the join array.');
}
$Conditions = array();
foreach ($joins as $table => $conditions) {
$join = ' ' . $mode . ' ' . $table . ' ON ';
foreach ($conditions as $tbl1 => $tbl2) {
$Conditions[] = $tbl1 . ' = ' . $tbl2;
}
$join .= implode(' AND ', $Conditions);
}
$this->sql .= $join;
return $this;
}
/**
* Setting up GROUP BY clause
* #param array $columns The columns you want to group by
* #param string $sort The type of sort, ascending is the default
* #return object Return this object back for method chaining
*/
public function groupBy(array $columns, $sort = 'ASC') {
if (!isset($this->sql)) {
throw new BadMethodCallException('You must use SELECT, INSERT, UPDATE, or DELETE first before group by clause');
}
$groupBy = ' GROUP BY ' . implode(',', $columns) . ' ' . $sort;
$this->sql .= $groupBy;
return $this;
}
/**
* Setting up HAVING clause with expression
* #param expression $expression Conditional expression. The key is the operator, the value is an array with key being the column and the value being the conditional value
* #return object Return this object back for method chaining
*/
public function having($expression) {
if (!isset($this->sql) && strpos($this->sql, 'GROUP BY') === FALSE) {
throw new BadMethodCallException('You must have SELECT, INSERT, UPDATE, or DELETE and have GROUP BY clause first before where clause');
}
if (!is_array(reset($expression))) {
throw new InvalidArgumentException('Invalid format of expression');
}
$having = ' HAVING ';
$conditions = array();
foreach ($expression as $operator => $record) {
foreach ($record as $column => $value) {
$conditions[] = $column . ' ' . $operator . ' ' . $value;
}
}
$having .= implode(' AND ', $conditions);
$this->sql .= $having;
return $this;
}
/**
* Return the SQL statement if this object is supposed to be string
* #return string The sql statement
*/
public function __toString() {
return $this->sql;
}
}
The disadvantage I found is when I need to use prepared statement since prepared statements contains placeholders.
Should I add a feature to my SQL Statement Object to do prepared statements? When should using prepared statements good practice?
It's not overkill or overengineering to use objects or prepared statements, they are good practice.
The goal is to make something versatile and re-usable, and it looks like you are heading on the right track.
However, many people have done this already, and you may be better off using an existing solution.
Some of the top ones are:
Doctrine
Propel
and I used to personally use:
Idiorm
And if I am not mistaken, all three are built on PDO, and use prepared statements.
If you wanted to make your own solution for this, PDO and prepared statements are a very good idea, if not a must.
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;
}
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
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!
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 } }